blob: 7ea73dfacdfbb18856f8133c9f6de870c2fa87b9 [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
1809 if (state->m_OperationMode != oMode) {
1810 switch (state->m_OperationMode) {
1811 /* OM_NONE was added for start up */
1812 case OM_NONE:
1813 break;
1814 case OM_DVBT:
1815 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001816 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001817 goto error;
1818 status = PowerDownDVBT(state, true);
1819 if (status < 0)
1820 goto error;
1821 state->m_OperationMode = OM_NONE;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001822 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001823 case OM_QAM_ITU_A: /* fallthrough */
1824 case OM_QAM_ITU_C:
1825 status = MPEGTSStop(state);
1826 if (status < 0)
1827 goto error;
1828 status = PowerDownQAM(state);
1829 if (status < 0)
1830 goto error;
1831 state->m_OperationMode = OM_NONE;
1832 break;
1833 case OM_QAM_ITU_B:
1834 default:
1835 status = -EINVAL;
1836 goto error;
1837 }
1838
1839 /*
1840 Power up new standard
1841 */
1842 switch (oMode) {
1843 case OM_DVBT:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001844 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001845 status = SetDVBTStandard(state, oMode);
1846 if (status < 0)
1847 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001848 break;
1849 case OM_QAM_ITU_A: /* fallthrough */
1850 case OM_QAM_ITU_C:
Mauro Carvalho Chehabd6a05402011-07-10 13:07:36 -03001851 state->m_OperationMode = oMode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001852 status = SetQAMStandard(state, oMode);
1853 if (status < 0)
1854 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001855 break;
1856 case OM_QAM_ITU_B:
1857 default:
1858 status = -EINVAL;
1859 }
1860 }
1861error:
1862 if (status < 0)
1863 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1864 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001865}
1866
1867static int Start(struct drxk_state *state, s32 offsetFreq,
1868 s32 IntermediateFrequency)
1869{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001870 int status = -EINVAL;
1871
1872 u16 IFreqkHz;
1873 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001874
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001875 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001876 if (state->m_DrxkState != DRXK_STOPPED &&
1877 state->m_DrxkState != DRXK_DTV_STARTED)
1878 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001879
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001880 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001881
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001882 if (IntermediateFrequency < 0) {
1883 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1884 IntermediateFrequency = -IntermediateFrequency;
1885 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001887 switch (state->m_OperationMode) {
1888 case OM_QAM_ITU_A:
1889 case OM_QAM_ITU_C:
1890 IFreqkHz = (IntermediateFrequency / 1000);
1891 status = SetQAM(state, IFreqkHz, OffsetkHz);
1892 if (status < 0)
1893 goto error;
1894 state->m_DrxkState = DRXK_DTV_STARTED;
1895 break;
1896 case OM_DVBT:
1897 IFreqkHz = (IntermediateFrequency / 1000);
1898 status = MPEGTSStop(state);
1899 if (status < 0)
1900 goto error;
1901 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1902 if (status < 0)
1903 goto error;
1904 status = DVBTStart(state);
1905 if (status < 0)
1906 goto error;
1907 state->m_DrxkState = DRXK_DTV_STARTED;
1908 break;
1909 default:
1910 break;
1911 }
1912error:
1913 if (status < 0)
1914 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001915 return status;
1916}
1917
1918static int ShutDown(struct drxk_state *state)
1919{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001920 dprintk(1, "\n");
1921
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001922 MPEGTSStop(state);
1923 return 0;
1924}
1925
Oliver Endrissebc7de22011-07-03 13:49:44 -03001926static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1927 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001928{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001929 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001930
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001931 dprintk(1, "\n");
1932
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001933 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001934 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001935
1936 *pLockStatus = NOT_LOCKED;
1937
1938 /* define the SCU command code */
1939 switch (state->m_OperationMode) {
1940 case OM_QAM_ITU_A:
1941 case OM_QAM_ITU_B:
1942 case OM_QAM_ITU_C:
1943 status = GetQAMLockStatus(state, pLockStatus);
1944 break;
1945 case OM_DVBT:
1946 status = GetDVBTLockStatus(state, pLockStatus);
1947 break;
1948 default:
1949 break;
1950 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001951error:
1952 if (status < 0)
1953 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001954 return status;
1955}
1956
1957static int MPEGTSStart(struct drxk_state *state)
1958{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001959 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001960
1961 u16 fecOcSncMode = 0;
1962
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963 /* Allow OC to sync again */
1964 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1965 if (status < 0)
1966 goto error;
1967 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1968 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1969 if (status < 0)
1970 goto error;
1971 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1972error:
1973 if (status < 0)
1974 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001975 return status;
1976}
1977
1978static int MPEGTSDtoInit(struct drxk_state *state)
1979{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001980 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001981
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001982 dprintk(1, "\n");
1983
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001984 /* Rate integration settings */
1985 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1986 if (status < 0)
1987 goto error;
1988 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1989 if (status < 0)
1990 goto error;
1991 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1992 if (status < 0)
1993 goto error;
1994 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1995 if (status < 0)
1996 goto error;
1997 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1998 if (status < 0)
1999 goto error;
2000 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2001 if (status < 0)
2002 goto error;
2003 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2004 if (status < 0)
2005 goto error;
2006 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2007 if (status < 0)
2008 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002010 /* Additional configuration */
2011 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2012 if (status < 0)
2013 goto error;
2014 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2015 if (status < 0)
2016 goto error;
2017 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2018error:
2019 if (status < 0)
2020 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2021
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002022 return status;
2023}
2024
Oliver Endrissebc7de22011-07-03 13:49:44 -03002025static int MPEGTSDtoSetup(struct drxk_state *state,
2026 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002027{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002028 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002029
Oliver Endrissebc7de22011-07-03 13:49:44 -03002030 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2031 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2032 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2033 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2034 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2035 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2036 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002037 u16 fecOcTmdMode = 0;
2038 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002039 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002040 bool staticCLK = false;
2041
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002042 dprintk(1, "\n");
2043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002044 /* Check insertion of the Reed-Solomon parity bytes */
2045 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2046 if (status < 0)
2047 goto error;
2048 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2049 if (status < 0)
2050 goto error;
2051 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2052 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2053 if (state->m_insertRSByte == true) {
2054 /* enable parity symbol forward */
2055 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2056 /* MVAL disable during parity bytes */
2057 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2058 /* TS burst length to 204 */
2059 fecOcDtoBurstLen = 204;
2060 }
2061
2062 /* Check serial or parrallel output */
2063 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2064 if (state->m_enableParallel == false) {
2065 /* MPEG data output is serial -> set ipr_mode[0] */
2066 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2067 }
2068
2069 switch (oMode) {
2070 case OM_DVBT:
2071 maxBitRate = state->m_DVBTBitrate;
2072 fecOcTmdMode = 3;
2073 fecOcRcnCtlRate = 0xC00000;
2074 staticCLK = state->m_DVBTStaticCLK;
2075 break;
2076 case OM_QAM_ITU_A: /* fallthrough */
2077 case OM_QAM_ITU_C:
2078 fecOcTmdMode = 0x0004;
2079 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2080 maxBitRate = state->m_DVBCBitrate;
2081 staticCLK = state->m_DVBCStaticCLK;
2082 break;
2083 default:
2084 status = -EINVAL;
2085 } /* switch (standard) */
2086 if (status < 0)
2087 goto error;
2088
2089 /* Configure DTO's */
2090 if (staticCLK) {
2091 u32 bitRate = 0;
2092
2093 /* Rational DTO for MCLK source (static MCLK rate),
2094 Dynamic DTO for optimal grouping
2095 (avoid intra-packet gaps),
2096 DTO offset enable to sync TS burst with MSTRT */
2097 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2098 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2099 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2100 FEC_OC_FCT_MODE_VIRT_ENA__M);
2101
2102 /* Check user defined bitrate */
2103 bitRate = maxBitRate;
2104 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2105 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002106 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002107 /* Rational DTO period:
2108 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002110 Result should be floored,
2111 to make sure >= requested bitrate
2112 */
2113 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2114 * 1000) / bitRate);
2115 if (fecOcDtoPeriod <= 2)
2116 fecOcDtoPeriod = 0;
2117 else
2118 fecOcDtoPeriod -= 2;
2119 fecOcTmdIntUpdRate = 8;
2120 } else {
2121 /* (commonAttr->staticCLK == false) => dynamic mode */
2122 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2123 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2124 fecOcTmdIntUpdRate = 5;
2125 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002127 /* Write appropriate registers with requested configuration */
2128 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2129 if (status < 0)
2130 goto error;
2131 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2132 if (status < 0)
2133 goto error;
2134 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2135 if (status < 0)
2136 goto error;
2137 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2138 if (status < 0)
2139 goto error;
2140 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2141 if (status < 0)
2142 goto error;
2143 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2144 if (status < 0)
2145 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002146
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002147 /* Rate integration settings */
2148 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2149 if (status < 0)
2150 goto error;
2151 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2152 if (status < 0)
2153 goto error;
2154 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2155error:
2156 if (status < 0)
2157 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002158 return status;
2159}
2160
2161static int MPEGTSConfigurePolarity(struct drxk_state *state)
2162{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002163 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002164
2165 /* Data mask for the output data byte */
2166 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002167 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2168 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2169 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2170 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002171
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002172 dprintk(1, "\n");
2173
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002174 /* Control selective inversion of output bits */
2175 fecOcRegIprInvert &= (~(InvertDataMask));
2176 if (state->m_invertDATA == true)
2177 fecOcRegIprInvert |= InvertDataMask;
2178 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2179 if (state->m_invertERR == true)
2180 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2181 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2182 if (state->m_invertSTR == true)
2183 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2184 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2185 if (state->m_invertVAL == true)
2186 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2187 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2188 if (state->m_invertCLK == true)
2189 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002190
2191 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002192}
2193
2194#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2195
2196static int SetAgcRf(struct drxk_state *state,
2197 struct SCfgAgc *pAgcCfg, bool isDTV)
2198{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002199 int status = -EINVAL;
2200 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002201 struct SCfgAgc *pIfAgcSettings;
2202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002203 dprintk(1, "\n");
2204
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002205 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002206 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002207
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002208 switch (pAgcCfg->ctrlMode) {
2209 case DRXK_AGC_CTRL_AUTO:
2210 /* Enable RF AGC DAC */
2211 status = read16(state, IQM_AF_STDBY__A, &data);
2212 if (status < 0)
2213 goto error;
2214 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2215 status = write16(state, IQM_AF_STDBY__A, data);
2216 if (status < 0)
2217 goto error;
2218 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2219 if (status < 0)
2220 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002222 /* Enable SCU RF AGC loop */
2223 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002224
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002225 /* Polarity */
2226 if (state->m_RfAgcPol)
2227 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2228 else
2229 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2230 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2231 if (status < 0)
2232 goto error;
2233
2234 /* Set speed (using complementary reduction value) */
2235 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2236 if (status < 0)
2237 goto error;
2238
2239 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2240 data |= (~(pAgcCfg->speed <<
2241 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2242 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2243
2244 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2245 if (status < 0)
2246 goto error;
2247
2248 if (IsDVBT(state))
2249 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2250 else if (IsQAM(state))
2251 pIfAgcSettings = &state->m_qamIfAgcCfg;
2252 else
2253 pIfAgcSettings = &state->m_atvIfAgcCfg;
2254 if (pIfAgcSettings == NULL) {
2255 status = -EINVAL;
2256 goto error;
2257 }
2258
2259 /* Set TOP, only if IF-AGC is in AUTO mode */
2260 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2261 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002262 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002263 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002264
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002265 /* Cut-Off current */
2266 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2267 if (status < 0)
2268 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002269
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002270 /* Max. output level */
2271 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2272 if (status < 0)
2273 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002274
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002275 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002276
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002277 case DRXK_AGC_CTRL_USER:
2278 /* Enable RF AGC DAC */
2279 status = read16(state, IQM_AF_STDBY__A, &data);
2280 if (status < 0)
2281 goto error;
2282 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2283 status = write16(state, IQM_AF_STDBY__A, data);
2284 if (status < 0)
2285 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002286
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002287 /* Disable SCU RF AGC loop */
2288 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2289 if (status < 0)
2290 goto error;
2291 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2292 if (state->m_RfAgcPol)
2293 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2294 else
2295 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2296 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2297 if (status < 0)
2298 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002299
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002300 /* SCU c.o.c. to 0, enabling full control range */
2301 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2302 if (status < 0)
2303 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002304
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002305 /* Write value to output pin */
2306 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2307 if (status < 0)
2308 goto error;
2309 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002310
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002311 case DRXK_AGC_CTRL_OFF:
2312 /* Disable RF AGC DAC */
2313 status = read16(state, IQM_AF_STDBY__A, &data);
2314 if (status < 0)
2315 goto error;
2316 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2317 status = write16(state, IQM_AF_STDBY__A, data);
2318 if (status < 0)
2319 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002320
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002321 /* Disable SCU RF AGC loop */
2322 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2323 if (status < 0)
2324 goto error;
2325 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2326 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2327 if (status < 0)
2328 goto error;
2329 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002331 default:
2332 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002334 }
2335error:
2336 if (status < 0)
2337 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338 return status;
2339}
2340
2341#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2342
Oliver Endrissebc7de22011-07-03 13:49:44 -03002343static int SetAgcIf(struct drxk_state *state,
2344 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345{
2346 u16 data = 0;
2347 int status = 0;
2348 struct SCfgAgc *pRfAgcSettings;
2349
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002350 dprintk(1, "\n");
2351
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002352 switch (pAgcCfg->ctrlMode) {
2353 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002355 /* Enable IF AGC DAC */
2356 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002357 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002358 goto error;
2359 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2360 status = write16(state, IQM_AF_STDBY__A, data);
2361 if (status < 0)
2362 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2365 if (status < 0)
2366 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002367
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002368 /* Enable SCU IF AGC loop */
2369 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2370
2371 /* Polarity */
2372 if (state->m_IfAgcPol)
2373 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2374 else
2375 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2376 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2377 if (status < 0)
2378 goto error;
2379
2380 /* Set speed (using complementary reduction value) */
2381 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2382 if (status < 0)
2383 goto error;
2384 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2385 data |= (~(pAgcCfg->speed <<
2386 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2387 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2388
2389 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2390 if (status < 0)
2391 goto error;
2392
2393 if (IsQAM(state))
2394 pRfAgcSettings = &state->m_qamRfAgcCfg;
2395 else
2396 pRfAgcSettings = &state->m_atvRfAgcCfg;
2397 if (pRfAgcSettings == NULL)
2398 return -1;
2399 /* Restore TOP */
2400 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2401 if (status < 0)
2402 goto error;
2403 break;
2404
2405 case DRXK_AGC_CTRL_USER:
2406
2407 /* Enable IF AGC DAC */
2408 status = read16(state, IQM_AF_STDBY__A, &data);
2409 if (status < 0)
2410 goto error;
2411 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2412 status = write16(state, IQM_AF_STDBY__A, data);
2413 if (status < 0)
2414 goto error;
2415
2416 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2417 if (status < 0)
2418 goto error;
2419
2420 /* Disable SCU IF AGC loop */
2421 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2422
2423 /* Polarity */
2424 if (state->m_IfAgcPol)
2425 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2426 else
2427 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2428 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2429 if (status < 0)
2430 goto error;
2431
2432 /* Write value to output pin */
2433 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2434 if (status < 0)
2435 goto error;
2436 break;
2437
2438 case DRXK_AGC_CTRL_OFF:
2439
2440 /* Disable If AGC DAC */
2441 status = read16(state, IQM_AF_STDBY__A, &data);
2442 if (status < 0)
2443 goto error;
2444 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2445 status = write16(state, IQM_AF_STDBY__A, data);
2446 if (status < 0)
2447 goto error;
2448
2449 /* Disable SCU IF AGC loop */
2450 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2451 if (status < 0)
2452 goto error;
2453 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2454 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2455 if (status < 0)
2456 goto error;
2457 break;
2458 } /* switch (agcSettingsIf->ctrlMode) */
2459
2460 /* always set the top to support
2461 configurations without if-loop */
2462 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2463error:
2464 if (status < 0)
2465 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002466 return status;
2467}
2468
2469static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2470{
2471 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002472 int status;
2473 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002474
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002475 dprintk(1, "\n");
2476
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002477 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2478 if (status < 0) {
2479 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2480 return status;
2481 }
2482
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002483 *pValue = 0;
2484
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002485 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2486 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2487 if (Level < 14000)
2488 *pValue = (14000 - Level) / 4;
2489 else
2490 *pValue = 0;
2491
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002492 return status;
2493}
2494
Oliver Endrissebc7de22011-07-03 13:49:44 -03002495static int GetQAMSignalToNoise(struct drxk_state *state,
2496 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002497{
2498 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002499 u16 qamSlErrPower = 0; /* accum. error between
2500 raw and sliced symbols */
2501 u32 qamSlSigPower = 0; /* used for MER, depends of
2502 QAM constellation */
2503 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002504
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002505 dprintk(1, "\n");
2506
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002509 /* get the register value needed for MER */
2510 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2511 if (status < 0) {
2512 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2513 return -EINVAL;
2514 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 switch (state->param.u.qam.modulation) {
2517 case QAM_16:
2518 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2519 break;
2520 case QAM_32:
2521 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2522 break;
2523 case QAM_64:
2524 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2525 break;
2526 case QAM_128:
2527 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2528 break;
2529 default:
2530 case QAM_256:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2532 break;
2533 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002534
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002535 if (qamSlErrPower > 0) {
2536 qamSlMer = Log10Times100(qamSlSigPower) -
2537 Log10Times100((u32) qamSlErrPower);
2538 }
2539 *pSignalToNoise = qamSlMer;
2540
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002541 return status;
2542}
2543
Oliver Endrissebc7de22011-07-03 13:49:44 -03002544static int GetDVBTSignalToNoise(struct drxk_state *state,
2545 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002547 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002548 u16 regData = 0;
2549 u32 EqRegTdSqrErrI = 0;
2550 u32 EqRegTdSqrErrQ = 0;
2551 u16 EqRegTdSqrErrExp = 0;
2552 u16 EqRegTdTpsPwrOfs = 0;
2553 u16 EqRegTdReqSmbCnt = 0;
2554 u32 tpsCnt = 0;
2555 u32 SqrErrIQ = 0;
2556 u32 a = 0;
2557 u32 b = 0;
2558 u32 c = 0;
2559 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002560 u16 transmissionParams = 0;
2561
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002562 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002564 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2565 if (status < 0)
2566 goto error;
2567 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2568 if (status < 0)
2569 goto error;
2570 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2571 if (status < 0)
2572 goto error;
2573 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2574 if (status < 0)
2575 goto error;
2576 /* Extend SQR_ERR_I operational range */
2577 EqRegTdSqrErrI = (u32) regData;
2578 if ((EqRegTdSqrErrExp > 11) &&
2579 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2580 EqRegTdSqrErrI += 0x00010000UL;
2581 }
2582 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2583 if (status < 0)
2584 goto error;
2585 /* Extend SQR_ERR_Q operational range */
2586 EqRegTdSqrErrQ = (u32) regData;
2587 if ((EqRegTdSqrErrExp > 11) &&
2588 (EqRegTdSqrErrQ < 0x00000FFFUL))
2589 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002590
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002591 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2592 if (status < 0)
2593 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002595 /* Check input data for MER */
2596
2597 /* MER calculation (in 0.1 dB) without math.h */
2598 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2599 iMER = 0;
2600 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2601 /* No error at all, this must be the HW reset value
2602 * Apparently no first measurement yet
2603 * Set MER to 0.0 */
2604 iMER = 0;
2605 } else {
2606 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2607 EqRegTdSqrErrExp;
2608 if ((transmissionParams &
2609 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2610 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2611 tpsCnt = 17;
2612 else
2613 tpsCnt = 68;
2614
2615 /* IMER = 100 * log10 (x)
2616 where x = (EqRegTdTpsPwrOfs^2 *
2617 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2618
2619 => IMER = a + b -c
2620 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2621 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2622 c = 100 * log10 (SqrErrIQ)
2623 */
2624
2625 /* log(x) x = 9bits * 9bits->18 bits */
2626 a = Log10Times100(EqRegTdTpsPwrOfs *
2627 EqRegTdTpsPwrOfs);
2628 /* log(x) x = 16bits * 7bits->23 bits */
2629 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2630 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2631 c = Log10Times100(SqrErrIQ);
2632
2633 iMER = a + b;
2634 /* No negative MER, clip to zero */
2635 if (iMER > c)
2636 iMER -= c;
2637 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002638 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002639 }
2640 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002641
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002642error:
2643 if (status < 0)
2644 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645 return status;
2646}
2647
2648static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2649{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002650 dprintk(1, "\n");
2651
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002652 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002653 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002654 case OM_DVBT:
2655 return GetDVBTSignalToNoise(state, pSignalToNoise);
2656 case OM_QAM_ITU_A:
2657 case OM_QAM_ITU_C:
2658 return GetQAMSignalToNoise(state, pSignalToNoise);
2659 default:
2660 break;
2661 }
2662 return 0;
2663}
2664
2665#if 0
2666static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2667{
2668 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2669 int status = 0;
2670
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002671 dprintk(1, "\n");
2672
Oliver Endrissebc7de22011-07-03 13:49:44 -03002673 static s32 QE_SN[] = {
2674 51, /* QPSK 1/2 */
2675 69, /* QPSK 2/3 */
2676 79, /* QPSK 3/4 */
2677 89, /* QPSK 5/6 */
2678 97, /* QPSK 7/8 */
2679 108, /* 16-QAM 1/2 */
2680 131, /* 16-QAM 2/3 */
2681 146, /* 16-QAM 3/4 */
2682 156, /* 16-QAM 5/6 */
2683 160, /* 16-QAM 7/8 */
2684 165, /* 64-QAM 1/2 */
2685 187, /* 64-QAM 2/3 */
2686 202, /* 64-QAM 3/4 */
2687 216, /* 64-QAM 5/6 */
2688 225, /* 64-QAM 7/8 */
2689 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002690
2691 *pQuality = 0;
2692
2693 do {
2694 s32 SignalToNoise = 0;
2695 u16 Constellation = 0;
2696 u16 CodeRate = 0;
2697 u32 SignalToNoiseRel;
2698 u32 BERQuality;
2699
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002700 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2701 if (status < 0)
2702 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002703 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002704 if (status < 0)
2705 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002706 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2707
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002708 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002709 if (status < 0)
2710 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002711 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2712
2713 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2714 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2715 break;
2716 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002717 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 BERQuality = 100;
2719
Oliver Endrissebc7de22011-07-03 13:49:44 -03002720 if (SignalToNoiseRel < -70)
2721 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722 else if (SignalToNoiseRel < 30)
2723 *pQuality = ((SignalToNoiseRel + 70) *
2724 BERQuality) / 100;
2725 else
2726 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002728 return 0;
2729};
2730
Oliver Endrissebc7de22011-07-03 13:49:44 -03002731static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002732{
2733 int status = 0;
2734 *pQuality = 0;
2735
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002736 dprintk(1, "\n");
2737
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002738 do {
2739 u32 SignalToNoise = 0;
2740 u32 BERQuality = 100;
2741 u32 SignalToNoiseRel = 0;
2742
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002743 status = GetQAMSignalToNoise(state, &SignalToNoise);
2744 if (status < 0)
2745 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746
Oliver Endrissebc7de22011-07-03 13:49:44 -03002747 switch (state->param.u.qam.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002748 case QAM_16:
2749 SignalToNoiseRel = SignalToNoise - 200;
2750 break;
2751 case QAM_32:
2752 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002753 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002754 case QAM_64:
2755 SignalToNoiseRel = SignalToNoise - 260;
2756 break;
2757 case QAM_128:
2758 SignalToNoiseRel = SignalToNoise - 290;
2759 break;
2760 default:
2761 case QAM_256:
2762 SignalToNoiseRel = SignalToNoise - 320;
2763 break;
2764 }
2765
2766 if (SignalToNoiseRel < -70)
2767 *pQuality = 0;
2768 else if (SignalToNoiseRel < 30)
2769 *pQuality = ((SignalToNoiseRel + 70) *
2770 BERQuality) / 100;
2771 else
2772 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002773 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002774
2775 return status;
2776}
2777
2778static int GetQuality(struct drxk_state *state, s32 *pQuality)
2779{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002780 dprintk(1, "\n");
2781
Oliver Endrissebc7de22011-07-03 13:49:44 -03002782 switch (state->m_OperationMode) {
2783 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002784 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002785 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002786 return GetDVBCQuality(state, pQuality);
2787 default:
2788 break;
2789 }
2790
2791 return 0;
2792}
2793#endif
2794
2795/* Free data ram in SIO HI */
2796#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2797#define SIO_HI_RA_RAM_USR_END__A 0x420060
2798
2799#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2800#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2801#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2802#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2803
2804#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2805#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2806#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2807
2808static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2809{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002810 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002812 dprintk(1, "\n");
2813
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002814 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002816 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002819 if (state->no_i2c_bridge)
2820 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002822 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2823 if (status < 0)
2824 goto error;
2825 if (bEnableBridge) {
2826 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 -03002827 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002828 goto error;
2829 } else {
2830 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2831 if (status < 0)
2832 goto error;
2833 }
2834
2835 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2836
2837error:
2838 if (status < 0)
2839 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840 return status;
2841}
2842
Oliver Endrissebc7de22011-07-03 13:49:44 -03002843static int SetPreSaw(struct drxk_state *state,
2844 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002846 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002847
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002848 dprintk(1, "\n");
2849
Oliver Endrissebc7de22011-07-03 13:49:44 -03002850 if ((pPreSawCfg == NULL)
2851 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002852 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002854 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002855error:
2856 if (status < 0)
2857 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002858 return status;
2859}
2860
2861static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002862 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002864 u16 blStatus = 0;
2865 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2866 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2867 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002868 unsigned long end;
2869
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002870 dprintk(1, "\n");
2871
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002873 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2874 if (status < 0)
2875 goto error;
2876 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2877 if (status < 0)
2878 goto error;
2879 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2880 if (status < 0)
2881 goto error;
2882 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2883 if (status < 0)
2884 goto error;
2885 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2886 if (status < 0)
2887 goto error;
2888 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2889 if (status < 0)
2890 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002891
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002892 end = jiffies + msecs_to_jiffies(timeOut);
2893 do {
2894 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2895 if (status < 0)
2896 goto error;
2897 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2898 if (blStatus == 0x1) {
2899 printk(KERN_ERR "drxk: SIO not ready\n");
2900 status = -EINVAL;
2901 goto error2;
2902 }
2903error:
2904 if (status < 0)
2905 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2906error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002907 mutex_unlock(&state->mutex);
2908 return status;
2909
2910}
2911
Oliver Endrissebc7de22011-07-03 13:49:44 -03002912static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002913{
2914 u16 data = 0;
2915 int status;
2916
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002917 dprintk(1, "\n");
2918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002919 /* Start measurement */
2920 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2921 if (status < 0)
2922 goto error;
2923 status = write16(state, IQM_AF_START_LOCK__A, 1);
2924 if (status < 0)
2925 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002926
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002927 *count = 0;
2928 status = read16(state, IQM_AF_PHASE0__A, &data);
2929 if (status < 0)
2930 goto error;
2931 if (data == 127)
2932 *count = *count + 1;
2933 status = read16(state, IQM_AF_PHASE1__A, &data);
2934 if (status < 0)
2935 goto error;
2936 if (data == 127)
2937 *count = *count + 1;
2938 status = read16(state, IQM_AF_PHASE2__A, &data);
2939 if (status < 0)
2940 goto error;
2941 if (data == 127)
2942 *count = *count + 1;
2943
2944error:
2945 if (status < 0)
2946 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002947 return status;
2948}
2949
2950static int ADCSynchronization(struct drxk_state *state)
2951{
2952 u16 count = 0;
2953 int status;
2954
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002955 dprintk(1, "\n");
2956
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002957 status = ADCSyncMeasurement(state, &count);
2958 if (status < 0)
2959 goto error;
2960
2961 if (count == 1) {
2962 /* Try sampling on a diffrent edge */
2963 u16 clkNeg = 0;
2964
2965 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2966 if (status < 0)
2967 goto error;
2968 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2969 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2970 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2971 clkNeg |=
2972 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2973 } else {
2974 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2975 clkNeg |=
2976 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2977 }
2978 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2979 if (status < 0)
2980 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002981 status = ADCSyncMeasurement(state, &count);
2982 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002983 goto error;
2984 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002985
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002986 if (count < 2)
2987 status = -EINVAL;
2988error:
2989 if (status < 0)
2990 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002991 return status;
2992}
2993
2994static int SetFrequencyShifter(struct drxk_state *state,
2995 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002996 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002997{
2998 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002999 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003000 u32 fmFrequencyShift = 0;
3001 bool tunerMirror = !state->m_bMirrorFreqSpect;
3002 u32 adcFreq;
3003 bool adcFlip;
3004 int status;
3005 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003006 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003007 u32 frequencyShift;
3008 bool imageToSelect;
3009
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003010 dprintk(1, "\n");
3011
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003012 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003013 Program frequency shifter
3014 No need to account for mirroring on RF
3015 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 if (isDTV) {
3017 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3018 (state->m_OperationMode == OM_QAM_ITU_C) ||
3019 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003020 selectPosImage = true;
3021 else
3022 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003023 }
3024 if (tunerMirror)
3025 /* tuner doesn't mirror */
3026 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003027 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 else
3029 /* tuner mirrors */
3030 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003031 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 if (ifFreqActual > samplingFrequency / 2) {
3033 /* adc mirrors */
3034 adcFreq = samplingFrequency - ifFreqActual;
3035 adcFlip = true;
3036 } else {
3037 /* adc doesn't mirror */
3038 adcFreq = ifFreqActual;
3039 adcFlip = false;
3040 }
3041
3042 frequencyShift = adcFreq;
3043 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003044 adcFlip ^ selectPosImage;
3045 state->m_IqmFsRateOfs =
3046 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003047
3048 if (imageToSelect)
3049 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3050
3051 /* Program frequency shifter with tuner offset compensation */
3052 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003053 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3054 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003055 if (status < 0)
3056 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003057 return status;
3058}
3059
3060static int InitAGC(struct drxk_state *state, bool isDTV)
3061{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003062 u16 ingainTgt = 0;
3063 u16 ingainTgtMin = 0;
3064 u16 ingainTgtMax = 0;
3065 u16 clpCyclen = 0;
3066 u16 clpSumMin = 0;
3067 u16 clpDirTo = 0;
3068 u16 snsSumMin = 0;
3069 u16 snsSumMax = 0;
3070 u16 clpSumMax = 0;
3071 u16 snsDirTo = 0;
3072 u16 kiInnergainMin = 0;
3073 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003074 u16 ifIaccuHiTgtMin = 0;
3075 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003076 u16 data = 0;
3077 u16 fastClpCtrlDelay = 0;
3078 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003079 int status = 0;
3080
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003081 dprintk(1, "\n");
3082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003083 /* Common settings */
3084 snsSumMax = 1023;
3085 ifIaccuHiTgtMin = 2047;
3086 clpCyclen = 500;
3087 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003088
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003089 if (IsQAM(state)) {
3090 /* Standard specific settings */
3091 clpSumMin = 8;
3092 clpDirTo = (u16) -9;
3093 clpCtrlMode = 0;
3094 snsSumMin = 8;
3095 snsDirTo = (u16) -9;
3096 kiInnergainMin = (u16) -1030;
3097 } else {
3098 status = -EINVAL;
3099 goto error;
3100 }
3101 if (IsQAM(state)) {
3102 ifIaccuHiTgtMax = 0x2380;
3103 ifIaccuHiTgt = 0x2380;
3104 ingainTgtMin = 0x0511;
3105 ingainTgt = 0x0511;
3106 ingainTgtMax = 5119;
3107 fastClpCtrlDelay =
3108 state->m_qamIfAgcCfg.FastClipCtrlDelay;
3109 } else {
3110 ifIaccuHiTgtMax = 0x1200;
3111 ifIaccuHiTgt = 0x1200;
3112 ingainTgtMin = 13424;
3113 ingainTgt = 13424;
3114 ingainTgtMax = 30000;
3115 fastClpCtrlDelay =
3116 state->m_dvbtIfAgcCfg.FastClipCtrlDelay;
3117 }
3118 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3119 if (status < 0)
3120 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003122 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3153 if (status < 0)
3154 goto error;
3155 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3156 if (status < 0)
3157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003158
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003159 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3160 if (status < 0)
3161 goto error;
3162 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3163 if (status < 0)
3164 goto error;
3165 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3166 if (status < 0)
3167 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003168
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003169 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3173 if (status < 0)
3174 goto error;
3175 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3176 if (status < 0)
3177 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003178
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003179 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3231 if (status < 0)
3232 goto error;
3233 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3234 if (status < 0)
3235 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003236
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003237 /* Initialize inner-loop KI gain factors */
3238 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3239 if (status < 0)
3240 goto error;
3241 if (IsQAM(state)) {
3242 data = 0x0657;
3243 data &= ~SCU_RAM_AGC_KI_RF__M;
3244 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3245 data &= ~SCU_RAM_AGC_KI_IF__M;
3246 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3247 }
3248 status = write16(state, SCU_RAM_AGC_KI__A, data);
3249error:
3250 if (status < 0)
3251 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003252 return status;
3253}
3254
Oliver Endrissebc7de22011-07-03 13:49:44 -03003255static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003256{
3257 int status;
3258
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003259 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003260 if (packetErr == NULL)
3261 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3262 else
3263 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3264 if (status < 0)
3265 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003266 return status;
3267}
3268
3269static int DVBTScCommand(struct drxk_state *state,
3270 u16 cmd, u16 subcmd,
3271 u16 param0, u16 param1, u16 param2,
3272 u16 param3, u16 param4)
3273{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 u16 curCmd = 0;
3275 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003277 u16 scExec = 0;
3278 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003280 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003281 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 if (scExec != 1) {
3283 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003284 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003286 if (status < 0)
3287 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288
3289 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003290 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 do {
3292 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003293 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 retryCnt++;
3295 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003296 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3297 goto error;
3298
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 /* Write sub-command */
3300 switch (cmd) {
3301 /* All commands using sub-cmd */
3302 case OFDM_SC_RA_RAM_CMD_PROC_START:
3303 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3304 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003305 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3306 if (status < 0)
3307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308 break;
3309 default:
3310 /* Do nothing */
3311 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003312 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003313
3314 /* Write needed parameters and the command */
3315 switch (cmd) {
3316 /* All commands using 5 parameters */
3317 /* All commands using 4 parameters */
3318 /* All commands using 3 parameters */
3319 /* All commands using 2 parameters */
3320 case OFDM_SC_RA_RAM_CMD_PROC_START:
3321 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3322 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003323 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003324 /* All commands using 1 parameters */
3325 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3326 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003327 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003328 /* All commands using 0 parameters */
3329 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3330 case OFDM_SC_RA_RAM_CMD_NULL:
3331 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003332 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003333 break;
3334 default:
3335 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003336 status = -EINVAL;
3337 }
3338 if (status < 0)
3339 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340
3341 /* Wait until sc is ready processing command */
3342 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003343 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003345 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003346 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003347 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003348 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3349 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350
3351 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003352 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003353 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003354 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 if (status < 0)
3358 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003359
3360 /* Retreive results parameters from SC */
3361 switch (cmd) {
3362 /* All commands yielding 5 results */
3363 /* All commands yielding 4 results */
3364 /* All commands yielding 3 results */
3365 /* All commands yielding 2 results */
3366 /* All commands yielding 1 result */
3367 case OFDM_SC_RA_RAM_CMD_USER_IO:
3368 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003369 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003370 /* All commands yielding 0 results */
3371 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3372 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3373 case OFDM_SC_RA_RAM_CMD_PROC_START:
3374 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3375 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3376 case OFDM_SC_RA_RAM_CMD_NULL:
3377 break;
3378 default:
3379 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003381 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003382 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003383error:
3384 if (status < 0)
3385 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386 return status;
3387}
3388
Oliver Endrissebc7de22011-07-03 13:49:44 -03003389static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003391 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003392 int status;
3393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003394 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003395 status = CtrlPowerMode(state, &powerMode);
3396 if (status < 0)
3397 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 return status;
3399}
3400
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003405 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003407 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003410 if (status < 0)
3411 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003412 return status;
3413}
3414
3415#define DEFAULT_FR_THRES_8K 4000
3416static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3417{
3418
3419 int status;
3420
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003421 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003422 if (*enabled == true) {
3423 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003424 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 DEFAULT_FR_THRES_8K);
3426 } else {
3427 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003428 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003430 if (status < 0)
3431 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003432
3433 return status;
3434}
3435
3436static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3437 struct DRXKCfgDvbtEchoThres_t *echoThres)
3438{
3439 u16 data = 0;
3440 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003441
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003442 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003443 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3444 if (status < 0)
3445 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003447 switch (echoThres->fftMode) {
3448 case DRX_FFTMODE_2K:
3449 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3450 data |= ((echoThres->threshold <<
3451 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3452 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3453 goto error;
3454 case DRX_FFTMODE_8K:
3455 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3456 data |= ((echoThres->threshold <<
3457 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3458 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3459 goto error;
3460 default:
3461 return -EINVAL;
3462 goto error;
3463 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003464
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003465 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3466error:
3467 if (status < 0)
3468 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003469 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470}
3471
3472static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003473 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003475 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003477 dprintk(1, "\n");
3478
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003479 switch (*speed) {
3480 case DRXK_DVBT_SQI_SPEED_FAST:
3481 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3482 case DRXK_DVBT_SQI_SPEED_SLOW:
3483 break;
3484 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003485 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003486 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003487 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003488 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003489error:
3490 if (status < 0)
3491 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003492 return status;
3493}
3494
3495/*============================================================================*/
3496
3497/**
3498* \brief Activate DVBT specific presets
3499* \param demod instance of demodulator.
3500* \return DRXStatus_t.
3501*
3502* Called in DVBTSetStandard
3503*
3504*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003505static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003506{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003508 bool setincenable = false;
3509 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510
Oliver Endrissebc7de22011-07-03 13:49:44 -03003511 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3512 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003513
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003514 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003515 status = DVBTCtrlSetIncEnable(state, &setincenable);
3516 if (status < 0)
3517 goto error;
3518 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3519 if (status < 0)
3520 goto error;
3521 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3522 if (status < 0)
3523 goto error;
3524 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3525 if (status < 0)
3526 goto error;
3527 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3528error:
3529 if (status < 0)
3530 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003531 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003532}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003533
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534/*============================================================================*/
3535
3536/**
3537* \brief Initialize channelswitch-independent settings for DVBT.
3538* \param demod instance of demodulator.
3539* \return DRXStatus_t.
3540*
3541* For ROM code channel filter taps are loaded from the bootloader. For microcode
3542* the DVB-T taps from the drxk_filters.h are used.
3543*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003544static int SetDVBTStandard(struct drxk_state *state,
3545 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003547 u16 cmdResult = 0;
3548 u16 data = 0;
3549 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003550
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003551 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003553 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003554 /* added antenna switch */
3555 SwitchAntennaToDVBT(state);
3556 /* send OFDM reset command */
3557 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 -03003558 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003559 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003560
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003561 /* send OFDM setenv command */
3562 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3563 if (status < 0)
3564 goto error;
3565
3566 /* reset datapath for OFDM, processors first */
3567 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3568 if (status < 0)
3569 goto error;
3570 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3571 if (status < 0)
3572 goto error;
3573 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3574 if (status < 0)
3575 goto error;
3576
3577 /* IQM setup */
3578 /* synchronize on ofdstate->m_festart */
3579 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3580 if (status < 0)
3581 goto error;
3582 /* window size for clipping ADC detection */
3583 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3584 if (status < 0)
3585 goto error;
3586 /* window size for for sense pre-SAW detection */
3587 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3588 if (status < 0)
3589 goto error;
3590 /* sense threshold for sense pre-SAW detection */
3591 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3592 if (status < 0)
3593 goto error;
3594 status = SetIqmAf(state, true);
3595 if (status < 0)
3596 goto error;
3597
3598 status = write16(state, IQM_AF_AGC_RF__A, 0);
3599 if (status < 0)
3600 goto error;
3601
3602 /* Impulse noise cruncher setup */
3603 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3604 if (status < 0)
3605 goto error;
3606 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3607 if (status < 0)
3608 goto error;
3609 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3610 if (status < 0)
3611 goto error;
3612
3613 status = write16(state, IQM_RC_STRETCH__A, 16);
3614 if (status < 0)
3615 goto error;
3616 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3617 if (status < 0)
3618 goto error;
3619 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3620 if (status < 0)
3621 goto error;
3622 status = write16(state, IQM_CF_SCALE__A, 1600);
3623 if (status < 0)
3624 goto error;
3625 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3626 if (status < 0)
3627 goto error;
3628
3629 /* virtual clipping threshold for clipping ADC detection */
3630 status = write16(state, IQM_AF_CLP_TH__A, 448);
3631 if (status < 0)
3632 goto error;
3633 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3634 if (status < 0)
3635 goto error;
3636
3637 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3638 if (status < 0)
3639 goto error;
3640
3641 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3642 if (status < 0)
3643 goto error;
3644 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3645 if (status < 0)
3646 goto error;
3647 /* enable power measurement interrupt */
3648 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3649 if (status < 0)
3650 goto error;
3651 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3652 if (status < 0)
3653 goto error;
3654
3655 /* IQM will not be reset from here, sync ADC and update/init AGC */
3656 status = ADCSynchronization(state);
3657 if (status < 0)
3658 goto error;
3659 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3660 if (status < 0)
3661 goto error;
3662
3663 /* Halt SCU to enable safe non-atomic accesses */
3664 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3665 if (status < 0)
3666 goto error;
3667
3668 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3669 if (status < 0)
3670 goto error;
3671 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3672 if (status < 0)
3673 goto error;
3674
3675 /* Set Noise Estimation notch width and enable DC fix */
3676 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3677 if (status < 0)
3678 goto error;
3679 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3680 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3681 if (status < 0)
3682 goto error;
3683
3684 /* Activate SCU to enable SCU commands */
3685 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3686 if (status < 0)
3687 goto error;
3688
3689 if (!state->m_DRXK_A3_ROM_CODE) {
3690 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3691 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3692 if (status < 0)
3693 goto error;
3694 }
3695
3696 /* OFDM_SC setup */
3697#ifdef COMPILE_FOR_NONRT
3698 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3699 if (status < 0)
3700 goto error;
3701 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3702 if (status < 0)
3703 goto error;
3704#endif
3705
3706 /* FEC setup */
3707 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3708 if (status < 0)
3709 goto error;
3710
3711
3712#ifdef COMPILE_FOR_NONRT
3713 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3714 if (status < 0)
3715 goto error;
3716#else
3717 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3718 if (status < 0)
3719 goto error;
3720#endif
3721 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3722 if (status < 0)
3723 goto error;
3724
3725 /* Setup MPEG bus */
3726 status = MPEGTSDtoSetup(state, OM_DVBT);
3727 if (status < 0)
3728 goto error;
3729 /* Set DVBT Presets */
3730 status = DVBTActivatePresets(state);
3731 if (status < 0)
3732 goto error;
3733
3734error:
3735 if (status < 0)
3736 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003737 return status;
3738}
3739
3740/*============================================================================*/
3741/**
3742* \brief Start dvbt demodulating for channel.
3743* \param demod instance of demodulator.
3744* \return DRXStatus_t.
3745*/
3746static int DVBTStart(struct drxk_state *state)
3747{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003748 u16 param1;
3749 int status;
3750 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003752 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003753 /* Start correct processes to get in lock */
3754 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003755 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3756 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3757 if (status < 0)
3758 goto error;
3759 /* Start FEC OC */
3760 status = MPEGTSStart(state);
3761 if (status < 0)
3762 goto error;
3763 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3764 if (status < 0)
3765 goto error;
3766error:
3767 if (status < 0)
3768 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003769 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003770}
3771
3772
3773/*============================================================================*/
3774
3775/**
3776* \brief Set up dvbt demodulator for channel.
3777* \param demod instance of demodulator.
3778* \return DRXStatus_t.
3779* // original DVBTSetChannel()
3780*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003781static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3782 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003783{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003784 u16 cmdResult = 0;
3785 u16 transmissionParams = 0;
3786 u16 operationMode = 0;
3787 u32 iqmRcRateOfs = 0;
3788 u32 bandwidth = 0;
3789 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003790 int status;
3791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003792 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3795 if (status < 0)
3796 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003798 /* Halt SCU to enable safe non-atomic accesses */
3799 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3800 if (status < 0)
3801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003803 /* Stop processors */
3804 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3805 if (status < 0)
3806 goto error;
3807 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3808 if (status < 0)
3809 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003811 /* Mandatory fix, always stop CP, required to set spl offset back to
3812 hardware default (is set to 0 by ucode during pilot detection */
3813 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3814 if (status < 0)
3815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003816
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003817 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /* mode */
3820 switch (state->param.u.ofdm.transmission_mode) {
3821 case TRANSMISSION_MODE_AUTO:
3822 default:
3823 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3824 /* fall through , try first guess DRX_FFTMODE_8K */
3825 case TRANSMISSION_MODE_8K:
3826 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3827 goto error;
3828 case TRANSMISSION_MODE_2K:
3829 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3830 goto error;
3831 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 /* guard */
3834 switch (state->param.u.ofdm.guard_interval) {
3835 default:
3836 case GUARD_INTERVAL_AUTO:
3837 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3838 /* fall through , try first guess DRX_GUARD_1DIV4 */
3839 case GUARD_INTERVAL_1_4:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3841 goto error;
3842 case GUARD_INTERVAL_1_32:
3843 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3844 goto error;
3845 case GUARD_INTERVAL_1_16:
3846 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3847 goto error;
3848 case GUARD_INTERVAL_1_8:
3849 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3850 goto error;
3851 }
3852
3853 /* hierarchy */
3854 switch (state->param.u.ofdm.hierarchy_information) {
3855 case HIERARCHY_AUTO:
3856 case HIERARCHY_NONE:
3857 default:
3858 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3859 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3860 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3861 /* break; */
3862 case HIERARCHY_1:
3863 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3864 break;
3865 case HIERARCHY_2:
3866 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3867 break;
3868 case HIERARCHY_4:
3869 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3870 break;
3871 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003872
3873
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003874 /* constellation */
3875 switch (state->param.u.ofdm.constellation) {
3876 case QAM_AUTO:
3877 default:
3878 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3879 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3880 case QAM_64:
3881 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3882 break;
3883 case QPSK:
3884 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3885 break;
3886 case QAM_16:
3887 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3888 break;
3889 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003890#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003891 /* No hierachical channels support in BDA */
3892 /* Priority (only for hierarchical channels) */
3893 switch (channel->priority) {
3894 case DRX_PRIORITY_LOW:
3895 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3896 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3897 OFDM_EC_SB_PRIOR_LO);
3898 break;
3899 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003900 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003901 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3902 OFDM_EC_SB_PRIOR_HI));
3903 break;
3904 case DRX_PRIORITY_UNKNOWN: /* fall through */
3905 default:
3906 status = -EINVAL;
3907 goto error;
3908 }
3909#else
3910 /* Set Priorty high */
3911 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3912 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3913 if (status < 0)
3914 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003915#endif
3916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003917 /* coderate */
3918 switch (state->param.u.ofdm.code_rate_HP) {
3919 case FEC_AUTO:
3920 default:
3921 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3922 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3923 case FEC_2_3:
3924 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3925 break;
3926 case FEC_1_2:
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3928 break;
3929 case FEC_3_4:
3930 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3931 break;
3932 case FEC_5_6:
3933 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3934 break;
3935 case FEC_7_8:
3936 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3937 break;
3938 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003939
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003940 /* SAW filter selection: normaly not necesarry, but if wanted
3941 the application can select a SAW filter via the driver by using UIOs */
3942 /* First determine real bandwidth (Hz) */
3943 /* Also set delay for impulse noise cruncher */
3944 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3945 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3946 functions */
3947 switch (state->param.u.ofdm.bandwidth) {
3948 case BANDWIDTH_AUTO:
3949 case BANDWIDTH_8_MHZ:
3950 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3951 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003952 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003953 goto error;
3954 /* cochannel protection for PAL 8 MHz */
3955 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3956 if (status < 0)
3957 goto error;
3958 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3959 if (status < 0)
3960 goto error;
3961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3962 if (status < 0)
3963 goto error;
3964 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3965 if (status < 0)
3966 goto error;
3967 break;
3968 case BANDWIDTH_7_MHZ:
3969 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3970 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3971 if (status < 0)
3972 goto error;
3973 /* cochannel protection for PAL 7 MHz */
3974 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3975 if (status < 0)
3976 goto error;
3977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3978 if (status < 0)
3979 goto error;
3980 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3981 if (status < 0)
3982 goto error;
3983 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3984 if (status < 0)
3985 goto error;
3986 break;
3987 case BANDWIDTH_6_MHZ:
3988 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3989 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3990 if (status < 0)
3991 goto error;
3992 /* cochannel protection for NTSC 6 MHz */
3993 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3994 if (status < 0)
3995 goto error;
3996 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3997 if (status < 0)
3998 goto error;
3999 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4000 if (status < 0)
4001 goto error;
4002 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4003 if (status < 0)
4004 goto error;
4005 break;
4006 default:
4007 status = -EINVAL;
4008 goto error;
4009 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004011 if (iqmRcRateOfs == 0) {
4012 /* Now compute IQM_RC_RATE_OFS
4013 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4014 =>
4015 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4016 */
4017 /* (SysFreq / BandWidth) * (2^28) */
4018 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4019 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4020 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4021 iqmRcRateOfs = Frac28a((u32)
4022 ((state->m_sysClockFreq *
4023 1000) / 3), bandwidth);
4024 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4025 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4026 iqmRcRateOfs += 0x80L;
4027 iqmRcRateOfs = iqmRcRateOfs >> 7;
4028 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4029 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4030 }
4031
4032 iqmRcRateOfs &=
4033 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4034 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4035 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4036 if (status < 0)
4037 goto error;
4038
4039 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004040
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004041#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004042 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4043 if (status < 0)
4044 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004045#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004046 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4047 if (status < 0)
4048 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004050 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004052 /* Activate SCU to enable SCU commands */
4053 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4054 if (status < 0)
4055 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004056
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004057 /* Enable SC after setting all other parameters */
4058 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4059 if (status < 0)
4060 goto error;
4061 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4062 if (status < 0)
4063 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004064
4065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004066 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4067 if (status < 0)
4068 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004069
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004070 /* Write SC parameter registers, set all AUTO flags in operation mode */
4071 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4072 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4073 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4074 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4075 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4076 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4077 0, transmissionParams, param1, 0, 0, 0);
4078 if (status < 0)
4079 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004081 if (!state->m_DRXK_A3_ROM_CODE)
4082 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4083error:
4084 if (status < 0)
4085 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004086
4087 return status;
4088}
4089
4090
4091/*============================================================================*/
4092
4093/**
4094* \brief Retreive lock status .
4095* \param demod Pointer to demodulator instance.
4096* \param lockStat Pointer to lock status structure.
4097* \return DRXStatus_t.
4098*
4099*/
4100static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4101{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004102 int status;
4103 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4104 OFDM_SC_RA_RAM_LOCK_FEC__M);
4105 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4106 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004107
Oliver Endrissebc7de22011-07-03 13:49:44 -03004108 u16 ScRaRamLock = 0;
4109 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004110
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004111 dprintk(1, "\n");
4112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004113 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004114 /* driver 0.9.0 */
4115 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004116 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004117 if (status < 0)
4118 goto end;
4119 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4120 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004121
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004122 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004123 if (status < 0)
4124 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125
Oliver Endrissebc7de22011-07-03 13:49:44 -03004126 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4127 *pLockStatus = MPEG_LOCK;
4128 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4129 *pLockStatus = FEC_LOCK;
4130 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4131 *pLockStatus = DEMOD_LOCK;
4132 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4133 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004134end:
4135 if (status < 0)
4136 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004137
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004139}
4140
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004143 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004144 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004145
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004146 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004147 status = CtrlPowerMode(state, &powerMode);
4148 if (status < 0)
4149 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004150
Oliver Endrissebc7de22011-07-03 13:49:44 -03004151 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152}
4153
4154
Oliver Endrissebc7de22011-07-03 13:49:44 -03004155/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156static int PowerDownQAM(struct drxk_state *state)
4157{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004158 u16 data = 0;
4159 u16 cmdResult;
4160 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004161
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004162 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004163 status = read16(state, SCU_COMM_EXEC__A, &data);
4164 if (status < 0)
4165 goto error;
4166 if (data == SCU_COMM_EXEC_ACTIVE) {
4167 /*
4168 STOP demodulator
4169 QAM and HW blocks
4170 */
4171 /* stop all comstate->m_exec */
4172 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004173 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004174 goto error;
4175 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 -03004176 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004177 goto error;
4178 }
4179 /* powerdown AFE */
4180 status = SetIqmAf(state, false);
4181
4182error:
4183 if (status < 0)
4184 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004185
Oliver Endrissebc7de22011-07-03 13:49:44 -03004186 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004187}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004188
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004189/*============================================================================*/
4190
4191/**
4192* \brief Setup of the QAM Measurement intervals for signal quality
4193* \param demod instance of demod.
4194* \param constellation current constellation.
4195* \return DRXStatus_t.
4196*
4197* NOTE:
4198* Take into account that for certain settings the errorcounters can overflow.
4199* The implementation does not check this.
4200*
4201*/
4202static int SetQAMMeasurement(struct drxk_state *state,
4203 enum EDrxkConstellation constellation,
4204 u32 symbolRate)
4205{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004206 u32 fecBitsDesired = 0; /* BER accounting period */
4207 u32 fecRsPeriodTotal = 0; /* Total period */
4208 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4209 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004210 int status = 0;
4211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004212 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004213
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004214 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004215 /* fecBitsDesired = symbolRate [kHz] *
4216 FrameLenght [ms] *
4217 (constellation + 1) *
4218 SyncLoss (== 1) *
4219 ViterbiLoss (==1)
4220 */
4221 switch (constellation) {
4222 case DRX_CONSTELLATION_QAM16:
4223 fecBitsDesired = 4 * symbolRate;
4224 break;
4225 case DRX_CONSTELLATION_QAM32:
4226 fecBitsDesired = 5 * symbolRate;
4227 break;
4228 case DRX_CONSTELLATION_QAM64:
4229 fecBitsDesired = 6 * symbolRate;
4230 break;
4231 case DRX_CONSTELLATION_QAM128:
4232 fecBitsDesired = 7 * symbolRate;
4233 break;
4234 case DRX_CONSTELLATION_QAM256:
4235 fecBitsDesired = 8 * symbolRate;
4236 break;
4237 default:
4238 status = -EINVAL;
4239 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004240 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004241 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004242
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004243 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4244 fecBitsDesired *= 500; /* meas. period [ms] */
4245
4246 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4247 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4248 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4249
4250 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4251 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4252 if (fecRsPrescale == 0) {
4253 /* Divide by zero (though impossible) */
4254 status = -EINVAL;
4255 if (status < 0)
4256 goto error;
4257 }
4258 fecRsPeriod =
4259 ((u16) fecRsPeriodTotal +
4260 (fecRsPrescale >> 1)) / fecRsPrescale;
4261
4262 /* write corresponding registers */
4263 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4264 if (status < 0)
4265 goto error;
4266 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4267 if (status < 0)
4268 goto error;
4269 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4270error:
4271 if (status < 0)
4272 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004273 return status;
4274}
4275
Oliver Endrissebc7de22011-07-03 13:49:44 -03004276static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004277{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004278 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004279
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004280 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004281 /* QAM Equalizer Setup */
4282 /* Equalizer */
4283 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4284 if (status < 0)
4285 goto error;
4286 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4287 if (status < 0)
4288 goto error;
4289 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4290 if (status < 0)
4291 goto error;
4292 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4293 if (status < 0)
4294 goto error;
4295 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4299 if (status < 0)
4300 goto error;
4301 /* Decision Feedback Equalizer */
4302 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4303 if (status < 0)
4304 goto error;
4305 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4306 if (status < 0)
4307 goto error;
4308 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4309 if (status < 0)
4310 goto error;
4311 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4312 if (status < 0)
4313 goto error;
4314 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4315 if (status < 0)
4316 goto error;
4317 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4318 if (status < 0)
4319 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004320
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004321 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4322 if (status < 0)
4323 goto error;
4324 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4325 if (status < 0)
4326 goto error;
4327 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
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 Slicer Settings */
4332 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4333 if (status < 0)
4334 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004335
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004336 /* QAM Loop Controller Coeficients */
4337 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4338 if (status < 0)
4339 goto error;
4340 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4341 if (status < 0)
4342 goto error;
4343 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4344 if (status < 0)
4345 goto error;
4346 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4347 if (status < 0)
4348 goto error;
4349 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4350 if (status < 0)
4351 goto error;
4352 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4353 if (status < 0)
4354 goto error;
4355 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4359 if (status < 0)
4360 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004361
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004362 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4363 if (status < 0)
4364 goto error;
4365 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4366 if (status < 0)
4367 goto error;
4368 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4372 if (status < 0)
4373 goto error;
4374 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4375 if (status < 0)
4376 goto error;
4377 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4378 if (status < 0)
4379 goto error;
4380 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4387 if (status < 0)
4388 goto error;
4389 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4390 if (status < 0)
4391 goto error;
4392 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4393 if (status < 0)
4394 goto error;
4395 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4396 if (status < 0)
4397 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004398
4399
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004400 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004401
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004402 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4403 if (status < 0)
4404 goto error;
4405 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4412 if (status < 0)
4413 goto error;
4414 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4418 if (status < 0)
4419 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004420
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004421 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4422 if (status < 0)
4423 goto error;
4424 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4425 if (status < 0)
4426 goto error;
4427 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4428 if (status < 0)
4429 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004430
4431
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004432 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004434 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4435 if (status < 0)
4436 goto error;
4437 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4444 if (status < 0)
4445 goto error;
4446 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4447 if (status < 0)
4448 goto error;
4449 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4450 if (status < 0)
4451 goto error;
4452 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4453 if (status < 0)
4454 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004455
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004456error:
4457 if (status < 0)
4458 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004459 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004460}
4461
4462/*============================================================================*/
4463
4464/**
4465* \brief QAM32 specific setup
4466* \param demod instance of demod.
4467* \return DRXStatus_t.
4468*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004469static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004470{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004471 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004472
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004473 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004474
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004475 /* QAM Equalizer Setup */
4476 /* Equalizer */
4477 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4478 if (status < 0)
4479 goto error;
4480 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4481 if (status < 0)
4482 goto error;
4483 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4487 if (status < 0)
4488 goto error;
4489 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4490 if (status < 0)
4491 goto error;
4492 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4493 if (status < 0)
4494 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004495
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004496 /* Decision Feedback Equalizer */
4497 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4498 if (status < 0)
4499 goto error;
4500 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4501 if (status < 0)
4502 goto error;
4503 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4504 if (status < 0)
4505 goto error;
4506 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4507 if (status < 0)
4508 goto error;
4509 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4510 if (status < 0)
4511 goto error;
4512 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4513 if (status < 0)
4514 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004516 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4517 if (status < 0)
4518 goto error;
4519 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4520 if (status < 0)
4521 goto error;
4522 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4523 if (status < 0)
4524 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004525
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004526 /* QAM Slicer Settings */
4527
4528 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4529 if (status < 0)
4530 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004531
4532
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004533 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004534
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004535 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4536 if (status < 0)
4537 goto error;
4538 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4539 if (status < 0)
4540 goto error;
4541 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4542 if (status < 0)
4543 goto error;
4544 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4545 if (status < 0)
4546 goto error;
4547 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4548 if (status < 0)
4549 goto error;
4550 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4551 if (status < 0)
4552 goto error;
4553 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4557 if (status < 0)
4558 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004559
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004560 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4561 if (status < 0)
4562 goto error;
4563 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4564 if (status < 0)
4565 goto error;
4566 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4567 if (status < 0)
4568 goto error;
4569 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4585 if (status < 0)
4586 goto error;
4587 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4588 if (status < 0)
4589 goto error;
4590 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4594 if (status < 0)
4595 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004596
4597
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004598 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004599
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004600 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4601 if (status < 0)
4602 goto error;
4603 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4604 if (status < 0)
4605 goto error;
4606 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4607 if (status < 0)
4608 goto error;
4609 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4610 if (status < 0)
4611 goto error;
4612 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4613 if (status < 0)
4614 goto error;
4615 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4616 if (status < 0)
4617 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004618
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004619 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4620 if (status < 0)
4621 goto error;
4622 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4623 if (status < 0)
4624 goto error;
4625 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4626 if (status < 0)
4627 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004628
4629
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004630 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004631
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004632 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4633 if (status < 0)
4634 goto error;
4635 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4642 if (status < 0)
4643 goto error;
4644 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4645 if (status < 0)
4646 goto error;
4647 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4648 if (status < 0)
4649 goto error;
4650 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4651error:
4652 if (status < 0)
4653 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004654 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004655}
4656
4657/*============================================================================*/
4658
4659/**
4660* \brief QAM64 specific setup
4661* \param demod instance of demod.
4662* \return DRXStatus_t.
4663*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004664static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004665{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004666 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004667
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004668 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004669 /* QAM Equalizer Setup */
4670 /* Equalizer */
4671 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4672 if (status < 0)
4673 goto error;
4674 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4675 if (status < 0)
4676 goto error;
4677 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4678 if (status < 0)
4679 goto error;
4680 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4681 if (status < 0)
4682 goto error;
4683 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4684 if (status < 0)
4685 goto error;
4686 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4687 if (status < 0)
4688 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004689
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004690 /* Decision Feedback Equalizer */
4691 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4692 if (status < 0)
4693 goto error;
4694 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4695 if (status < 0)
4696 goto error;
4697 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4707 if (status < 0)
4708 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004709
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004710 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4711 if (status < 0)
4712 goto error;
4713 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4717 if (status < 0)
4718 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004720 /* QAM Slicer Settings */
4721 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4722 if (status < 0)
4723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004724
4725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004726 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004728 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4729 if (status < 0)
4730 goto error;
4731 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4732 if (status < 0)
4733 goto error;
4734 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4735 if (status < 0)
4736 goto error;
4737 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4738 if (status < 0)
4739 goto error;
4740 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4741 if (status < 0)
4742 goto error;
4743 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4744 if (status < 0)
4745 goto error;
4746 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4750 if (status < 0)
4751 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004753 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4754 if (status < 0)
4755 goto error;
4756 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4757 if (status < 0)
4758 goto error;
4759 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4760 if (status < 0)
4761 goto error;
4762 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4763 if (status < 0)
4764 goto error;
4765 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4766 if (status < 0)
4767 goto error;
4768 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4769 if (status < 0)
4770 goto error;
4771 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4772 if (status < 0)
4773 goto error;
4774 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4775 if (status < 0)
4776 goto error;
4777 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4778 if (status < 0)
4779 goto error;
4780 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4781 if (status < 0)
4782 goto error;
4783 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4787 if (status < 0)
4788 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004789
4790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004791 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004792
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004793 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4794 if (status < 0)
4795 goto error;
4796 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4797 if (status < 0)
4798 goto error;
4799 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4800 if (status < 0)
4801 goto error;
4802 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4809 if (status < 0)
4810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004811
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004812 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4813 if (status < 0)
4814 goto error;
4815 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4816 if (status < 0)
4817 goto error;
4818 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4819 if (status < 0)
4820 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004821
4822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004823 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004824
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004825 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4826 if (status < 0)
4827 goto error;
4828 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4835 if (status < 0)
4836 goto error;
4837 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4838 if (status < 0)
4839 goto error;
4840 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4841 if (status < 0)
4842 goto error;
4843 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4844error:
4845 if (status < 0)
4846 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847
Oliver Endrissebc7de22011-07-03 13:49:44 -03004848 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004849}
4850
4851/*============================================================================*/
4852
4853/**
4854* \brief QAM128 specific setup
4855* \param demod: instance of demod.
4856* \return DRXStatus_t.
4857*/
4858static int SetQAM128(struct drxk_state *state)
4859{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004860 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004861
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004862 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004863 /* QAM Equalizer Setup */
4864 /* Equalizer */
4865 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4866 if (status < 0)
4867 goto error;
4868 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4869 if (status < 0)
4870 goto error;
4871 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4881 if (status < 0)
4882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004883
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004884 /* Decision Feedback Equalizer */
4885 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4886 if (status < 0)
4887 goto error;
4888 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4889 if (status < 0)
4890 goto error;
4891 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4892 if (status < 0)
4893 goto error;
4894 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4895 if (status < 0)
4896 goto error;
4897 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4898 if (status < 0)
4899 goto error;
4900 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4901 if (status < 0)
4902 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004903
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004904 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4905 if (status < 0)
4906 goto error;
4907 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4908 if (status < 0)
4909 goto error;
4910 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4911 if (status < 0)
4912 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004913
4914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004915 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4918 if (status < 0)
4919 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004920
4921
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004922 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004923
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004924 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4925 if (status < 0)
4926 goto error;
4927 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4928 if (status < 0)
4929 goto error;
4930 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4934 if (status < 0)
4935 goto error;
4936 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4937 if (status < 0)
4938 goto error;
4939 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4940 if (status < 0)
4941 goto error;
4942 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4946 if (status < 0)
4947 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004948
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004949 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4950 if (status < 0)
4951 goto error;
4952 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4953 if (status < 0)
4954 goto error;
4955 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4959 if (status < 0)
4960 goto error;
4961 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4962 if (status < 0)
4963 goto error;
4964 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4965 if (status < 0)
4966 goto error;
4967 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4974 if (status < 0)
4975 goto error;
4976 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4983 if (status < 0)
4984 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004985
4986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004987 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004988
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004989 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4990 if (status < 0)
4991 goto error;
4992 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4996 if (status < 0)
4997 goto error;
4998 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5005 if (status < 0)
5006 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005008 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5009 if (status < 0)
5010 goto error;
5011 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5012 if (status < 0)
5013 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005015 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5016 if (status < 0)
5017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005019 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005020
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005021 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5022 if (status < 0)
5023 goto error;
5024 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5025 if (status < 0)
5026 goto error;
5027 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5031 if (status < 0)
5032 goto error;
5033 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5034 if (status < 0)
5035 goto error;
5036 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5037 if (status < 0)
5038 goto error;
5039 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5040error:
5041 if (status < 0)
5042 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005043
Oliver Endrissebc7de22011-07-03 13:49:44 -03005044 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005045}
5046
5047/*============================================================================*/
5048
5049/**
5050* \brief QAM256 specific setup
5051* \param demod: instance of demod.
5052* \return DRXStatus_t.
5053*/
5054static int SetQAM256(struct drxk_state *state)
5055{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005056 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005057
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005058 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005059 /* QAM Equalizer Setup */
5060 /* Equalizer */
5061 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5062 if (status < 0)
5063 goto error;
5064 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5065 if (status < 0)
5066 goto error;
5067 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5074 if (status < 0)
5075 goto error;
5076 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5077 if (status < 0)
5078 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005080 /* Decision Feedback Equalizer */
5081 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5082 if (status < 0)
5083 goto error;
5084 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5085 if (status < 0)
5086 goto error;
5087 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5088 if (status < 0)
5089 goto error;
5090 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5091 if (status < 0)
5092 goto error;
5093 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5094 if (status < 0)
5095 goto error;
5096 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5097 if (status < 0)
5098 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005099
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005100 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5101 if (status < 0)
5102 goto error;
5103 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5104 if (status < 0)
5105 goto error;
5106 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5107 if (status < 0)
5108 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005110 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5113 if (status < 0)
5114 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005115
5116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005117 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005119 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5120 if (status < 0)
5121 goto error;
5122 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5123 if (status < 0)
5124 goto error;
5125 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5126 if (status < 0)
5127 goto error;
5128 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5129 if (status < 0)
5130 goto error;
5131 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5132 if (status < 0)
5133 goto error;
5134 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5135 if (status < 0)
5136 goto error;
5137 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5141 if (status < 0)
5142 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005143
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005144 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5145 if (status < 0)
5146 goto error;
5147 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5148 if (status < 0)
5149 goto error;
5150 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5151 if (status < 0)
5152 goto error;
5153 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5154 if (status < 0)
5155 goto error;
5156 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5157 if (status < 0)
5158 goto error;
5159 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5160 if (status < 0)
5161 goto error;
5162 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5163 if (status < 0)
5164 goto error;
5165 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5166 if (status < 0)
5167 goto error;
5168 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5169 if (status < 0)
5170 goto error;
5171 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5172 if (status < 0)
5173 goto error;
5174 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5175 if (status < 0)
5176 goto error;
5177 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5178 if (status < 0)
5179 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005180
5181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005182 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005183
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005184 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5185 if (status < 0)
5186 goto error;
5187 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5188 if (status < 0)
5189 goto error;
5190 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5191 if (status < 0)
5192 goto error;
5193 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5194 if (status < 0)
5195 goto error;
5196 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5197 if (status < 0)
5198 goto error;
5199 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5200 if (status < 0)
5201 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005202
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005203 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5204 if (status < 0)
5205 goto error;
5206 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5207 if (status < 0)
5208 goto error;
5209 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5210 if (status < 0)
5211 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005212
5213
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005214 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005216 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5217 if (status < 0)
5218 goto error;
5219 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5220 if (status < 0)
5221 goto error;
5222 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5223 if (status < 0)
5224 goto error;
5225 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5226 if (status < 0)
5227 goto error;
5228 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5229 if (status < 0)
5230 goto error;
5231 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5232 if (status < 0)
5233 goto error;
5234 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5235error:
5236 if (status < 0)
5237 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005238 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005239}
5240
5241
5242/*============================================================================*/
5243/**
5244* \brief Reset QAM block.
5245* \param demod: instance of demod.
5246* \param channel: pointer to channel data.
5247* \return DRXStatus_t.
5248*/
5249static int QAMResetQAM(struct drxk_state *state)
5250{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005251 int status;
5252 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005253
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005254 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005255 /* Stop QAM comstate->m_exec */
5256 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5257 if (status < 0)
5258 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005259
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005260 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5261error:
5262 if (status < 0)
5263 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005264 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005265}
5266
5267/*============================================================================*/
5268
5269/**
5270* \brief Set QAM symbolrate.
5271* \param demod: instance of demod.
5272* \param channel: pointer to channel data.
5273* \return DRXStatus_t.
5274*/
5275static int QAMSetSymbolrate(struct drxk_state *state)
5276{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005277 u32 adcFrequency = 0;
5278 u32 symbFreq = 0;
5279 u32 iqmRcRate = 0;
5280 u16 ratesel = 0;
5281 u32 lcSymbRate = 0;
5282 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005283
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005284 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005285 /* Select & calculate correct IQM rate */
5286 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5287 ratesel = 0;
5288 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5289 if (state->param.u.qam.symbol_rate <= 1188750)
5290 ratesel = 3;
5291 else if (state->param.u.qam.symbol_rate <= 2377500)
5292 ratesel = 2;
5293 else if (state->param.u.qam.symbol_rate <= 4755000)
5294 ratesel = 1;
5295 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5296 if (status < 0)
5297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005299 /*
5300 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5301 */
5302 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5303 if (symbFreq == 0) {
5304 /* Divide by zero */
5305 status = -EINVAL;
5306 goto error;
5307 }
5308 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5309 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5310 (1 << 23);
5311 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5312 if (status < 0)
5313 goto error;
5314 state->m_iqmRcRate = iqmRcRate;
5315 /*
5316 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5317 */
5318 symbFreq = state->param.u.qam.symbol_rate;
5319 if (adcFrequency == 0) {
5320 /* Divide by zero */
5321 status = -EINVAL;
5322 goto error;
5323 }
5324 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5325 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5326 16);
5327 if (lcSymbRate > 511)
5328 lcSymbRate = 511;
5329 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005331error:
5332 if (status < 0)
5333 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005334 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005335}
5336
5337/*============================================================================*/
5338
5339/**
5340* \brief Get QAM lock status.
5341* \param demod: instance of demod.
5342* \param channel: pointer to channel data.
5343* \return DRXStatus_t.
5344*/
5345
5346static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5347{
5348 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005349 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005350
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005351 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005352 *pLockStatus = NOT_LOCKED;
5353 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 SCU_RAM_COMMAND_STANDARD_QAM |
5355 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5356 Result);
5357 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005358 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359
5360 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005361 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363 /* 0x4000 DEMOD LOCKED */
5364 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005365 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005366 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5367 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005368 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005369 /* 0xC000 NEVER LOCKED */
5370 /* (system will never be able to lock to the signal) */
5371 /* TODO: check this, intermediate & standard specific lock states are not
5372 taken into account here */
5373 *pLockStatus = NEVER_LOCK;
5374 }
5375 return status;
5376}
5377
5378#define QAM_MIRROR__M 0x03
5379#define QAM_MIRROR_NORMAL 0x00
5380#define QAM_MIRRORED 0x01
5381#define QAM_MIRROR_AUTO_ON 0x02
5382#define QAM_LOCKRANGE__M 0x10
5383#define QAM_LOCKRANGE_NORMAL 0x10
5384
Oliver Endrissebc7de22011-07-03 13:49:44 -03005385static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5386 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005387{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005388 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389 u8 parameterLen;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005390 u16 setEnvParameters[5];
5391 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5392 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005393
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005394 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005395 /*
5396 STEP 1: reset demodulator
5397 resets FEC DI and FEC RS
5398 resets QAM block
5399 resets SCU variables
5400 */
5401 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005402 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005403 goto error;
5404 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5405 if (status < 0)
5406 goto error;
5407 status = QAMResetQAM(state);
5408 if (status < 0)
5409 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005410
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005411 /*
5412 STEP 2: configure demodulator
5413 -set env
5414 -set params; resets IQM,QAM,FEC HW; initializes some SCU variables
5415 */
5416 status = QAMSetSymbolrate(state);
5417 if (status < 0)
5418 goto error;
5419
5420 /* Env parameters */
5421 setEnvParameters[2] = QAM_TOP_ANNEX_A; /* Annex */
5422 if (state->m_OperationMode == OM_QAM_ITU_C)
5423 setEnvParameters[2] = QAM_TOP_ANNEX_C; /* Annex */
5424 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5425 /* check for LOCKRANGE Extented */
5426 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5427 parameterLen = 4;
5428
5429 /* Set params */
5430 switch (state->param.u.qam.modulation) {
5431 case QAM_256:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5433 break;
5434 case QAM_AUTO:
5435 case QAM_64:
5436 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5437 break;
5438 case QAM_16:
5439 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5440 break;
5441 case QAM_32:
5442 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5443 break;
5444 case QAM_128:
5445 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5446 break;
5447 default:
5448 status = -EINVAL;
5449 break;
5450 }
5451 if (status < 0)
5452 goto error;
5453 setParamParameters[0] = state->m_Constellation; /* constellation */
5454 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5455
5456 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5457 if (status < 0)
5458 goto error;
5459
5460
5461 /* STEP 3: enable the system in a mode where the ADC provides valid signal
5462 setup constellation independent registers */
5463#if 0
5464 status = SetFrequency(channel, tunerFreqOffset));
5465 if (status < 0)
5466 goto error;
5467#endif
5468 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5469 if (status < 0)
5470 goto error;
5471
5472 /* Setup BER measurement */
5473 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5474 if (status < 0)
5475 goto error;
5476
5477 /* Reset default values */
5478 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5479 if (status < 0)
5480 goto error;
5481 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5482 if (status < 0)
5483 goto error;
5484
5485 /* Reset default LC values */
5486 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5487 if (status < 0)
5488 goto error;
5489 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5490 if (status < 0)
5491 goto error;
5492 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5493 if (status < 0)
5494 goto error;
5495 status = write16(state, QAM_LC_MODE__A, 7);
5496 if (status < 0)
5497 goto error;
5498
5499 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5500 if (status < 0)
5501 goto error;
5502 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5503 if (status < 0)
5504 goto error;
5505 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5506 if (status < 0)
5507 goto error;
5508 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5509 if (status < 0)
5510 goto error;
5511 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5512 if (status < 0)
5513 goto error;
5514 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5542 if (status < 0)
5543 goto error;
5544
5545 /* Mirroring, QAM-block starting point not inverted */
5546 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5547 if (status < 0)
5548 goto error;
5549
5550 /* Halt SCU to enable safe non-atomic accesses */
5551 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5552 if (status < 0)
5553 goto error;
5554
5555 /* STEP 4: constellation specific setup */
5556 switch (state->param.u.qam.modulation) {
5557 case QAM_16:
5558 status = SetQAM16(state);
5559 break;
5560 case QAM_32:
5561 status = SetQAM32(state);
5562 break;
5563 case QAM_AUTO:
5564 case QAM_64:
5565 status = SetQAM64(state);
5566 break;
5567 case QAM_128:
5568 status = SetQAM128(state);
5569 break;
5570 case QAM_256:
5571 status = SetQAM256(state);
5572 break;
5573 default:
5574 status = -EINVAL;
5575 break;
5576 }
5577 if (status < 0)
5578 goto error;
5579
5580 /* Activate SCU to enable SCU commands */
5581 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5582 if (status < 0)
5583 goto error;
5584
5585 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5586 /* extAttr->currentChannel.constellation = channel->constellation; */
5587 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5588 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5589 if (status < 0)
5590 goto error;
5591
5592 /* Start processes */
5593 status = MPEGTSStart(state);
5594 if (status < 0)
5595 goto error;
5596 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5597 if (status < 0)
5598 goto error;
5599 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5600 if (status < 0)
5601 goto error;
5602 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5603 if (status < 0)
5604 goto error;
5605
5606 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5607 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5608 if (status < 0)
5609 goto error;
5610
5611 /* update global DRXK data container */
5612/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5613
5614error:
5615 if (status < 0)
5616 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005617 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005618}
5619
Oliver Endrissebc7de22011-07-03 13:49:44 -03005620static int SetQAMStandard(struct drxk_state *state,
5621 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005622{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005623 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005624#ifdef DRXK_QAM_TAPS
5625#define DRXK_QAMA_TAPS_SELECT
5626#include "drxk_filters.h"
5627#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005628#endif
5629
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005630 /* added antenna switch */
5631 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005633 /* Ensure correct power-up mode */
5634 status = PowerUpQAM(state);
5635 if (status < 0)
5636 goto error;
5637 /* Reset QAM block */
5638 status = QAMResetQAM(state);
5639 if (status < 0)
5640 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005641
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005642 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005643
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005644 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5645 if (status < 0)
5646 goto error;
5647 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5648 if (status < 0)
5649 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005651 /* Upload IQM Channel Filter settings by
5652 boot loader from ROM table */
5653 switch (oMode) {
5654 case OM_QAM_ITU_A:
5655 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5656 break;
5657 case OM_QAM_ITU_C:
5658 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 -03005659 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005660 goto error;
5661 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5662 break;
5663 default:
5664 status = -EINVAL;
5665 }
5666 if (status < 0)
5667 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005668
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005669 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5670 if (status < 0)
5671 goto error;
5672 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5673 if (status < 0)
5674 goto error;
5675 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5676 if (status < 0)
5677 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005678
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005679 status = write16(state, IQM_RC_STRETCH__A, 21);
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, IQM_AF_CLP_TH__A, 448);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5692 if (status < 0)
5693 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005695 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5702 if (status < 0)
5703 goto error;
5704 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5705 if (status < 0)
5706 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005708 /* IQM Impulse Noise Processing Unit */
5709 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_CF_DATATH__A, 1000);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_CF_DET_LCT__A, 0);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_CF_WND_LEN__A, 1);
5722 if (status < 0)
5723 goto error;
5724 status = write16(state, IQM_CF_PKDTH__A, 1);
5725 if (status < 0)
5726 goto error;
5727 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5728 if (status < 0)
5729 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005730
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005731 /* turn on IQMAF. Must be done before setAgc**() */
5732 status = SetIqmAf(state, true);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5736 if (status < 0)
5737 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005738
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005739 /* IQM will not be reset from here, sync ADC and update/init AGC */
5740 status = ADCSynchronization(state);
5741 if (status < 0)
5742 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005744 /* Set the FSM step period */
5745 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5746 if (status < 0)
5747 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005748
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005749 /* Halt SCU to enable safe non-atomic accesses */
5750 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5751 if (status < 0)
5752 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005753
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005754 /* No more resets of the IQM, current standard correctly set =>
5755 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005757 status = InitAGC(state, true);
5758 if (status < 0)
5759 goto error;
5760 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5761 if (status < 0)
5762 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005764 /* Configure AGC's */
5765 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5766 if (status < 0)
5767 goto error;
5768 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5769 if (status < 0)
5770 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005771
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005772 /* Activate SCU to enable SCU commands */
5773 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5774error:
5775 if (status < 0)
5776 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005777 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005778}
5779
5780static int WriteGPIO(struct drxk_state *state)
5781{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005782 int status;
5783 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005784
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005785 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005786 /* stop lock indicator process */
5787 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5788 if (status < 0)
5789 goto error;
5790
5791 /* Write magic word to enable pdr reg write */
5792 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5793 if (status < 0)
5794 goto error;
5795
5796 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005797 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5798 /* write to io pad configuration register - output mode */
5799 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5800 if (status < 0)
5801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005802
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005803 /* use corresponding bit in io data output registar */
5804 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5805 if (status < 0)
5806 goto error;
5807 if ((state->m_GPIO & 0x0001) == 0)
5808 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5809 else
5810 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5811 /* write back to io data output register */
5812 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5813 if (status < 0)
5814 goto error;
5815 }
5816 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5817 /* write to io pad configuration register - output mode */
5818 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5819 if (status < 0)
5820 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005821
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005822 /* use corresponding bit in io data output registar */
5823 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5824 if (status < 0)
5825 goto error;
5826 if ((state->m_GPIO & 0x0002) == 0)
5827 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5828 else
5829 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5830 /* write back to io data output register */
5831 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5832 if (status < 0)
5833 goto error;
5834 }
5835 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5836 /* write to io pad configuration register - output mode */
5837 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5838 if (status < 0)
5839 goto error;
5840
5841 /* use corresponding bit in io data output registar */
5842 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5843 if (status < 0)
5844 goto error;
5845 if ((state->m_GPIO & 0x0004) == 0)
5846 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5847 else
5848 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5849 /* write back to io data output register */
5850 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5851 if (status < 0)
5852 goto error;
5853 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005854 }
5855 /* Write magic word to disable pdr reg write */
5856 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5857error:
5858 if (status < 0)
5859 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005860 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005861}
5862
5863static int SwitchAntennaToQAM(struct drxk_state *state)
5864{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005865 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005866 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005867
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005868 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005869
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005870 if (!state->antenna_gpio)
5871 return 0;
5872
5873 gpio_state = state->m_GPIO & state->antenna_gpio;
5874
5875 if (state->antenna_dvbt ^ gpio_state) {
5876 /* Antenna is on DVB-T mode. Switch */
5877 if (state->antenna_dvbt)
5878 state->m_GPIO &= ~state->antenna_gpio;
5879 else
5880 state->m_GPIO |= state->antenna_gpio;
5881 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005882 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005883 if (status < 0)
5884 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005885 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886}
5887
5888static int SwitchAntennaToDVBT(struct drxk_state *state)
5889{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005890 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005891 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005892
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005893 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005894
5895 if (!state->antenna_gpio)
5896 return 0;
5897
5898 gpio_state = state->m_GPIO & state->antenna_gpio;
5899
5900 if (!(state->antenna_dvbt ^ gpio_state)) {
5901 /* Antenna is on DVB-C mode. Switch */
5902 if (state->antenna_dvbt)
5903 state->m_GPIO |= state->antenna_gpio;
5904 else
5905 state->m_GPIO &= ~state->antenna_gpio;
5906 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005907 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005908 if (status < 0)
5909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005910 return status;
5911}
5912
5913
5914static int PowerDownDevice(struct drxk_state *state)
5915{
5916 /* Power down to requested mode */
5917 /* Backup some register settings */
5918 /* Set pins with possible pull-ups connected to them in input mode */
5919 /* Analog power down */
5920 /* ADC power down */
5921 /* Power down device */
5922 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005923
5924 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005925 if (state->m_bPDownOpenBridge) {
5926 /* Open I2C bridge before power down of DRXK */
5927 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005928 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005929 goto error;
5930 }
5931 /* driver 0.9.0 */
5932 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005933 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005934 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005936 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5937 if (status < 0)
5938 goto error;
5939 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5940 if (status < 0)
5941 goto error;
5942 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5943 status = HI_CfgCommand(state);
5944error:
5945 if (status < 0)
5946 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5947
5948 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005949}
5950
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005951static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005952{
5953 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005954 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005956 dprintk(1, "\n");
5957
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005958 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5959 if (err < 0) {
5960 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005961 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005963 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964 return err;
5965 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005966 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005967 release_firmware(fw);
5968 return err;
5969}
5970
5971static int init_drxk(struct drxk_state *state)
5972{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005973 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005974 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 u16 driverVersion;
5976
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005977 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005979 status = PowerUpDevice(state);
5980 if (status < 0)
5981 goto error;
5982 status = DRXX_Open(state);
5983 if (status < 0)
5984 goto error;
5985 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5986 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);
5987 if (status < 0)
5988 goto error;
5989 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5990 if (status < 0)
5991 goto error;
5992 /* TODO is this needed, if yes how much delay in worst case scenario */
5993 msleep(1);
5994 state->m_DRXK_A3_PATCH_CODE = true;
5995 status = GetDeviceCapabilities(state);
5996 if (status < 0)
5997 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005998
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005999 /* Bridge delay, uses oscilator clock */
6000 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6001 /* SDA brdige delay */
6002 state->m_HICfgBridgeDelay =
6003 (u16) ((state->m_oscClockFreq / 1000) *
6004 HI_I2C_BRIDGE_DELAY) / 1000;
6005 /* Clipping */
6006 if (state->m_HICfgBridgeDelay >
6007 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006008 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006009 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6010 }
6011 /* SCL bridge delay, same as SDA for now */
6012 state->m_HICfgBridgeDelay +=
6013 state->m_HICfgBridgeDelay <<
6014 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 status = InitHI(state);
6017 if (status < 0)
6018 goto error;
6019 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006020#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006021 if (!(state->m_DRXK_A1_ROM_CODE)
6022 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006024 {
6025 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6026 if (status < 0)
6027 goto error;
6028 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 /* disable MPEG port */
6031 status = MPEGTSDisable(state);
6032 if (status < 0)
6033 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 /* Stop AUD and SCU */
6036 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6037 if (status < 0)
6038 goto error;
6039 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6040 if (status < 0)
6041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 /* enable token-ring bus through OFDM block for possible ucode upload */
6044 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6045 if (status < 0)
6046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006048 /* include boot loader section */
6049 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6050 if (status < 0)
6051 goto error;
6052 status = BLChainCmd(state, 0, 6, 100);
6053 if (status < 0)
6054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006056 if (!state->microcode_name)
6057 load_microcode(state, "drxk_a3.mc");
6058 else
6059 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006061 /* disable token-ring bus through OFDM block for possible ucode upload */
6062 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6063 if (status < 0)
6064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006066 /* Run SCU for a little while to initialize microcode version numbers */
6067 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6068 if (status < 0)
6069 goto error;
6070 status = DRXX_Open(state);
6071 if (status < 0)
6072 goto error;
6073 /* added for test */
6074 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 powerMode = DRXK_POWER_DOWN_OFDM;
6077 status = CtrlPowerMode(state, &powerMode);
6078 if (status < 0)
6079 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006081 /* Stamp driver version number in SCU data RAM in BCD code
6082 Done to enable field application engineers to retreive drxdriver version
6083 via I2C from SCU RAM.
6084 Not using SCU command interface for SCU register access since no
6085 microcode may be present.
6086 */
6087 driverVersion =
6088 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6089 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6090 ((DRXK_VERSION_MAJOR % 10) << 4) +
6091 (DRXK_VERSION_MINOR % 10);
6092 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6093 if (status < 0)
6094 goto error;
6095 driverVersion =
6096 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6097 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6098 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6099 (DRXK_VERSION_PATCH % 10);
6100 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6101 if (status < 0)
6102 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006103
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006104 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6105 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6106 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006108 /* Dirty fix of default values for ROM/PATCH microcode
6109 Dirty because this fix makes it impossible to setup suitable values
6110 before calling DRX_Open. This solution requires changes to RF AGC speed
6111 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006113 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006115 /* Reset driver debug flags to 0 */
6116 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6117 if (status < 0)
6118 goto error;
6119 /* driver 0.9.0 */
6120 /* Setup FEC OC:
6121 NOTE: No more full FEC resets allowed afterwards!! */
6122 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6123 if (status < 0)
6124 goto error;
6125 /* MPEGTS functions are still the same */
6126 status = MPEGTSDtoInit(state);
6127 if (status < 0)
6128 goto error;
6129 status = MPEGTSStop(state);
6130 if (status < 0)
6131 goto error;
6132 status = MPEGTSConfigurePolarity(state);
6133 if (status < 0)
6134 goto error;
6135 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6136 if (status < 0)
6137 goto error;
6138 /* added: configure GPIO */
6139 status = WriteGPIO(state);
6140 if (status < 0)
6141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006143 state->m_DrxkState = DRXK_STOPPED;
6144
6145 if (state->m_bPowerDown) {
6146 status = PowerDownDevice(state);
6147 if (status < 0)
6148 goto error;
6149 state->m_DrxkState = DRXK_POWERED_DOWN;
6150 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006151 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006152 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006153error:
6154 if (status < 0)
6155 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006156
6157 return 0;
6158}
6159
Oliver Endrissebc7de22011-07-03 13:49:44 -03006160static void drxk_c_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006161{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006162 struct drxk_state *state = fe->demodulator_priv;
6163
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006164 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006165 kfree(state);
6166}
6167
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168static int drxk_c_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006170 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006171
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006172 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006173 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174 return -EBUSY;
6175 SetOperationMode(state, OM_QAM_ITU_A);
6176 return 0;
6177}
6178
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179static int drxk_c_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006183 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006184 ShutDown(state);
6185 mutex_unlock(&state->ctlock);
6186 return 0;
6187}
6188
Oliver Endrissebc7de22011-07-03 13:49:44 -03006189static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190{
6191 struct drxk_state *state = fe->demodulator_priv;
6192
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006193 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006194 return ConfigureI2CBridge(state, enable ? true : false);
6195}
6196
Oliver Endrissebc7de22011-07-03 13:49:44 -03006197static int drxk_set_parameters(struct dvb_frontend *fe,
6198 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199{
6200 struct drxk_state *state = fe->demodulator_priv;
6201 u32 IF;
6202
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006203 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204 if (fe->ops.i2c_gate_ctrl)
6205 fe->ops.i2c_gate_ctrl(fe, 1);
6206 if (fe->ops.tuner_ops.set_params)
6207 fe->ops.tuner_ops.set_params(fe, p);
6208 if (fe->ops.i2c_gate_ctrl)
6209 fe->ops.i2c_gate_ctrl(fe, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006210 state->param = *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006211 fe->ops.tuner_ops.get_frequency(fe, &IF);
6212 Start(state, 0, IF);
6213
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006214 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006215
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 return 0;
6217}
6218
Oliver Endrissebc7de22011-07-03 13:49:44 -03006219static int drxk_c_get_frontend(struct dvb_frontend *fe,
6220 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006221{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006222 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006223 return 0;
6224}
6225
6226static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6227{
6228 struct drxk_state *state = fe->demodulator_priv;
6229 u32 stat;
6230
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006231 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006232 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006233 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006234 if (stat == MPEG_LOCK)
6235 *status |= 0x1f;
6236 if (stat == FEC_LOCK)
6237 *status |= 0x0f;
6238 if (stat == DEMOD_LOCK)
6239 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006240 return 0;
6241}
6242
6243static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6244{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006245 dprintk(1, "\n");
6246
Oliver Endrissebc7de22011-07-03 13:49:44 -03006247 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248 return 0;
6249}
6250
Oliver Endrissebc7de22011-07-03 13:49:44 -03006251static int drxk_read_signal_strength(struct dvb_frontend *fe,
6252 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253{
6254 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006255 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006256
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006257 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006258 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260 return 0;
6261}
6262
6263static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6264{
6265 struct drxk_state *state = fe->demodulator_priv;
6266 s32 snr2;
6267
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006268 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006270 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006271 return 0;
6272}
6273
6274static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6275{
6276 struct drxk_state *state = fe->demodulator_priv;
6277 u16 err;
6278
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006279 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280 DVBTQAMGetAccPktErr(state, &err);
6281 *ucblocks = (u32) err;
6282 return 0;
6283}
6284
Oliver Endrissebc7de22011-07-03 13:49:44 -03006285static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6286 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006287{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006288 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006289 sets->min_delay_ms = 3000;
6290 sets->max_drift = 0;
6291 sets->step_size = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006292 return 0;
6293}
6294
Oliver Endrissebc7de22011-07-03 13:49:44 -03006295static void drxk_t_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006296{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006297#if 0
6298 struct drxk_state *state = fe->demodulator_priv;
6299
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006300 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006301 kfree(state);
6302#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006303}
6304
Oliver Endrissebc7de22011-07-03 13:49:44 -03006305static int drxk_t_init(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006307 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006308
6309 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006310 if (mutex_trylock(&state->ctlock) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 return -EBUSY;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006312 SetOperationMode(state, OM_DVBT);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006313 return 0;
6314}
6315
Oliver Endrissebc7de22011-07-03 13:49:44 -03006316static int drxk_t_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006317{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006318 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006319
6320 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006321 mutex_unlock(&state->ctlock);
6322 return 0;
6323}
6324
Oliver Endrissebc7de22011-07-03 13:49:44 -03006325static int drxk_t_get_frontend(struct dvb_frontend *fe,
6326 struct dvb_frontend_parameters *p)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006327{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006328 dprintk(1, "\n");
6329
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006330 return 0;
6331}
6332
6333static struct dvb_frontend_ops drxk_c_ops = {
6334 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006335 .name = "DRXK DVB-C",
6336 .type = FE_QAM,
6337 .frequency_stepsize = 62500,
6338 .frequency_min = 47000000,
6339 .frequency_max = 862000000,
6340 .symbol_rate_min = 870000,
6341 .symbol_rate_max = 11700000,
6342 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6343 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006344 .release = drxk_c_release,
6345 .init = drxk_c_init,
6346 .sleep = drxk_c_sleep,
6347 .i2c_gate_ctrl = drxk_gate_ctrl,
6348
6349 .set_frontend = drxk_set_parameters,
6350 .get_frontend = drxk_c_get_frontend,
6351 .get_tune_settings = drxk_c_get_tune_settings,
6352
6353 .read_status = drxk_read_status,
6354 .read_ber = drxk_read_ber,
6355 .read_signal_strength = drxk_read_signal_strength,
6356 .read_snr = drxk_read_snr,
6357 .read_ucblocks = drxk_read_ucblocks,
6358};
6359
6360static struct dvb_frontend_ops drxk_t_ops = {
6361 .info = {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006362 .name = "DRXK DVB-T",
6363 .type = FE_OFDM,
6364 .frequency_min = 47125000,
6365 .frequency_max = 865000000,
6366 .frequency_stepsize = 166667,
6367 .frequency_tolerance = 0,
6368 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6369 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6370 FE_CAN_FEC_AUTO |
6371 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6372 FE_CAN_QAM_AUTO |
6373 FE_CAN_TRANSMISSION_MODE_AUTO |
6374 FE_CAN_GUARD_INTERVAL_AUTO |
6375 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376 .release = drxk_t_release,
6377 .init = drxk_t_init,
6378 .sleep = drxk_t_sleep,
6379 .i2c_gate_ctrl = drxk_gate_ctrl,
6380
6381 .set_frontend = drxk_set_parameters,
6382 .get_frontend = drxk_t_get_frontend,
6383
6384 .read_status = drxk_read_status,
6385 .read_ber = drxk_read_ber,
6386 .read_signal_strength = drxk_read_signal_strength,
6387 .read_snr = drxk_read_snr,
6388 .read_ucblocks = drxk_read_ucblocks,
6389};
6390
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006391struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6392 struct i2c_adapter *i2c,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006393 struct dvb_frontend **fe_t)
6394{
6395 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006396 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006397
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006398 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006399 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006400 if (!state)
6401 return NULL;
6402
Oliver Endrissebc7de22011-07-03 13:49:44 -03006403 state->i2c = i2c;
6404 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006405 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006406 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006407 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006408 state->antenna_gpio = config->antenna_gpio;
6409 state->antenna_dvbt = config->antenna_dvbt;
6410
6411 /* NOTE: as more UIO bits will be used, add them to the mask */
6412 state->UIO_mask = config->antenna_gpio;
6413
6414 /* Default gpio to DVB-C */
6415 if (!state->antenna_dvbt && state->antenna_gpio)
6416 state->m_GPIO |= state->antenna_gpio;
6417 else
6418 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006419
6420 mutex_init(&state->mutex);
6421 mutex_init(&state->ctlock);
6422
Oliver Endrissebc7de22011-07-03 13:49:44 -03006423 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6424 sizeof(struct dvb_frontend_ops));
6425 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6426 sizeof(struct dvb_frontend_ops));
6427 state->c_frontend.demodulator_priv = state;
6428 state->t_frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006429
6430 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006431 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006432 goto error;
6433 *fe_t = &state->t_frontend;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006434
6435#ifdef CONFIG_MEDIA_ATTACH
6436 /*
6437 * HACK: As this function initializes both DVB-T and DVB-C fe symbols,
6438 * and calling it twice would create the state twice, leading into
6439 * memory leaks, the right way is to call it only once. However, dvb
6440 * release functions will call symbol_put twice. So, the solution is to
6441 * artificially increment the usage count, in order to allow the
6442 * driver to be released.
6443 */
6444 symbol_get(drxk_attach);
6445#endif
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006446 return &state->c_frontend;
6447
6448error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006449 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006450 kfree(state);
6451 return NULL;
6452}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006453EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006454
6455MODULE_DESCRIPTION("DRX-K driver");
6456MODULE_AUTHOR("Ralph Metzler");
6457MODULE_LICENSE("GPL");