blob: a414b1f2b6a5a0f2cd1c4dcfef210ea45189f912 [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>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030031#include <asm/div64.h>
32
33#include "dvb_frontend.h"
34#include "drxk.h"
35#include "drxk_hard.h"
36
37static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
38static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030039static int SetDVBTStandard(struct drxk_state *state,
40 enum OperationMode oMode);
41static int SetQAMStandard(struct drxk_state *state,
42 enum OperationMode oMode);
43static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030044 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030045static int SetDVBTStandard(struct drxk_state *state,
46 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030047static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030048static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
49 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030050static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
51static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int SwitchAntennaToQAM(struct drxk_state *state);
53static int SwitchAntennaToDVBT(struct drxk_state *state);
54
55static bool IsDVBT(struct drxk_state *state)
56{
57 return state->m_OperationMode == OM_DVBT;
58}
59
60static bool IsQAM(struct drxk_state *state)
61{
62 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030063 state->m_OperationMode == OM_QAM_ITU_B ||
64 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030065}
66
67bool IsA1WithPatchCode(struct drxk_state *state)
68{
69 return state->m_DRXK_A1_PATCH_CODE;
70}
71
72bool IsA1WithRomCode(struct drxk_state *state)
73{
74 return state->m_DRXK_A1_ROM_CODE;
75}
76
77#define NOA1ROM 0
78
Ralph Metzler43dd07f2011-07-03 13:42:18 -030079#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
80#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
81
82#define DEFAULT_MER_83 165
83#define DEFAULT_MER_93 250
84
85#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
86#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
87#endif
88
89#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
90#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
91#endif
92
Ralph Metzler43dd07f2011-07-03 13:42:18 -030093#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
94#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
95
96#ifndef DRXK_KI_RAGC_ATV
97#define DRXK_KI_RAGC_ATV 4
98#endif
99#ifndef DRXK_KI_IAGC_ATV
100#define DRXK_KI_IAGC_ATV 6
101#endif
102#ifndef DRXK_KI_DAGC_ATV
103#define DRXK_KI_DAGC_ATV 7
104#endif
105
106#ifndef DRXK_KI_RAGC_QAM
107#define DRXK_KI_RAGC_QAM 3
108#endif
109#ifndef DRXK_KI_IAGC_QAM
110#define DRXK_KI_IAGC_QAM 4
111#endif
112#ifndef DRXK_KI_DAGC_QAM
113#define DRXK_KI_DAGC_QAM 7
114#endif
115#ifndef DRXK_KI_RAGC_DVBT
116#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
117#endif
118#ifndef DRXK_KI_IAGC_DVBT
119#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
120#endif
121#ifndef DRXK_KI_DAGC_DVBT
122#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
123#endif
124
125#ifndef DRXK_AGC_DAC_OFFSET
126#define DRXK_AGC_DAC_OFFSET (0x800)
127#endif
128
129#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
130#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
131#endif
132
133#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
134#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
135#endif
136
137#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
138#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
139#endif
140
141#ifndef DRXK_QAM_SYMBOLRATE_MAX
142#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
143#endif
144
145#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
146#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
147#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
148#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
149#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
150#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
151#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
152#define DRXK_BL_ROM_OFFSET_UCODE 0
153
154#define DRXK_BLC_TIMEOUT 100
155
156#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
157#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
158
159#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
160
161#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
162#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
163#endif
164
165#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
166#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
167#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
168#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
169#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
170
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300171static unsigned int debug;
172module_param(debug, int, 0644);
173MODULE_PARM_DESC(debug, "enable debug messages");
174
175#define dprintk(level, fmt, arg...) do { \
176if (debug >= level) \
177 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
178} while (0)
179
180
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300181static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300182{
183 u64 tmp64;
184
Oliver Endrissebc7de22011-07-03 13:49:44 -0300185 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300186 do_div(tmp64, c);
187
188 return (u32) tmp64;
189}
190
191inline u32 Frac28a(u32 a, u32 c)
192{
193 int i = 0;
194 u32 Q1 = 0;
195 u32 R0 = 0;
196
Oliver Endrissebc7de22011-07-03 13:49:44 -0300197 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
198 Q1 = a / c; /* integer part, only the 4 least significant bits
199 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300200
201 /* division using radix 16, 7 nibbles in the result */
202 for (i = 0; i < 7; i++) {
203 Q1 = (Q1 << 4) | (R0 / c);
204 R0 = (R0 % c) << 4;
205 }
206 /* rounding */
207 if ((R0 >> 3) >= c)
208 Q1++;
209
210 return Q1;
211}
212
213static u32 Log10Times100(u32 x)
214{
215 static const u8 scale = 15;
216 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300217 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300218 u32 y = 0;
219 u32 d = 0;
220 u32 k = 0;
221 u32 r = 0;
222 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300223 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
224 0 <= n < ((1<<INDEXWIDTH)+1)
225 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300226
227 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 0, /* 0.000000 */
229 290941, /* 290941.300628 */
230 573196, /* 573196.476418 */
231 847269, /* 847269.179851 */
232 1113620, /* 1113620.489452 */
233 1372674, /* 1372673.576986 */
234 1624818, /* 1624817.752104 */
235 1870412, /* 1870411.981536 */
236 2109788, /* 2109787.962654 */
237 2343253, /* 2343252.817465 */
238 2571091, /* 2571091.461923 */
239 2793569, /* 2793568.696416 */
240 3010931, /* 3010931.055901 */
241 3223408, /* 3223408.452106 */
242 3431216, /* 3431215.635215 */
243 3634553, /* 3634553.498355 */
244 3833610, /* 3833610.244726 */
245 4028562, /* 4028562.434393 */
246 4219576, /* 4219575.925308 */
247 4406807, /* 4406806.721144 */
248 4590402, /* 4590401.736809 */
249 4770499, /* 4770499.491025 */
250 4947231, /* 4947230.734179 */
251 5120719, /* 5120719.018555 */
252 5291081, /* 5291081.217197 */
253 5458428, /* 5458427.996830 */
254 5622864, /* 5622864.249668 */
255 5784489, /* 5784489.488298 */
256 5943398, /* 5943398.207380 */
257 6099680, /* 6099680.215452 */
258 6253421, /* 6253420.939751 */
259 6404702, /* 6404701.706649 */
260 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300261 };
262
263
264 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300265 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266
267 /* Scale x (normalize) */
268 /* computing y in log(x/y) = log(x) - log(y) */
269 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
270 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300271 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300272 break;
273 x <<= 1;
274 }
275 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 for (k = scale; k < 31; k++) {
277 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300278 break;
279 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300280 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300281 }
282 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300283 Now x has binary point between bit[scale] and bit[scale-1]
284 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300285
286 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300287 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300288
289 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300290 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300291 /* get index */
292 i = (u8) (x >> (scale - indexWidth));
293 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300294 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300295 /* compute log, multiplication (d* (..)) must be within range ! */
296 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300297 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300298 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 r = (y >> 1);
301 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305}
306
307/****************************************************************************/
308/* I2C **********************************************************************/
309/****************************************************************************/
310
311static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
312{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300313 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
314 .buf = val, .len = 1}
315 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300316
317 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300318}
319
320static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
321{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300322 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300323 struct i2c_msg msg = {
324 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300325
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300326 dprintk(3, ":");
327 if (debug > 2) {
328 int i;
329 for (i = 0; i < len; i++)
330 printk(KERN_CONT " %02x", data[i]);
331 printk(KERN_CONT "\n");
332 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300333 status = i2c_transfer(adap, &msg, 1);
334 if (status >= 0 && status != 1)
335 status = -EIO;
336
337 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300338 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300339
340 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300341}
342
343static int i2c_read(struct i2c_adapter *adap,
344 u8 adr, u8 *msg, int len, u8 *answ, int alen)
345{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300346 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300347 struct i2c_msg msgs[2] = {
348 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300349 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300350 {.addr = adr, .flags = I2C_M_RD,
351 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300352 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300354 status = i2c_transfer(adap, msgs, 2);
355 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300356 if (debug > 2)
357 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300358 if (status >= 0)
359 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300360
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300361 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300362 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300364 if (debug > 2) {
365 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300366 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300367 for (i = 0; i < len; i++)
368 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300369 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300370 for (i = 0; i < alen; i++)
371 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300372 printk(KERN_CONT "\n");
373 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300374 return 0;
375}
376
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300377static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300378{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300379 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300380 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300381
382 if (state->single_master)
383 flags |= 0xC0;
384
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300385 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
386 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
387 mm1[1] = ((reg >> 16) & 0xFF);
388 mm1[2] = ((reg >> 24) & 0xFF) | flags;
389 mm1[3] = ((reg >> 7) & 0xFF);
390 len = 4;
391 } else {
392 mm1[0] = ((reg << 1) & 0xFF);
393 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
394 len = 2;
395 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300396 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300397 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
398 if (status < 0)
399 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300400 if (data)
401 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300402
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300403 return 0;
404}
405
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300406static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300407{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300408 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300409}
410
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300411static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300413 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300415
416 if (state->single_master)
417 flags |= 0xC0;
418
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300419 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
420 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
421 mm1[1] = ((reg >> 16) & 0xFF);
422 mm1[2] = ((reg >> 24) & 0xFF) | flags;
423 mm1[3] = ((reg >> 7) & 0xFF);
424 len = 4;
425 } else {
426 mm1[0] = ((reg << 1) & 0xFF);
427 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
428 len = 2;
429 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300430 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300431 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
432 if (status < 0)
433 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300434 if (data)
435 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300436 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300437
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300438 return 0;
439}
440
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300441static int read32(struct drxk_state *state, u32 reg, u32 *data)
442{
443 return read32_flags(state, reg, data, 0);
444}
445
446static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300447{
448 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300449
450 if (state->single_master)
451 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300452 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
453 mm[0] = (((reg << 1) & 0xFF) | 0x01);
454 mm[1] = ((reg >> 16) & 0xFF);
455 mm[2] = ((reg >> 24) & 0xFF) | flags;
456 mm[3] = ((reg >> 7) & 0xFF);
457 len = 4;
458 } else {
459 mm[0] = ((reg << 1) & 0xFF);
460 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
461 len = 2;
462 }
463 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300464 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300465
466 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300467 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300468}
469
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300470static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300471{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300472 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473}
474
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300475static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476{
477 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300478
479 if (state->single_master)
480 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
482 mm[0] = (((reg << 1) & 0xFF) | 0x01);
483 mm[1] = ((reg >> 16) & 0xFF);
484 mm[2] = ((reg >> 24) & 0xFF) | flags;
485 mm[3] = ((reg >> 7) & 0xFF);
486 len = 4;
487 } else {
488 mm[0] = ((reg << 1) & 0xFF);
489 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
490 len = 2;
491 }
492 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300493 mm[len + 1] = (data >> 8) & 0xff;
494 mm[len + 2] = (data >> 16) & 0xff;
495 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300496 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300497
498 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300499}
500
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300501static int write32(struct drxk_state *state, u32 reg, u32 data)
502{
503 return write32_flags(state, reg, data, 0);
504}
505
506static int write_block(struct drxk_state *state, u32 Address,
507 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300508{
509 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300510 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300511
512 if (state->single_master)
513 Flags |= 0xC0;
514
Oliver Endrissebc7de22011-07-03 13:49:44 -0300515 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300517 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300518 u8 *AdrBuf = &state->Chunk[0];
519 u32 AdrLength = 0;
520
Oliver Endrissebc7de22011-07-03 13:49:44 -0300521 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
522 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
523 AdrBuf[1] = ((Address >> 16) & 0xFF);
524 AdrBuf[2] = ((Address >> 24) & 0xFF);
525 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526 AdrBuf[2] |= Flags;
527 AdrLength = 4;
528 if (Chunk == state->m_ChunkSize)
529 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300530 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300531 AdrBuf[0] = ((Address << 1) & 0xFF);
532 AdrBuf[1] = (((Address >> 16) & 0x0F) |
533 ((Address >> 18) & 0xF0));
534 AdrLength = 2;
535 }
536 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300537 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
538 if (debug > 1) {
539 int i;
540 if (pBlock)
541 for (i = 0; i < Chunk; i++)
542 printk(KERN_CONT " %02x", pBlock[i]);
543 printk(KERN_CONT "\n");
544 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300545 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300546 &state->Chunk[0], Chunk + AdrLength);
547 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300548 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
549 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300550 break;
551 }
552 pBlock += Chunk;
553 Address += (Chunk >> 1);
554 BlkSize -= Chunk;
555 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300556 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300557}
558
559#ifndef DRXK_MAX_RETRIES_POWERUP
560#define DRXK_MAX_RETRIES_POWERUP 20
561#endif
562
563int PowerUpDevice(struct drxk_state *state)
564{
565 int status;
566 u8 data = 0;
567 u16 retryCount = 0;
568
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300569 dprintk(1, "\n");
570
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300571 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300572 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300573 do {
574 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300575 status = i2c_write(state->i2c, state->demod_address,
576 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300578 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300579 if (status < 0)
580 continue;
581 status = i2c_read1(state->i2c, state->demod_address,
582 &data);
583 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300584 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300585 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
586 goto error;
587 }
588
589 /* Make sure all clk domains are active */
590 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
591 if (status < 0)
592 goto error;
593 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
594 if (status < 0)
595 goto error;
596 /* Enable pll lock tests */
597 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
598 if (status < 0)
599 goto error;
600
601 state->m_currentPowerMode = DRX_POWER_UP;
602
603error:
604 if (status < 0)
605 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
606
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607 return status;
608}
609
610
611static int init_state(struct drxk_state *state)
612{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300613 /*
614 * FIXME: most (all?) of the values bellow should be moved into
615 * struct drxk_config, as they are probably board-specific
616 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300617 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
618 u32 ulVSBIfAgcOutputLevel = 0;
619 u32 ulVSBIfAgcMinLevel = 0;
620 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
621 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300622
Oliver Endrissebc7de22011-07-03 13:49:44 -0300623 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
624 u32 ulVSBRfAgcOutputLevel = 0;
625 u32 ulVSBRfAgcMinLevel = 0;
626 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
627 u32 ulVSBRfAgcSpeed = 3;
628 u32 ulVSBRfAgcTop = 9500;
629 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
Oliver Endrissebc7de22011-07-03 13:49:44 -0300631 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
632 u32 ulATVIfAgcOutputLevel = 0;
633 u32 ulATVIfAgcMinLevel = 0;
634 u32 ulATVIfAgcMaxLevel = 0;
635 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300636
Oliver Endrissebc7de22011-07-03 13:49:44 -0300637 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
638 u32 ulATVRfAgcOutputLevel = 0;
639 u32 ulATVRfAgcMinLevel = 0;
640 u32 ulATVRfAgcMaxLevel = 0;
641 u32 ulATVRfAgcTop = 9500;
642 u32 ulATVRfAgcCutOffCurrent = 4000;
643 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644
645 u32 ulQual83 = DEFAULT_MER_83;
646 u32 ulQual93 = DEFAULT_MER_93;
647
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
649 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
650
651 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
652 /* io_pad_cfg_mode output mode is drive always */
653 /* io_pad_cfg_drive is set to power 2 (23 mA) */
654 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300655 u32 ulInvertTSClock = 0;
656 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300657 u32 ulDVBTBitrate = 50000000;
658 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
659
660 u32 ulInsertRSByte = 0;
661
662 u32 ulRfMirror = 1;
663 u32 ulPowerDown = 0;
664
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300665 dprintk(1, "\n");
666
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300667 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300668 state->m_hasDVBT = false;
669 state->m_hasDVBC = false;
670 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300671 state->m_hasOOB = false;
672 state->m_hasAudio = false;
673
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300674 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200675 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300676
677 state->m_oscClockFreq = 0;
678 state->m_smartAntInverted = false;
679 state->m_bPDownOpenBridge = false;
680
681 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300682 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300683 /* Timing div, 250ns/Psys */
684 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
685 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
686 HI_I2C_DELAY) / 1000;
687 /* Clipping */
688 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
689 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
690 state->m_HICfgWakeUpKey = (state->demod_address << 1);
691 /* port/bridge/power down ctrl */
692 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
693
694 state->m_bPowerDown = (ulPowerDown != 0);
695
696 state->m_DRXK_A1_PATCH_CODE = false;
697 state->m_DRXK_A1_ROM_CODE = false;
698 state->m_DRXK_A2_ROM_CODE = false;
699 state->m_DRXK_A3_ROM_CODE = false;
700 state->m_DRXK_A2_PATCH_CODE = false;
701 state->m_DRXK_A3_PATCH_CODE = false;
702
703 /* Init AGC and PGA parameters */
704 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300705 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
706 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
707 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
708 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
709 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300710 state->m_vsbPgaCfg = 140;
711
712 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300713 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
714 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
715 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
716 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
717 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
718 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
719 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
720 state->m_vsbPreSawCfg.reference = 0x07;
721 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300722
723 state->m_Quality83percent = DEFAULT_MER_83;
724 state->m_Quality93percent = DEFAULT_MER_93;
725 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
726 state->m_Quality83percent = ulQual83;
727 state->m_Quality93percent = ulQual93;
728 }
729
730 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300731 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
732 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
733 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
734 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
735 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300736
737 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300738 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
739 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
740 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
741 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
742 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
743 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
744 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
745 state->m_atvPreSawCfg.reference = 0x04;
746 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300747
748
749 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300750 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
751 state->m_dvbtRfAgcCfg.outputLevel = 0;
752 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
753 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
754 state->m_dvbtRfAgcCfg.top = 0x2100;
755 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
756 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300757
758
759 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300760 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
761 state->m_dvbtIfAgcCfg.outputLevel = 0;
762 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
763 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
764 state->m_dvbtIfAgcCfg.top = 13424;
765 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
766 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300768 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
769 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
Oliver Endrissebc7de22011-07-03 13:49:44 -0300771 state->m_dvbtPreSawCfg.reference = 4;
772 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300773
774 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300775 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
776 state->m_qamRfAgcCfg.outputLevel = 0;
777 state->m_qamRfAgcCfg.minOutputLevel = 6023;
778 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
779 state->m_qamRfAgcCfg.top = 0x2380;
780 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
781 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
783 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
785 state->m_qamIfAgcCfg.outputLevel = 0;
786 state->m_qamIfAgcCfg.minOutputLevel = 0;
787 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
788 state->m_qamIfAgcCfg.top = 0x0511;
789 state->m_qamIfAgcCfg.cutOffCurrent = 0;
790 state->m_qamIfAgcCfg.speed = 3;
791 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300792 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
793
Oliver Endrissebc7de22011-07-03 13:49:44 -0300794 state->m_qamPgaCfg = 140;
795 state->m_qamPreSawCfg.reference = 4;
796 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300797
798 state->m_OperationMode = OM_NONE;
799 state->m_DrxkState = DRXK_UNINITIALIZED;
800
801 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300802 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
803 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300804 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
805 state->m_invertERR = false; /* If TRUE; invert ERR signal */
806 state->m_invertSTR = false; /* If TRUE; invert STR signals */
807 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
808 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300809
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810 /* If TRUE; static MPEG clockrate will be used;
811 otherwise clockrate will adapt to the bitrate of the TS */
812
813 state->m_DVBTBitrate = ulDVBTBitrate;
814 state->m_DVBCBitrate = ulDVBCBitrate;
815
816 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300817
818 /* Maximum bitrate in b/s in case static clockrate is selected */
819 state->m_mpegTsStaticBitrate = 19392658;
820 state->m_disableTEIhandling = false;
821
822 if (ulInsertRSByte)
823 state->m_insertRSByte = true;
824
825 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
826 if (ulMpegLockTimeOut < 10000)
827 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
828 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
829 if (ulDemodLockTimeOut < 10000)
830 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
831
Oliver Endrissebc7de22011-07-03 13:49:44 -0300832 /* QAM defaults */
833 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300834 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300835 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
836 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300837
838 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
839 state->m_agcFastClipCtrlDelay = 0;
840
841 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300842
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300843 state->m_bPowerDown = false;
844 state->m_currentPowerMode = DRX_POWER_DOWN;
845
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300846 state->m_rfmirror = (ulRfMirror == 0);
847 state->m_IfAgcPol = false;
848 return 0;
849}
850
851static int DRXX_Open(struct drxk_state *state)
852{
853 int status = 0;
854 u32 jtag = 0;
855 u16 bid = 0;
856 u16 key = 0;
857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300858 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300859 /* stop lock indicator process */
860 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
861 if (status < 0)
862 goto error;
863 /* Check device id */
864 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
865 if (status < 0)
866 goto error;
867 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
868 if (status < 0)
869 goto error;
870 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
871 if (status < 0)
872 goto error;
873 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
874 if (status < 0)
875 goto error;
876 status = write16(state, SIO_TOP_COMM_KEY__A, key);
877error:
878 if (status < 0)
879 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300880 return status;
881}
882
883static int GetDeviceCapabilities(struct drxk_state *state)
884{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300885 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300886 u32 sioTopJtagidLo = 0;
887 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300888 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300890 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300891
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300892 /* driver 0.9.0 */
893 /* stop lock indicator process */
894 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
895 if (status < 0)
896 goto error;
897 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
898 if (status < 0)
899 goto error;
900 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
901 if (status < 0)
902 goto error;
903 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
904 if (status < 0)
905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300907 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
908 case 0:
909 /* ignore (bypass ?) */
910 break;
911 case 1:
912 /* 27 MHz */
913 state->m_oscClockFreq = 27000;
914 break;
915 case 2:
916 /* 20.25 MHz */
917 state->m_oscClockFreq = 20250;
918 break;
919 case 3:
920 /* 4 MHz */
921 state->m_oscClockFreq = 20250;
922 break;
923 default:
924 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
925 return -EINVAL;
926 }
927 /*
928 Determine device capabilities
929 Based on pinning v14
930 */
931 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
932 if (status < 0)
933 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300934
935printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300937 /* driver 0.9.0 */
938 switch ((sioTopJtagidLo >> 29) & 0xF) {
939 case 0:
940 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300941 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300942 break;
943 case 2:
944 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300945 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300946 break;
947 case 3:
948 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300949 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300950 break;
951 default:
952 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
953 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300954 printk(KERN_ERR "drxk: Spin %d unknown\n",
955 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300956 goto error2;
957 }
958 switch ((sioTopJtagidLo >> 12) & 0xFF) {
959 case 0x13:
960 /* typeId = DRX3913K_TYPE_ID */
961 state->m_hasLNA = false;
962 state->m_hasOOB = false;
963 state->m_hasATV = false;
964 state->m_hasAudio = false;
965 state->m_hasDVBT = true;
966 state->m_hasDVBC = true;
967 state->m_hasSAWSW = true;
968 state->m_hasGPIO2 = false;
969 state->m_hasGPIO1 = false;
970 state->m_hasIRQN = false;
971 break;
972 case 0x15:
973 /* typeId = DRX3915K_TYPE_ID */
974 state->m_hasLNA = false;
975 state->m_hasOOB = false;
976 state->m_hasATV = true;
977 state->m_hasAudio = false;
978 state->m_hasDVBT = true;
979 state->m_hasDVBC = false;
980 state->m_hasSAWSW = true;
981 state->m_hasGPIO2 = true;
982 state->m_hasGPIO1 = true;
983 state->m_hasIRQN = false;
984 break;
985 case 0x16:
986 /* typeId = DRX3916K_TYPE_ID */
987 state->m_hasLNA = false;
988 state->m_hasOOB = false;
989 state->m_hasATV = true;
990 state->m_hasAudio = false;
991 state->m_hasDVBT = true;
992 state->m_hasDVBC = false;
993 state->m_hasSAWSW = true;
994 state->m_hasGPIO2 = true;
995 state->m_hasGPIO1 = true;
996 state->m_hasIRQN = false;
997 break;
998 case 0x18:
999 /* typeId = DRX3918K_TYPE_ID */
1000 state->m_hasLNA = false;
1001 state->m_hasOOB = false;
1002 state->m_hasATV = true;
1003 state->m_hasAudio = true;
1004 state->m_hasDVBT = true;
1005 state->m_hasDVBC = false;
1006 state->m_hasSAWSW = true;
1007 state->m_hasGPIO2 = true;
1008 state->m_hasGPIO1 = true;
1009 state->m_hasIRQN = false;
1010 break;
1011 case 0x21:
1012 /* typeId = DRX3921K_TYPE_ID */
1013 state->m_hasLNA = false;
1014 state->m_hasOOB = false;
1015 state->m_hasATV = true;
1016 state->m_hasAudio = true;
1017 state->m_hasDVBT = true;
1018 state->m_hasDVBC = true;
1019 state->m_hasSAWSW = true;
1020 state->m_hasGPIO2 = true;
1021 state->m_hasGPIO1 = true;
1022 state->m_hasIRQN = false;
1023 break;
1024 case 0x23:
1025 /* typeId = DRX3923K_TYPE_ID */
1026 state->m_hasLNA = false;
1027 state->m_hasOOB = false;
1028 state->m_hasATV = true;
1029 state->m_hasAudio = true;
1030 state->m_hasDVBT = true;
1031 state->m_hasDVBC = true;
1032 state->m_hasSAWSW = true;
1033 state->m_hasGPIO2 = true;
1034 state->m_hasGPIO1 = true;
1035 state->m_hasIRQN = false;
1036 break;
1037 case 0x25:
1038 /* typeId = DRX3925K_TYPE_ID */
1039 state->m_hasLNA = false;
1040 state->m_hasOOB = false;
1041 state->m_hasATV = true;
1042 state->m_hasAudio = true;
1043 state->m_hasDVBT = true;
1044 state->m_hasDVBC = true;
1045 state->m_hasSAWSW = true;
1046 state->m_hasGPIO2 = true;
1047 state->m_hasGPIO1 = true;
1048 state->m_hasIRQN = false;
1049 break;
1050 case 0x26:
1051 /* typeId = DRX3926K_TYPE_ID */
1052 state->m_hasLNA = false;
1053 state->m_hasOOB = false;
1054 state->m_hasATV = true;
1055 state->m_hasAudio = false;
1056 state->m_hasDVBT = true;
1057 state->m_hasDVBC = true;
1058 state->m_hasSAWSW = true;
1059 state->m_hasGPIO2 = true;
1060 state->m_hasGPIO1 = true;
1061 state->m_hasIRQN = false;
1062 break;
1063 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001064 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001065 ((sioTopJtagidLo >> 12) & 0xFF));
1066 status = -EINVAL;
1067 goto error2;
1068 }
1069
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001070 printk(KERN_INFO
1071 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1072 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1073 state->m_oscClockFreq / 1000,
1074 state->m_oscClockFreq % 1000);
1075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001076error:
1077 if (status < 0)
1078 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1079
1080error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001081 return status;
1082}
1083
1084static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1085{
1086 int status;
1087 bool powerdown_cmd;
1088
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001089 dprintk(1, "\n");
1090
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001091 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001092 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001094 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001095 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1096 msleep(1);
1097
1098 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001099 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1100 ((state->m_HICfgCtrl) &
1101 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1102 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103 if (powerdown_cmd == false) {
1104 /* Wait until command rdy */
1105 u32 retryCount = 0;
1106 u16 waitCmd;
1107
1108 do {
1109 msleep(1);
1110 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001111 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1112 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001113 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1114 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001115 if (status < 0)
1116 goto error;
1117 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001118 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001119error:
1120 if (status < 0)
1121 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1122
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001123 return status;
1124}
1125
1126static int HI_CfgCommand(struct drxk_state *state)
1127{
1128 int status;
1129
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001130 dprintk(1, "\n");
1131
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001132 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001134 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1135 if (status < 0)
1136 goto error;
1137 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1138 if (status < 0)
1139 goto error;
1140 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1141 if (status < 0)
1142 goto error;
1143 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1144 if (status < 0)
1145 goto error;
1146 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1150 if (status < 0)
1151 goto error;
1152 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1153 if (status < 0)
1154 goto error;
1155
1156 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1157error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001158 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001159 if (status < 0)
1160 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001161 return status;
1162}
1163
1164static int InitHI(struct drxk_state *state)
1165{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001166 dprintk(1, "\n");
1167
Oliver Endrissebc7de22011-07-03 13:49:44 -03001168 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169 state->m_HICfgTimeout = 0x96FF;
1170 /* port/bridge/power down ctrl */
1171 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001172
Oliver Endrissebc7de22011-07-03 13:49:44 -03001173 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001174}
1175
1176static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1177{
1178 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 u16 sioPdrMclkCfg = 0;
1180 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001181 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001182
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001183 dprintk(1, ": mpeg %s, %s mode\n",
1184 mpegEnable ? "enable" : "disable",
1185 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187 /* stop lock indicator process */
1188 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1189 if (status < 0)
1190 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001191
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001192 /* MPEG TS pad configuration */
1193 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1194 if (status < 0)
1195 goto error;
1196
1197 if (mpegEnable == false) {
1198 /* Set MPEG TS pads to inputmode */
1199 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1200 if (status < 0)
1201 goto error;
1202 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1203 if (status < 0)
1204 goto error;
1205 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1206 if (status < 0)
1207 goto error;
1208 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1209 if (status < 0)
1210 goto error;
1211 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 } else {
1236 /* Enable MPEG output */
1237 sioPdrMdxCfg =
1238 ((state->m_TSDataStrength <<
1239 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1240 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1241 SIO_PDR_MCLK_CFG_DRIVE__B) |
1242 0x0003);
1243
1244 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1245 if (status < 0)
1246 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001247
1248 if (state->enable_merr_cfg)
1249 err_cfg = sioPdrMdxCfg;
1250
1251 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001252 if (status < 0)
1253 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001254 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001255 if (status < 0)
1256 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001257
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001258 if (state->m_enableParallel == true) {
1259 /* paralel -> enable MD1 to MD7 */
1260 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001261 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001262 goto error;
1263 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001264 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001265 goto error;
1266 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001268 goto error;
1269 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001271 goto error;
1272 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001273 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001274 goto error;
1275 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1276 if (status < 0)
1277 goto error;
1278 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1279 if (status < 0)
1280 goto error;
1281 } else {
1282 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1283 SIO_PDR_MD0_CFG_DRIVE__B)
1284 | 0x0003);
1285 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001286 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001287 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001288 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001289 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001290 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001291 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001292 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001293 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001294 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001295 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001296 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001297 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001298 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001299 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001300 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001301 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001302 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001303 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001304 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001305 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001307 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001308 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001309 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001310 goto error;
1311 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001312 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 goto error;
1314 }
1315 /* Enable MB output over MPEG pads and ctl input */
1316 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1317 if (status < 0)
1318 goto error;
1319 /* Write nomagic word to enable pdr reg write */
1320 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1321error:
1322 if (status < 0)
1323 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001324 return status;
1325}
1326
1327static int MPEGTSDisable(struct drxk_state *state)
1328{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001329 dprintk(1, "\n");
1330
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331 return MPEGTSConfigurePins(state, false);
1332}
1333
1334static int BLChainCmd(struct drxk_state *state,
1335 u16 romOffset, u16 nrOfElements, u32 timeOut)
1336{
1337 u16 blStatus = 0;
1338 int status;
1339 unsigned long end;
1340
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001341 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001342 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001343 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1344 if (status < 0)
1345 goto error;
1346 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1347 if (status < 0)
1348 goto error;
1349 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1350 if (status < 0)
1351 goto error;
1352 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1353 if (status < 0)
1354 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001355
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001356 end = jiffies + msecs_to_jiffies(timeOut);
1357 do {
1358 msleep(1);
1359 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1360 if (status < 0)
1361 goto error;
1362 } while ((blStatus == 0x1) &&
1363 ((time_is_after_jiffies(end))));
1364
1365 if (blStatus == 0x1) {
1366 printk(KERN_ERR "drxk: SIO not ready\n");
1367 status = -EINVAL;
1368 goto error2;
1369 }
1370error:
1371 if (status < 0)
1372 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1373error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001374 mutex_unlock(&state->mutex);
1375 return status;
1376}
1377
1378
1379static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001380 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001381{
1382 const u8 *pSrc = pMCImage;
1383 u16 Flags;
1384 u16 Drain;
1385 u32 Address;
1386 u16 nBlocks;
1387 u16 BlockSize;
1388 u16 BlockCRC;
1389 u32 offset = 0;
1390 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001391 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001392
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001393 dprintk(1, "\n");
1394
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395 /* down the drain (we don care about MAGIC_WORD) */
1396 Drain = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001397 pSrc += sizeof(u16);
1398 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001400 pSrc += sizeof(u16);
1401 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402
1403 for (i = 0; i < nBlocks; i += 1) {
1404 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001405 (pSrc[2] << 8) | pSrc[3];
1406 pSrc += sizeof(u32);
1407 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001408
1409 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001410 pSrc += sizeof(u16);
1411 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001412
1413 Flags = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001414 pSrc += sizeof(u16);
1415 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001416
1417 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001418 pSrc += sizeof(u16);
1419 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001420
1421 if (offset + BlockSize > Length) {
1422 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1423 return -EINVAL;
1424 }
1425
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001426 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001427 if (status < 0) {
1428 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001429 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001430 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001431 pSrc += BlockSize;
1432 offset += BlockSize;
1433 }
1434 return status;
1435}
1436
1437static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1438{
1439 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001440 u16 data = 0;
1441 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001442 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1443 unsigned long end;
1444
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001445 dprintk(1, "\n");
1446
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001447 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001448 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1450 }
1451
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001452 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1453 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001454 /* tokenring already has correct status */
1455 return status;
1456 }
1457 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001458 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001459
Oliver Endrissebc7de22011-07-03 13:49:44 -03001460 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001461 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001462 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001463 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001464 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001465 msleep(1);
1466 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001467 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001468 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001469 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001470 }
1471 return status;
1472}
1473
1474static int MPEGTSStop(struct drxk_state *state)
1475{
1476 int status = 0;
1477 u16 fecOcSncMode = 0;
1478 u16 fecOcIprMode = 0;
1479
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001480 dprintk(1, "\n");
1481
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001482 /* Gracefull shutdown (byte boundaries) */
1483 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1484 if (status < 0)
1485 goto error;
1486 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1487 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1488 if (status < 0)
1489 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001490
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001491 /* Suppress MCLK during absence of data */
1492 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1493 if (status < 0)
1494 goto error;
1495 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1496 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1497
1498error:
1499 if (status < 0)
1500 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1501
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001502 return status;
1503}
1504
1505static int scu_command(struct drxk_state *state,
1506 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001507 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001508{
1509#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1510#error DRXK register mapping no longer compatible with this routine!
1511#endif
1512 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001513 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001515 u8 buffer[34];
1516 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001517 const char *p;
1518 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001519
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001520 dprintk(1, "\n");
1521
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001522 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001523 ((resultLen > 0) && (result == NULL))) {
1524 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1525 return status;
1526 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001527
1528 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001529
1530 /* assume that the command register is ready
1531 since it is checked afterwards */
1532 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1533 buffer[cnt++] = (parameter[ii] & 0xFF);
1534 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1535 }
1536 buffer[cnt++] = (cmd & 0xFF);
1537 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1538
1539 write_block(state, SCU_RAM_PARAM_0__A -
1540 (parameterLen - 1), cnt, buffer);
1541 /* Wait until SCU has processed command */
1542 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001543 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001544 msleep(1);
1545 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1546 if (status < 0)
1547 goto error;
1548 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1549 if (curCmd != DRX_SCU_READY) {
1550 printk(KERN_ERR "drxk: SCU not ready\n");
1551 status = -EIO;
1552 goto error2;
1553 }
1554 /* read results */
1555 if ((resultLen > 0) && (result != NULL)) {
1556 s16 err;
1557 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001559 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1560 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001561 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001562 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001564
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001565 /* Check if an error was reported by SCU */
1566 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001567 if (err >= 0)
1568 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001569
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001570 /* check for the known error codes */
1571 switch (err) {
1572 case SCU_RESULT_UNKCMD:
1573 p = "SCU_RESULT_UNKCMD";
1574 break;
1575 case SCU_RESULT_UNKSTD:
1576 p = "SCU_RESULT_UNKSTD";
1577 break;
1578 case SCU_RESULT_SIZE:
1579 p = "SCU_RESULT_SIZE";
1580 break;
1581 case SCU_RESULT_INVPAR:
1582 p = "SCU_RESULT_INVPAR";
1583 break;
1584 default: /* Other negative values are errors */
1585 sprintf(errname, "ERROR: %d\n", err);
1586 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001587 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001588 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1589 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1590 status = -EINVAL;
1591 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001592 }
1593
1594error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001595 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001596 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001597error2:
1598 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001599 return status;
1600}
1601
1602static int SetIqmAf(struct drxk_state *state, bool active)
1603{
1604 u16 data = 0;
1605 int status;
1606
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001607 dprintk(1, "\n");
1608
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001609 /* Configure IQM */
1610 status = read16(state, IQM_AF_STDBY__A, &data);
1611 if (status < 0)
1612 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001613
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001614 if (!active) {
1615 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1616 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1617 | IQM_AF_STDBY_STDBY_PD_STANDBY
1618 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1619 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1620 } else {
1621 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1622 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1624 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1625 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1626 );
1627 }
1628 status = write16(state, IQM_AF_STDBY__A, data);
1629
1630error:
1631 if (status < 0)
1632 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001633 return status;
1634}
1635
Oliver Endrissebc7de22011-07-03 13:49:44 -03001636static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001637{
1638 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001639 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001640
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001641 dprintk(1, "\n");
1642
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001643 /* Check arguments */
1644 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001645 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001646
1647 switch (*mode) {
1648 case DRX_POWER_UP:
1649 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1650 break;
1651 case DRXK_POWER_DOWN_OFDM:
1652 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1653 break;
1654 case DRXK_POWER_DOWN_CORE:
1655 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1656 break;
1657 case DRXK_POWER_DOWN_PLL:
1658 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1659 break;
1660 case DRX_POWER_DOWN:
1661 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1662 break;
1663 default:
1664 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001665 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001666 }
1667
1668 /* If already in requested power mode, do nothing */
1669 if (state->m_currentPowerMode == *mode)
1670 return 0;
1671
1672 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001673 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001674 status = PowerUpDevice(state);
1675 if (status < 0)
1676 goto error;
1677 status = DVBTEnableOFDMTokenRing(state, true);
1678 if (status < 0)
1679 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001680 }
1681
1682 if (*mode == DRX_POWER_UP) {
1683 /* Restore analog & pin configuartion */
1684 } else {
1685 /* Power down to requested mode */
1686 /* Backup some register settings */
1687 /* Set pins with possible pull-ups connected
1688 to them in input mode */
1689 /* Analog power down */
1690 /* ADC power down */
1691 /* Power down device */
1692 /* stop all comm_exec */
1693 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001694 switch (state->m_OperationMode) {
1695 case OM_DVBT:
1696 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001697 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001698 goto error;
1699 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001700 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001701 goto error;
1702 break;
1703 case OM_QAM_ITU_A:
1704 case OM_QAM_ITU_C:
1705 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001707 goto error;
1708 status = PowerDownQAM(state);
1709 if (status < 0)
1710 goto error;
1711 break;
1712 default:
1713 break;
1714 }
1715 status = DVBTEnableOFDMTokenRing(state, false);
1716 if (status < 0)
1717 goto error;
1718 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1719 if (status < 0)
1720 goto error;
1721 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1722 if (status < 0)
1723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001725 if (*mode != DRXK_POWER_DOWN_OFDM) {
1726 state->m_HICfgCtrl |=
1727 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1728 status = HI_CfgCommand(state);
1729 if (status < 0)
1730 goto error;
1731 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001732 }
1733 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001734
1735error:
1736 if (status < 0)
1737 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1738
Oliver Endrissebc7de22011-07-03 13:49:44 -03001739 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001740}
1741
1742static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1743{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001744 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001745 u16 cmdResult = 0;
1746 u16 data = 0;
1747 int status;
1748
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001749 dprintk(1, "\n");
1750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001751 status = read16(state, SCU_COMM_EXEC__A, &data);
1752 if (status < 0)
1753 goto error;
1754 if (data == SCU_COMM_EXEC_ACTIVE) {
1755 /* Send OFDM stop command */
1756 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 -03001757 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001758 goto error;
1759 /* Send OFDM reset command */
1760 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1761 if (status < 0)
1762 goto error;
1763 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001764
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001765 /* Reset datapath for OFDM, processors first */
1766 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1767 if (status < 0)
1768 goto error;
1769 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1770 if (status < 0)
1771 goto error;
1772 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1773 if (status < 0)
1774 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001776 /* powerdown AFE */
1777 status = SetIqmAf(state, false);
1778 if (status < 0)
1779 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001780
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001781 /* powerdown to OFDM mode */
1782 if (setPowerMode) {
1783 status = CtrlPowerMode(state, &powerMode);
1784 if (status < 0)
1785 goto error;
1786 }
1787error:
1788 if (status < 0)
1789 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001790 return status;
1791}
1792
Oliver Endrissebc7de22011-07-03 13:49:44 -03001793static int SetOperationMode(struct drxk_state *state,
1794 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001795{
1796 int status = 0;
1797
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001798 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001799 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001800 Stop and power down previous standard
1801 TODO investigate total power down instead of partial
1802 power down depending on "previous" standard.
1803 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001805 /* disable HW lock indicator */
1806 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1807 if (status < 0)
1808 goto error;
1809
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001810 /* Device is already at the required mode */
1811 if (state->m_OperationMode == oMode)
1812 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001813
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001814 switch (state->m_OperationMode) {
1815 /* OM_NONE was added for start up */
1816 case OM_NONE:
1817 break;
1818 case OM_DVBT:
1819 status = MPEGTSStop(state);
1820 if (status < 0)
1821 goto error;
1822 status = PowerDownDVBT(state, true);
1823 if (status < 0)
1824 goto error;
1825 state->m_OperationMode = OM_NONE;
1826 break;
1827 case OM_QAM_ITU_A: /* fallthrough */
1828 case OM_QAM_ITU_C:
1829 status = MPEGTSStop(state);
1830 if (status < 0)
1831 goto error;
1832 status = PowerDownQAM(state);
1833 if (status < 0)
1834 goto error;
1835 state->m_OperationMode = OM_NONE;
1836 break;
1837 case OM_QAM_ITU_B:
1838 default:
1839 status = -EINVAL;
1840 goto error;
1841 }
1842
1843 /*
1844 Power up new standard
1845 */
1846 switch (oMode) {
1847 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001848 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001849 state->m_OperationMode = oMode;
1850 status = SetDVBTStandard(state, oMode);
1851 if (status < 0)
1852 goto error;
1853 break;
1854 case OM_QAM_ITU_A: /* fallthrough */
1855 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001856 dprintk(1, ": DVB-C Annex %c\n",
1857 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001858 state->m_OperationMode = oMode;
1859 status = SetQAMStandard(state, oMode);
1860 if (status < 0)
1861 goto error;
1862 break;
1863 case OM_QAM_ITU_B:
1864 default:
1865 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001866 }
1867error:
1868 if (status < 0)
1869 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1870 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001871}
1872
1873static int Start(struct drxk_state *state, s32 offsetFreq,
1874 s32 IntermediateFrequency)
1875{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001876 int status = -EINVAL;
1877
1878 u16 IFreqkHz;
1879 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001880
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001881 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001882 if (state->m_DrxkState != DRXK_STOPPED &&
1883 state->m_DrxkState != DRXK_DTV_STARTED)
1884 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001886 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001887
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001888 if (IntermediateFrequency < 0) {
1889 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1890 IntermediateFrequency = -IntermediateFrequency;
1891 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001892
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001893 switch (state->m_OperationMode) {
1894 case OM_QAM_ITU_A:
1895 case OM_QAM_ITU_C:
1896 IFreqkHz = (IntermediateFrequency / 1000);
1897 status = SetQAM(state, IFreqkHz, OffsetkHz);
1898 if (status < 0)
1899 goto error;
1900 state->m_DrxkState = DRXK_DTV_STARTED;
1901 break;
1902 case OM_DVBT:
1903 IFreqkHz = (IntermediateFrequency / 1000);
1904 status = MPEGTSStop(state);
1905 if (status < 0)
1906 goto error;
1907 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1908 if (status < 0)
1909 goto error;
1910 status = DVBTStart(state);
1911 if (status < 0)
1912 goto error;
1913 state->m_DrxkState = DRXK_DTV_STARTED;
1914 break;
1915 default:
1916 break;
1917 }
1918error:
1919 if (status < 0)
1920 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001921 return status;
1922}
1923
1924static int ShutDown(struct drxk_state *state)
1925{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001926 dprintk(1, "\n");
1927
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001928 MPEGTSStop(state);
1929 return 0;
1930}
1931
Oliver Endrissebc7de22011-07-03 13:49:44 -03001932static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1933 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001935 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001936
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001937 dprintk(1, "\n");
1938
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001940 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001941
1942 *pLockStatus = NOT_LOCKED;
1943
1944 /* define the SCU command code */
1945 switch (state->m_OperationMode) {
1946 case OM_QAM_ITU_A:
1947 case OM_QAM_ITU_B:
1948 case OM_QAM_ITU_C:
1949 status = GetQAMLockStatus(state, pLockStatus);
1950 break;
1951 case OM_DVBT:
1952 status = GetDVBTLockStatus(state, pLockStatus);
1953 break;
1954 default:
1955 break;
1956 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001957error:
1958 if (status < 0)
1959 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001960 return status;
1961}
1962
1963static int MPEGTSStart(struct drxk_state *state)
1964{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001965 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001966
1967 u16 fecOcSncMode = 0;
1968
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001969 /* Allow OC to sync again */
1970 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1971 if (status < 0)
1972 goto error;
1973 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1974 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1975 if (status < 0)
1976 goto error;
1977 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1978error:
1979 if (status < 0)
1980 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001981 return status;
1982}
1983
1984static int MPEGTSDtoInit(struct drxk_state *state)
1985{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001986 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001987
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001988 dprintk(1, "\n");
1989
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001990 /* Rate integration settings */
1991 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1992 if (status < 0)
1993 goto error;
1994 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1995 if (status < 0)
1996 goto error;
1997 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1998 if (status < 0)
1999 goto error;
2000 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2001 if (status < 0)
2002 goto error;
2003 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2004 if (status < 0)
2005 goto error;
2006 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2007 if (status < 0)
2008 goto error;
2009 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2010 if (status < 0)
2011 goto error;
2012 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2013 if (status < 0)
2014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002016 /* Additional configuration */
2017 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2018 if (status < 0)
2019 goto error;
2020 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2021 if (status < 0)
2022 goto error;
2023 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2024error:
2025 if (status < 0)
2026 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2027
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002028 return status;
2029}
2030
Oliver Endrissebc7de22011-07-03 13:49:44 -03002031static int MPEGTSDtoSetup(struct drxk_state *state,
2032 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002033{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002034 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002035
Oliver Endrissebc7de22011-07-03 13:49:44 -03002036 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2037 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2038 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2039 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2040 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2041 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2042 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002043 u16 fecOcTmdMode = 0;
2044 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002045 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002046 bool staticCLK = false;
2047
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002048 dprintk(1, "\n");
2049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002050 /* Check insertion of the Reed-Solomon parity bytes */
2051 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2052 if (status < 0)
2053 goto error;
2054 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2055 if (status < 0)
2056 goto error;
2057 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2058 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2059 if (state->m_insertRSByte == true) {
2060 /* enable parity symbol forward */
2061 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2062 /* MVAL disable during parity bytes */
2063 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2064 /* TS burst length to 204 */
2065 fecOcDtoBurstLen = 204;
2066 }
2067
2068 /* Check serial or parrallel output */
2069 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2070 if (state->m_enableParallel == false) {
2071 /* MPEG data output is serial -> set ipr_mode[0] */
2072 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2073 }
2074
2075 switch (oMode) {
2076 case OM_DVBT:
2077 maxBitRate = state->m_DVBTBitrate;
2078 fecOcTmdMode = 3;
2079 fecOcRcnCtlRate = 0xC00000;
2080 staticCLK = state->m_DVBTStaticCLK;
2081 break;
2082 case OM_QAM_ITU_A: /* fallthrough */
2083 case OM_QAM_ITU_C:
2084 fecOcTmdMode = 0x0004;
2085 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2086 maxBitRate = state->m_DVBCBitrate;
2087 staticCLK = state->m_DVBCStaticCLK;
2088 break;
2089 default:
2090 status = -EINVAL;
2091 } /* switch (standard) */
2092 if (status < 0)
2093 goto error;
2094
2095 /* Configure DTO's */
2096 if (staticCLK) {
2097 u32 bitRate = 0;
2098
2099 /* Rational DTO for MCLK source (static MCLK rate),
2100 Dynamic DTO for optimal grouping
2101 (avoid intra-packet gaps),
2102 DTO offset enable to sync TS burst with MSTRT */
2103 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2104 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2105 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2106 FEC_OC_FCT_MODE_VIRT_ENA__M);
2107
2108 /* Check user defined bitrate */
2109 bitRate = maxBitRate;
2110 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2111 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002112 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002113 /* Rational DTO period:
2114 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002116 Result should be floored,
2117 to make sure >= requested bitrate
2118 */
2119 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2120 * 1000) / bitRate);
2121 if (fecOcDtoPeriod <= 2)
2122 fecOcDtoPeriod = 0;
2123 else
2124 fecOcDtoPeriod -= 2;
2125 fecOcTmdIntUpdRate = 8;
2126 } else {
2127 /* (commonAttr->staticCLK == false) => dynamic mode */
2128 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2129 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2130 fecOcTmdIntUpdRate = 5;
2131 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002132
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002133 /* Write appropriate registers with requested configuration */
2134 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2135 if (status < 0)
2136 goto error;
2137 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2138 if (status < 0)
2139 goto error;
2140 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2141 if (status < 0)
2142 goto error;
2143 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2144 if (status < 0)
2145 goto error;
2146 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2147 if (status < 0)
2148 goto error;
2149 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2150 if (status < 0)
2151 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002152
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002153 /* Rate integration settings */
2154 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2155 if (status < 0)
2156 goto error;
2157 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2158 if (status < 0)
2159 goto error;
2160 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2161error:
2162 if (status < 0)
2163 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002164 return status;
2165}
2166
2167static int MPEGTSConfigurePolarity(struct drxk_state *state)
2168{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002169 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170
2171 /* Data mask for the output data byte */
2172 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002173 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2174 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2175 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2176 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002177
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002178 dprintk(1, "\n");
2179
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002180 /* Control selective inversion of output bits */
2181 fecOcRegIprInvert &= (~(InvertDataMask));
2182 if (state->m_invertDATA == true)
2183 fecOcRegIprInvert |= InvertDataMask;
2184 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2185 if (state->m_invertERR == true)
2186 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2187 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2188 if (state->m_invertSTR == true)
2189 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2190 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2191 if (state->m_invertVAL == true)
2192 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2193 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2194 if (state->m_invertCLK == true)
2195 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002196
2197 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002198}
2199
2200#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2201
2202static int SetAgcRf(struct drxk_state *state,
2203 struct SCfgAgc *pAgcCfg, bool isDTV)
2204{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002205 int status = -EINVAL;
2206 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002207 struct SCfgAgc *pIfAgcSettings;
2208
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002209 dprintk(1, "\n");
2210
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002212 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002214 switch (pAgcCfg->ctrlMode) {
2215 case DRXK_AGC_CTRL_AUTO:
2216 /* Enable RF AGC DAC */
2217 status = read16(state, IQM_AF_STDBY__A, &data);
2218 if (status < 0)
2219 goto error;
2220 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2221 status = write16(state, IQM_AF_STDBY__A, data);
2222 if (status < 0)
2223 goto error;
2224 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2225 if (status < 0)
2226 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002227
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002228 /* Enable SCU RF AGC loop */
2229 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002230
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002231 /* Polarity */
2232 if (state->m_RfAgcPol)
2233 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2234 else
2235 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2236 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2237 if (status < 0)
2238 goto error;
2239
2240 /* Set speed (using complementary reduction value) */
2241 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2242 if (status < 0)
2243 goto error;
2244
2245 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2246 data |= (~(pAgcCfg->speed <<
2247 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2248 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2249
2250 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2251 if (status < 0)
2252 goto error;
2253
2254 if (IsDVBT(state))
2255 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2256 else if (IsQAM(state))
2257 pIfAgcSettings = &state->m_qamIfAgcCfg;
2258 else
2259 pIfAgcSettings = &state->m_atvIfAgcCfg;
2260 if (pIfAgcSettings == NULL) {
2261 status = -EINVAL;
2262 goto error;
2263 }
2264
2265 /* Set TOP, only if IF-AGC is in AUTO mode */
2266 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2267 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002268 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002270
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002271 /* Cut-Off current */
2272 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2273 if (status < 0)
2274 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002275
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002276 /* Max. output level */
2277 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2278 if (status < 0)
2279 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002281 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002282
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002283 case DRXK_AGC_CTRL_USER:
2284 /* Enable RF AGC DAC */
2285 status = read16(state, IQM_AF_STDBY__A, &data);
2286 if (status < 0)
2287 goto error;
2288 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2289 status = write16(state, IQM_AF_STDBY__A, data);
2290 if (status < 0)
2291 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002292
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002293 /* Disable SCU RF AGC loop */
2294 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2295 if (status < 0)
2296 goto error;
2297 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2298 if (state->m_RfAgcPol)
2299 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2300 else
2301 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2302 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2303 if (status < 0)
2304 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002305
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002306 /* SCU c.o.c. to 0, enabling full control range */
2307 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2308 if (status < 0)
2309 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002310
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002311 /* Write value to output pin */
2312 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2313 if (status < 0)
2314 goto error;
2315 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002317 case DRXK_AGC_CTRL_OFF:
2318 /* Disable RF AGC DAC */
2319 status = read16(state, IQM_AF_STDBY__A, &data);
2320 if (status < 0)
2321 goto error;
2322 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2323 status = write16(state, IQM_AF_STDBY__A, data);
2324 if (status < 0)
2325 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002327 /* Disable SCU RF AGC loop */
2328 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2329 if (status < 0)
2330 goto error;
2331 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2332 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2333 if (status < 0)
2334 goto error;
2335 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002336
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002337 default:
2338 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002339
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002340 }
2341error:
2342 if (status < 0)
2343 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002344 return status;
2345}
2346
2347#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2348
Oliver Endrissebc7de22011-07-03 13:49:44 -03002349static int SetAgcIf(struct drxk_state *state,
2350 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002351{
2352 u16 data = 0;
2353 int status = 0;
2354 struct SCfgAgc *pRfAgcSettings;
2355
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002356 dprintk(1, "\n");
2357
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002358 switch (pAgcCfg->ctrlMode) {
2359 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002361 /* Enable IF AGC DAC */
2362 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002363 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 goto error;
2365 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2366 status = write16(state, IQM_AF_STDBY__A, data);
2367 if (status < 0)
2368 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002369
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002370 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2371 if (status < 0)
2372 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002373
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002374 /* Enable SCU IF AGC loop */
2375 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2376
2377 /* Polarity */
2378 if (state->m_IfAgcPol)
2379 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2380 else
2381 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2382 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2383 if (status < 0)
2384 goto error;
2385
2386 /* Set speed (using complementary reduction value) */
2387 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2388 if (status < 0)
2389 goto error;
2390 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2391 data |= (~(pAgcCfg->speed <<
2392 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2393 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2394
2395 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2396 if (status < 0)
2397 goto error;
2398
2399 if (IsQAM(state))
2400 pRfAgcSettings = &state->m_qamRfAgcCfg;
2401 else
2402 pRfAgcSettings = &state->m_atvRfAgcCfg;
2403 if (pRfAgcSettings == NULL)
2404 return -1;
2405 /* Restore TOP */
2406 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2407 if (status < 0)
2408 goto error;
2409 break;
2410
2411 case DRXK_AGC_CTRL_USER:
2412
2413 /* Enable IF AGC DAC */
2414 status = read16(state, IQM_AF_STDBY__A, &data);
2415 if (status < 0)
2416 goto error;
2417 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2418 status = write16(state, IQM_AF_STDBY__A, data);
2419 if (status < 0)
2420 goto error;
2421
2422 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2423 if (status < 0)
2424 goto error;
2425
2426 /* Disable SCU IF AGC loop */
2427 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2428
2429 /* Polarity */
2430 if (state->m_IfAgcPol)
2431 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2432 else
2433 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2434 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2435 if (status < 0)
2436 goto error;
2437
2438 /* Write value to output pin */
2439 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2440 if (status < 0)
2441 goto error;
2442 break;
2443
2444 case DRXK_AGC_CTRL_OFF:
2445
2446 /* Disable If AGC DAC */
2447 status = read16(state, IQM_AF_STDBY__A, &data);
2448 if (status < 0)
2449 goto error;
2450 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2451 status = write16(state, IQM_AF_STDBY__A, data);
2452 if (status < 0)
2453 goto error;
2454
2455 /* Disable SCU IF AGC loop */
2456 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2457 if (status < 0)
2458 goto error;
2459 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2460 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2461 if (status < 0)
2462 goto error;
2463 break;
2464 } /* switch (agcSettingsIf->ctrlMode) */
2465
2466 /* always set the top to support
2467 configurations without if-loop */
2468 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2469error:
2470 if (status < 0)
2471 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472 return status;
2473}
2474
2475static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2476{
2477 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002478 int status;
2479 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002480
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002481 dprintk(1, "\n");
2482
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002483 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2484 if (status < 0) {
2485 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2486 return status;
2487 }
2488
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002489 *pValue = 0;
2490
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002491 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2492 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2493 if (Level < 14000)
2494 *pValue = (14000 - Level) / 4;
2495 else
2496 *pValue = 0;
2497
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002498 return status;
2499}
2500
Oliver Endrissebc7de22011-07-03 13:49:44 -03002501static int GetQAMSignalToNoise(struct drxk_state *state,
2502 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002503{
2504 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002505 u16 qamSlErrPower = 0; /* accum. error between
2506 raw and sliced symbols */
2507 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002508 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002509 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002510
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002511 dprintk(1, "\n");
2512
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002513 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002515 /* get the register value needed for MER */
2516 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2517 if (status < 0) {
2518 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2519 return -EINVAL;
2520 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002521
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002522 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002523 case QAM_16:
2524 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2525 break;
2526 case QAM_32:
2527 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2528 break;
2529 case QAM_64:
2530 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2531 break;
2532 case QAM_128:
2533 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2534 break;
2535 default:
2536 case QAM_256:
2537 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2538 break;
2539 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002540
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002541 if (qamSlErrPower > 0) {
2542 qamSlMer = Log10Times100(qamSlSigPower) -
2543 Log10Times100((u32) qamSlErrPower);
2544 }
2545 *pSignalToNoise = qamSlMer;
2546
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002547 return status;
2548}
2549
Oliver Endrissebc7de22011-07-03 13:49:44 -03002550static int GetDVBTSignalToNoise(struct drxk_state *state,
2551 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002552{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002553 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002554 u16 regData = 0;
2555 u32 EqRegTdSqrErrI = 0;
2556 u32 EqRegTdSqrErrQ = 0;
2557 u16 EqRegTdSqrErrExp = 0;
2558 u16 EqRegTdTpsPwrOfs = 0;
2559 u16 EqRegTdReqSmbCnt = 0;
2560 u32 tpsCnt = 0;
2561 u32 SqrErrIQ = 0;
2562 u32 a = 0;
2563 u32 b = 0;
2564 u32 c = 0;
2565 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002566 u16 transmissionParams = 0;
2567
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002568 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002569
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002570 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2571 if (status < 0)
2572 goto error;
2573 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2574 if (status < 0)
2575 goto error;
2576 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2577 if (status < 0)
2578 goto error;
2579 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2580 if (status < 0)
2581 goto error;
2582 /* Extend SQR_ERR_I operational range */
2583 EqRegTdSqrErrI = (u32) regData;
2584 if ((EqRegTdSqrErrExp > 11) &&
2585 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2586 EqRegTdSqrErrI += 0x00010000UL;
2587 }
2588 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2589 if (status < 0)
2590 goto error;
2591 /* Extend SQR_ERR_Q operational range */
2592 EqRegTdSqrErrQ = (u32) regData;
2593 if ((EqRegTdSqrErrExp > 11) &&
2594 (EqRegTdSqrErrQ < 0x00000FFFUL))
2595 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002596
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002597 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2598 if (status < 0)
2599 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002600
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002601 /* Check input data for MER */
2602
2603 /* MER calculation (in 0.1 dB) without math.h */
2604 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2605 iMER = 0;
2606 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2607 /* No error at all, this must be the HW reset value
2608 * Apparently no first measurement yet
2609 * Set MER to 0.0 */
2610 iMER = 0;
2611 } else {
2612 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2613 EqRegTdSqrErrExp;
2614 if ((transmissionParams &
2615 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2616 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2617 tpsCnt = 17;
2618 else
2619 tpsCnt = 68;
2620
2621 /* IMER = 100 * log10 (x)
2622 where x = (EqRegTdTpsPwrOfs^2 *
2623 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2624
2625 => IMER = a + b -c
2626 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2627 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2628 c = 100 * log10 (SqrErrIQ)
2629 */
2630
2631 /* log(x) x = 9bits * 9bits->18 bits */
2632 a = Log10Times100(EqRegTdTpsPwrOfs *
2633 EqRegTdTpsPwrOfs);
2634 /* log(x) x = 16bits * 7bits->23 bits */
2635 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2636 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2637 c = Log10Times100(SqrErrIQ);
2638
2639 iMER = a + b;
2640 /* No negative MER, clip to zero */
2641 if (iMER > c)
2642 iMER -= c;
2643 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002644 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002645 }
2646 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002647
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002648error:
2649 if (status < 0)
2650 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002651 return status;
2652}
2653
2654static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2655{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002656 dprintk(1, "\n");
2657
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002659 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660 case OM_DVBT:
2661 return GetDVBTSignalToNoise(state, pSignalToNoise);
2662 case OM_QAM_ITU_A:
2663 case OM_QAM_ITU_C:
2664 return GetQAMSignalToNoise(state, pSignalToNoise);
2665 default:
2666 break;
2667 }
2668 return 0;
2669}
2670
2671#if 0
2672static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2673{
2674 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2675 int status = 0;
2676
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002677 dprintk(1, "\n");
2678
Oliver Endrissebc7de22011-07-03 13:49:44 -03002679 static s32 QE_SN[] = {
2680 51, /* QPSK 1/2 */
2681 69, /* QPSK 2/3 */
2682 79, /* QPSK 3/4 */
2683 89, /* QPSK 5/6 */
2684 97, /* QPSK 7/8 */
2685 108, /* 16-QAM 1/2 */
2686 131, /* 16-QAM 2/3 */
2687 146, /* 16-QAM 3/4 */
2688 156, /* 16-QAM 5/6 */
2689 160, /* 16-QAM 7/8 */
2690 165, /* 64-QAM 1/2 */
2691 187, /* 64-QAM 2/3 */
2692 202, /* 64-QAM 3/4 */
2693 216, /* 64-QAM 5/6 */
2694 225, /* 64-QAM 7/8 */
2695 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002696
2697 *pQuality = 0;
2698
2699 do {
2700 s32 SignalToNoise = 0;
2701 u16 Constellation = 0;
2702 u16 CodeRate = 0;
2703 u32 SignalToNoiseRel;
2704 u32 BERQuality;
2705
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002706 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2707 if (status < 0)
2708 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002709 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002710 if (status < 0)
2711 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002712 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2713
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002714 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002715 if (status < 0)
2716 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002717 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2718
2719 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2720 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2721 break;
2722 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002723 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002724 BERQuality = 100;
2725
Oliver Endrissebc7de22011-07-03 13:49:44 -03002726 if (SignalToNoiseRel < -70)
2727 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002728 else if (SignalToNoiseRel < 30)
2729 *pQuality = ((SignalToNoiseRel + 70) *
2730 BERQuality) / 100;
2731 else
2732 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002733 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002734 return 0;
2735};
2736
Oliver Endrissebc7de22011-07-03 13:49:44 -03002737static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002738{
2739 int status = 0;
2740 *pQuality = 0;
2741
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002742 dprintk(1, "\n");
2743
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002744 do {
2745 u32 SignalToNoise = 0;
2746 u32 BERQuality = 100;
2747 u32 SignalToNoiseRel = 0;
2748
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002749 status = GetQAMSignalToNoise(state, &SignalToNoise);
2750 if (status < 0)
2751 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002753 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002754 case QAM_16:
2755 SignalToNoiseRel = SignalToNoise - 200;
2756 break;
2757 case QAM_32:
2758 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002759 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002760 case QAM_64:
2761 SignalToNoiseRel = SignalToNoise - 260;
2762 break;
2763 case QAM_128:
2764 SignalToNoiseRel = SignalToNoise - 290;
2765 break;
2766 default:
2767 case QAM_256:
2768 SignalToNoiseRel = SignalToNoise - 320;
2769 break;
2770 }
2771
2772 if (SignalToNoiseRel < -70)
2773 *pQuality = 0;
2774 else if (SignalToNoiseRel < 30)
2775 *pQuality = ((SignalToNoiseRel + 70) *
2776 BERQuality) / 100;
2777 else
2778 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002779 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002780
2781 return status;
2782}
2783
2784static int GetQuality(struct drxk_state *state, s32 *pQuality)
2785{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002786 dprintk(1, "\n");
2787
Oliver Endrissebc7de22011-07-03 13:49:44 -03002788 switch (state->m_OperationMode) {
2789 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002791 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002792 return GetDVBCQuality(state, pQuality);
2793 default:
2794 break;
2795 }
2796
2797 return 0;
2798}
2799#endif
2800
2801/* Free data ram in SIO HI */
2802#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2803#define SIO_HI_RA_RAM_USR_END__A 0x420060
2804
2805#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2806#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2807#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2808#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2809
2810#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2811#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2812#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2813
2814static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2815{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002816 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002818 dprintk(1, "\n");
2819
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002823 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002824
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002825 if (state->no_i2c_bridge)
2826 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002828 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2829 if (status < 0)
2830 goto error;
2831 if (bEnableBridge) {
2832 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 -03002833 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002834 goto error;
2835 } else {
2836 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2837 if (status < 0)
2838 goto error;
2839 }
2840
2841 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2842
2843error:
2844 if (status < 0)
2845 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002846 return status;
2847}
2848
Oliver Endrissebc7de22011-07-03 13:49:44 -03002849static int SetPreSaw(struct drxk_state *state,
2850 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002852 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002854 dprintk(1, "\n");
2855
Oliver Endrissebc7de22011-07-03 13:49:44 -03002856 if ((pPreSawCfg == NULL)
2857 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002858 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002860 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002861error:
2862 if (status < 0)
2863 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864 return status;
2865}
2866
2867static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002868 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002869{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002870 u16 blStatus = 0;
2871 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2872 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2873 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002874 unsigned long end;
2875
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002876 dprintk(1, "\n");
2877
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002878 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002879 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2880 if (status < 0)
2881 goto error;
2882 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2883 if (status < 0)
2884 goto error;
2885 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2886 if (status < 0)
2887 goto error;
2888 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2889 if (status < 0)
2890 goto error;
2891 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2892 if (status < 0)
2893 goto error;
2894 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2895 if (status < 0)
2896 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002897
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002898 end = jiffies + msecs_to_jiffies(timeOut);
2899 do {
2900 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2901 if (status < 0)
2902 goto error;
2903 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2904 if (blStatus == 0x1) {
2905 printk(KERN_ERR "drxk: SIO not ready\n");
2906 status = -EINVAL;
2907 goto error2;
2908 }
2909error:
2910 if (status < 0)
2911 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2912error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002913 mutex_unlock(&state->mutex);
2914 return status;
2915
2916}
2917
Oliver Endrissebc7de22011-07-03 13:49:44 -03002918static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919{
2920 u16 data = 0;
2921 int status;
2922
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002923 dprintk(1, "\n");
2924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002925 /* Start measurement */
2926 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2927 if (status < 0)
2928 goto error;
2929 status = write16(state, IQM_AF_START_LOCK__A, 1);
2930 if (status < 0)
2931 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002933 *count = 0;
2934 status = read16(state, IQM_AF_PHASE0__A, &data);
2935 if (status < 0)
2936 goto error;
2937 if (data == 127)
2938 *count = *count + 1;
2939 status = read16(state, IQM_AF_PHASE1__A, &data);
2940 if (status < 0)
2941 goto error;
2942 if (data == 127)
2943 *count = *count + 1;
2944 status = read16(state, IQM_AF_PHASE2__A, &data);
2945 if (status < 0)
2946 goto error;
2947 if (data == 127)
2948 *count = *count + 1;
2949
2950error:
2951 if (status < 0)
2952 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002953 return status;
2954}
2955
2956static int ADCSynchronization(struct drxk_state *state)
2957{
2958 u16 count = 0;
2959 int status;
2960
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002961 dprintk(1, "\n");
2962
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002963 status = ADCSyncMeasurement(state, &count);
2964 if (status < 0)
2965 goto error;
2966
2967 if (count == 1) {
2968 /* Try sampling on a diffrent edge */
2969 u16 clkNeg = 0;
2970
2971 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2972 if (status < 0)
2973 goto error;
2974 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2975 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2976 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2977 clkNeg |=
2978 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2979 } else {
2980 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2981 clkNeg |=
2982 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2983 }
2984 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2985 if (status < 0)
2986 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002987 status = ADCSyncMeasurement(state, &count);
2988 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002989 goto error;
2990 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002992 if (count < 2)
2993 status = -EINVAL;
2994error:
2995 if (status < 0)
2996 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002997 return status;
2998}
2999
3000static int SetFrequencyShifter(struct drxk_state *state,
3001 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003002 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003{
3004 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006 u32 fmFrequencyShift = 0;
3007 bool tunerMirror = !state->m_bMirrorFreqSpect;
3008 u32 adcFreq;
3009 bool adcFlip;
3010 int status;
3011 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003012 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003013 u32 frequencyShift;
3014 bool imageToSelect;
3015
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003016 dprintk(1, "\n");
3017
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003018 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 Program frequency shifter
3020 No need to account for mirroring on RF
3021 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003022 if (isDTV) {
3023 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3024 (state->m_OperationMode == OM_QAM_ITU_C) ||
3025 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003026 selectPosImage = true;
3027 else
3028 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003029 }
3030 if (tunerMirror)
3031 /* tuner doesn't mirror */
3032 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003033 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003034 else
3035 /* tuner mirrors */
3036 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003037 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003038 if (ifFreqActual > samplingFrequency / 2) {
3039 /* adc mirrors */
3040 adcFreq = samplingFrequency - ifFreqActual;
3041 adcFlip = true;
3042 } else {
3043 /* adc doesn't mirror */
3044 adcFreq = ifFreqActual;
3045 adcFlip = false;
3046 }
3047
3048 frequencyShift = adcFreq;
3049 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003050 adcFlip ^ selectPosImage;
3051 state->m_IqmFsRateOfs =
3052 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003053
3054 if (imageToSelect)
3055 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3056
3057 /* Program frequency shifter with tuner offset compensation */
3058 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003059 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3060 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003061 if (status < 0)
3062 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003063 return status;
3064}
3065
3066static int InitAGC(struct drxk_state *state, bool isDTV)
3067{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003068 u16 ingainTgt = 0;
3069 u16 ingainTgtMin = 0;
3070 u16 ingainTgtMax = 0;
3071 u16 clpCyclen = 0;
3072 u16 clpSumMin = 0;
3073 u16 clpDirTo = 0;
3074 u16 snsSumMin = 0;
3075 u16 snsSumMax = 0;
3076 u16 clpSumMax = 0;
3077 u16 snsDirTo = 0;
3078 u16 kiInnergainMin = 0;
3079 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003080 u16 ifIaccuHiTgtMin = 0;
3081 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003082 u16 data = 0;
3083 u16 fastClpCtrlDelay = 0;
3084 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003085 int status = 0;
3086
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003087 dprintk(1, "\n");
3088
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003089 /* Common settings */
3090 snsSumMax = 1023;
3091 ifIaccuHiTgtMin = 2047;
3092 clpCyclen = 500;
3093 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003094
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003095 /* AGCInit() not available for DVBT; init done in microcode */
3096 if (!IsQAM(state)) {
3097 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3098 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003099 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003100
3101 /* FIXME: Analog TV AGC require different settings */
3102
3103 /* Standard specific settings */
3104 clpSumMin = 8;
3105 clpDirTo = (u16) -9;
3106 clpCtrlMode = 0;
3107 snsSumMin = 8;
3108 snsDirTo = (u16) -9;
3109 kiInnergainMin = (u16) -1030;
3110 ifIaccuHiTgtMax = 0x2380;
3111 ifIaccuHiTgt = 0x2380;
3112 ingainTgtMin = 0x0511;
3113 ingainTgt = 0x0511;
3114 ingainTgtMax = 5119;
3115 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003117 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3118 if (status < 0)
3119 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003121 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3122 if (status < 0)
3123 goto error;
3124 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3131 if (status < 0)
3132 goto error;
3133 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3134 if (status < 0)
3135 goto error;
3136 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3137 if (status < 0)
3138 goto error;
3139 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3155 if (status < 0)
3156 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003157
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003158 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3159 if (status < 0)
3160 goto error;
3161 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3162 if (status < 0)
3163 goto error;
3164 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3165 if (status < 0)
3166 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003167
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003168 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3169 if (status < 0)
3170 goto error;
3171 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3175 if (status < 0)
3176 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003177
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003178 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3179 if (status < 0)
3180 goto error;
3181 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3188 if (status < 0)
3189 goto error;
3190 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3191 if (status < 0)
3192 goto error;
3193 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3194 if (status < 0)
3195 goto error;
3196 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3233 if (status < 0)
3234 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003235
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003236 /* Initialize inner-loop KI gain factors */
3237 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3238 if (status < 0)
3239 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003240
3241 data = 0x0657;
3242 data &= ~SCU_RAM_AGC_KI_RF__M;
3243 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3244 data &= ~SCU_RAM_AGC_KI_IF__M;
3245 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3246
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003247 status = write16(state, SCU_RAM_AGC_KI__A, data);
3248error:
3249 if (status < 0)
3250 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 return status;
3252}
3253
Oliver Endrissebc7de22011-07-03 13:49:44 -03003254static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003255{
3256 int status;
3257
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003258 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003259 if (packetErr == NULL)
3260 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3261 else
3262 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3263 if (status < 0)
3264 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003265 return status;
3266}
3267
3268static int DVBTScCommand(struct drxk_state *state,
3269 u16 cmd, u16 subcmd,
3270 u16 param0, u16 param1, u16 param2,
3271 u16 param3, u16 param4)
3272{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003273 u16 curCmd = 0;
3274 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003275 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003276 u16 scExec = 0;
3277 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003279 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003280 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281 if (scExec != 1) {
3282 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003283 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003285 if (status < 0)
3286 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287
3288 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003289 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 do {
3291 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003292 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 retryCnt++;
3294 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003295 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3296 goto error;
3297
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003298 /* Write sub-command */
3299 switch (cmd) {
3300 /* All commands using sub-cmd */
3301 case OFDM_SC_RA_RAM_CMD_PROC_START:
3302 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3303 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003304 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3305 if (status < 0)
3306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003307 break;
3308 default:
3309 /* Do nothing */
3310 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003311 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003312
3313 /* Write needed parameters and the command */
3314 switch (cmd) {
3315 /* All commands using 5 parameters */
3316 /* All commands using 4 parameters */
3317 /* All commands using 3 parameters */
3318 /* All commands using 2 parameters */
3319 case OFDM_SC_RA_RAM_CMD_PROC_START:
3320 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3321 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003322 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003323 /* All commands using 1 parameters */
3324 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3325 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003326 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003327 /* All commands using 0 parameters */
3328 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3329 case OFDM_SC_RA_RAM_CMD_NULL:
3330 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003331 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003332 break;
3333 default:
3334 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003335 status = -EINVAL;
3336 }
3337 if (status < 0)
3338 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339
3340 /* Wait until sc is ready processing command */
3341 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003342 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003344 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003346 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003347 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3348 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349
3350 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003351 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003352 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003353 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003354 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003356 if (status < 0)
3357 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358
3359 /* Retreive results parameters from SC */
3360 switch (cmd) {
3361 /* All commands yielding 5 results */
3362 /* All commands yielding 4 results */
3363 /* All commands yielding 3 results */
3364 /* All commands yielding 2 results */
3365 /* All commands yielding 1 result */
3366 case OFDM_SC_RA_RAM_CMD_USER_IO:
3367 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003368 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003369 /* All commands yielding 0 results */
3370 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3371 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3372 case OFDM_SC_RA_RAM_CMD_PROC_START:
3373 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3374 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3375 case OFDM_SC_RA_RAM_CMD_NULL:
3376 break;
3377 default:
3378 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003379 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003380 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003381 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003382error:
3383 if (status < 0)
3384 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003385 return status;
3386}
3387
Oliver Endrissebc7de22011-07-03 13:49:44 -03003388static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003390 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391 int status;
3392
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003393 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003394 status = CtrlPowerMode(state, &powerMode);
3395 if (status < 0)
3396 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397 return status;
3398}
3399
Oliver Endrissebc7de22011-07-03 13:49:44 -03003400static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003401{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003404 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003405 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003406 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003408 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003409 if (status < 0)
3410 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003411 return status;
3412}
3413
3414#define DEFAULT_FR_THRES_8K 4000
3415static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3416{
3417
3418 int status;
3419
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003420 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421 if (*enabled == true) {
3422 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003423 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 DEFAULT_FR_THRES_8K);
3425 } else {
3426 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003427 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003428 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003429 if (status < 0)
3430 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003431
3432 return status;
3433}
3434
3435static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3436 struct DRXKCfgDvbtEchoThres_t *echoThres)
3437{
3438 u16 data = 0;
3439 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003440
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003441 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003442 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3443 if (status < 0)
3444 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003445
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003446 switch (echoThres->fftMode) {
3447 case DRX_FFTMODE_2K:
3448 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3449 data |= ((echoThres->threshold <<
3450 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3451 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003452 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003453 case DRX_FFTMODE_8K:
3454 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3455 data |= ((echoThres->threshold <<
3456 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3457 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003458 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 default:
3460 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003461 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003462
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003463 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3464error:
3465 if (status < 0)
3466 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003467 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003468}
3469
3470static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003471 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003472{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003473 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003475 dprintk(1, "\n");
3476
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477 switch (*speed) {
3478 case DRXK_DVBT_SQI_SPEED_FAST:
3479 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3480 case DRXK_DVBT_SQI_SPEED_SLOW:
3481 break;
3482 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003483 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003484 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003485 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003486 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003487error:
3488 if (status < 0)
3489 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490 return status;
3491}
3492
3493/*============================================================================*/
3494
3495/**
3496* \brief Activate DVBT specific presets
3497* \param demod instance of demodulator.
3498* \return DRXStatus_t.
3499*
3500* Called in DVBTSetStandard
3501*
3502*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003503static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003504{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003505 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003506 bool setincenable = false;
3507 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508
Oliver Endrissebc7de22011-07-03 13:49:44 -03003509 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3510 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003511
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003512 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003513 status = DVBTCtrlSetIncEnable(state, &setincenable);
3514 if (status < 0)
3515 goto error;
3516 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3517 if (status < 0)
3518 goto error;
3519 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3520 if (status < 0)
3521 goto error;
3522 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3523 if (status < 0)
3524 goto error;
3525 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3526error:
3527 if (status < 0)
3528 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003529 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003531
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003532/*============================================================================*/
3533
3534/**
3535* \brief Initialize channelswitch-independent settings for DVBT.
3536* \param demod instance of demodulator.
3537* \return DRXStatus_t.
3538*
3539* For ROM code channel filter taps are loaded from the bootloader. For microcode
3540* the DVB-T taps from the drxk_filters.h are used.
3541*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003542static int SetDVBTStandard(struct drxk_state *state,
3543 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003544{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003545 u16 cmdResult = 0;
3546 u16 data = 0;
3547 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003549 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003550
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003551 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003552 /* added antenna switch */
3553 SwitchAntennaToDVBT(state);
3554 /* send OFDM reset command */
3555 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 -03003556 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003557 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003559 /* send OFDM setenv command */
3560 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3561 if (status < 0)
3562 goto error;
3563
3564 /* reset datapath for OFDM, processors first */
3565 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3566 if (status < 0)
3567 goto error;
3568 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3569 if (status < 0)
3570 goto error;
3571 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3572 if (status < 0)
3573 goto error;
3574
3575 /* IQM setup */
3576 /* synchronize on ofdstate->m_festart */
3577 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3578 if (status < 0)
3579 goto error;
3580 /* window size for clipping ADC detection */
3581 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3582 if (status < 0)
3583 goto error;
3584 /* window size for for sense pre-SAW detection */
3585 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3586 if (status < 0)
3587 goto error;
3588 /* sense threshold for sense pre-SAW detection */
3589 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3590 if (status < 0)
3591 goto error;
3592 status = SetIqmAf(state, true);
3593 if (status < 0)
3594 goto error;
3595
3596 status = write16(state, IQM_AF_AGC_RF__A, 0);
3597 if (status < 0)
3598 goto error;
3599
3600 /* Impulse noise cruncher setup */
3601 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3602 if (status < 0)
3603 goto error;
3604 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3608 if (status < 0)
3609 goto error;
3610
3611 status = write16(state, IQM_RC_STRETCH__A, 16);
3612 if (status < 0)
3613 goto error;
3614 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_SCALE__A, 1600);
3621 if (status < 0)
3622 goto error;
3623 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3624 if (status < 0)
3625 goto error;
3626
3627 /* virtual clipping threshold for clipping ADC detection */
3628 status = write16(state, IQM_AF_CLP_TH__A, 448);
3629 if (status < 0)
3630 goto error;
3631 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3632 if (status < 0)
3633 goto error;
3634
3635 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3636 if (status < 0)
3637 goto error;
3638
3639 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3640 if (status < 0)
3641 goto error;
3642 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3643 if (status < 0)
3644 goto error;
3645 /* enable power measurement interrupt */
3646 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3647 if (status < 0)
3648 goto error;
3649 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3650 if (status < 0)
3651 goto error;
3652
3653 /* IQM will not be reset from here, sync ADC and update/init AGC */
3654 status = ADCSynchronization(state);
3655 if (status < 0)
3656 goto error;
3657 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3658 if (status < 0)
3659 goto error;
3660
3661 /* Halt SCU to enable safe non-atomic accesses */
3662 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3663 if (status < 0)
3664 goto error;
3665
3666 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3667 if (status < 0)
3668 goto error;
3669 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3670 if (status < 0)
3671 goto error;
3672
3673 /* Set Noise Estimation notch width and enable DC fix */
3674 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3675 if (status < 0)
3676 goto error;
3677 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3678 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3679 if (status < 0)
3680 goto error;
3681
3682 /* Activate SCU to enable SCU commands */
3683 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3684 if (status < 0)
3685 goto error;
3686
3687 if (!state->m_DRXK_A3_ROM_CODE) {
3688 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3689 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3690 if (status < 0)
3691 goto error;
3692 }
3693
3694 /* OFDM_SC setup */
3695#ifdef COMPILE_FOR_NONRT
3696 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3697 if (status < 0)
3698 goto error;
3699 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3700 if (status < 0)
3701 goto error;
3702#endif
3703
3704 /* FEC setup */
3705 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3706 if (status < 0)
3707 goto error;
3708
3709
3710#ifdef COMPILE_FOR_NONRT
3711 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3712 if (status < 0)
3713 goto error;
3714#else
3715 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3716 if (status < 0)
3717 goto error;
3718#endif
3719 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3720 if (status < 0)
3721 goto error;
3722
3723 /* Setup MPEG bus */
3724 status = MPEGTSDtoSetup(state, OM_DVBT);
3725 if (status < 0)
3726 goto error;
3727 /* Set DVBT Presets */
3728 status = DVBTActivatePresets(state);
3729 if (status < 0)
3730 goto error;
3731
3732error:
3733 if (status < 0)
3734 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003735 return status;
3736}
3737
3738/*============================================================================*/
3739/**
3740* \brief Start dvbt demodulating for channel.
3741* \param demod instance of demodulator.
3742* \return DRXStatus_t.
3743*/
3744static int DVBTStart(struct drxk_state *state)
3745{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003746 u16 param1;
3747 int status;
3748 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003749
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003750 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003751 /* Start correct processes to get in lock */
3752 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003753 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3754 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3755 if (status < 0)
3756 goto error;
3757 /* Start FEC OC */
3758 status = MPEGTSStart(state);
3759 if (status < 0)
3760 goto error;
3761 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3762 if (status < 0)
3763 goto error;
3764error:
3765 if (status < 0)
3766 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003767 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768}
3769
3770
3771/*============================================================================*/
3772
3773/**
3774* \brief Set up dvbt demodulator for channel.
3775* \param demod instance of demodulator.
3776* \return DRXStatus_t.
3777* // original DVBTSetChannel()
3778*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003779static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3780 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003781{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003782 u16 cmdResult = 0;
3783 u16 transmissionParams = 0;
3784 u16 operationMode = 0;
3785 u32 iqmRcRateOfs = 0;
3786 u32 bandwidth = 0;
3787 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003788 int status;
3789
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003790 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003792 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3793 if (status < 0)
3794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 /* Halt SCU to enable safe non-atomic accesses */
3797 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3798 if (status < 0)
3799 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003800
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003801 /* Stop processors */
3802 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3803 if (status < 0)
3804 goto error;
3805 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3806 if (status < 0)
3807 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003809 /* Mandatory fix, always stop CP, required to set spl offset back to
3810 hardware default (is set to 0 by ucode during pilot detection */
3811 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3812 if (status < 0)
3813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003816
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003817 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003818 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 case TRANSMISSION_MODE_AUTO:
3820 default:
3821 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3822 /* fall through , try first guess DRX_FFTMODE_8K */
3823 case TRANSMISSION_MODE_8K:
3824 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003825 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003826 case TRANSMISSION_MODE_2K:
3827 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003828 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003831 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003832 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 default:
3834 case GUARD_INTERVAL_AUTO:
3835 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3836 /* fall through , try first guess DRX_GUARD_1DIV4 */
3837 case GUARD_INTERVAL_1_4:
3838 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003839 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003840 case GUARD_INTERVAL_1_32:
3841 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003842 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003843 case GUARD_INTERVAL_1_16:
3844 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003845 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 case GUARD_INTERVAL_1_8:
3847 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003848 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 }
3850
3851 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003852 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003853 case HIERARCHY_AUTO:
3854 case HIERARCHY_NONE:
3855 default:
3856 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3857 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3858 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3859 /* break; */
3860 case HIERARCHY_1:
3861 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3862 break;
3863 case HIERARCHY_2:
3864 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3865 break;
3866 case HIERARCHY_4:
3867 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3868 break;
3869 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003870
3871
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003872 /* modulation */
3873 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003874 case QAM_AUTO:
3875 default:
3876 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3877 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3878 case QAM_64:
3879 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3880 break;
3881 case QPSK:
3882 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3883 break;
3884 case QAM_16:
3885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3886 break;
3887 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003888#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003889 /* No hierachical channels support in BDA */
3890 /* Priority (only for hierarchical channels) */
3891 switch (channel->priority) {
3892 case DRX_PRIORITY_LOW:
3893 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3894 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3895 OFDM_EC_SB_PRIOR_LO);
3896 break;
3897 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003898 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003899 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3900 OFDM_EC_SB_PRIOR_HI));
3901 break;
3902 case DRX_PRIORITY_UNKNOWN: /* fall through */
3903 default:
3904 status = -EINVAL;
3905 goto error;
3906 }
3907#else
3908 /* Set Priorty high */
3909 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3910 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3911 if (status < 0)
3912 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003913#endif
3914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003915 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003916 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003917 case FEC_AUTO:
3918 default:
3919 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3920 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3921 case FEC_2_3:
3922 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3923 break;
3924 case FEC_1_2:
3925 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3926 break;
3927 case FEC_3_4:
3928 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3929 break;
3930 case FEC_5_6:
3931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3932 break;
3933 case FEC_7_8:
3934 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3935 break;
3936 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003937
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003938 /* SAW filter selection: normaly not necesarry, but if wanted
3939 the application can select a SAW filter via the driver by using UIOs */
3940 /* First determine real bandwidth (Hz) */
3941 /* Also set delay for impulse noise cruncher */
3942 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3943 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3944 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003945 switch (state->props.bandwidth_hz) {
3946 case 0:
3947 state->props.bandwidth_hz = 8000000;
3948 /* fall though */
3949 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003950 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003968 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003969 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003987 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003988 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.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004194* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004195* \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,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004203 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004204 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] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004217 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004218 SyncLoss (== 1) *
4219 ViterbiLoss (==1)
4220 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004221 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004222 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;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005288 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5289 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005290 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005291 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005292 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005293 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005294 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 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005302 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005303 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 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005318 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005319 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;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005389 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5390 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005391
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005392 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005393 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005394 * STEP 1: reset demodulator
5395 * resets FEC DI and FEC RS
5396 * resets QAM block
5397 * resets SCU variables
5398 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005399 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005400 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005401 goto error;
5402 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5403 if (status < 0)
5404 goto error;
5405 status = QAMResetQAM(state);
5406 if (status < 0)
5407 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005408
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005409 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005410 * STEP 2: configure demodulator
5411 * -set params; resets IQM,QAM,FEC HW; initializes some
5412 * SCU variables
5413 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005414 status = QAMSetSymbolrate(state);
5415 if (status < 0)
5416 goto error;
5417
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005418 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005419 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005420 case QAM_256:
5421 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5422 break;
5423 case QAM_AUTO:
5424 case QAM_64:
5425 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5426 break;
5427 case QAM_16:
5428 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5429 break;
5430 case QAM_32:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5432 break;
5433 case QAM_128:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5435 break;
5436 default:
5437 status = -EINVAL;
5438 break;
5439 }
5440 if (status < 0)
5441 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005442 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005443 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005444 if (state->m_OperationMode == OM_QAM_ITU_C)
5445 setParamParameters[2] = QAM_TOP_ANNEX_C;
5446 else
5447 setParamParameters[2] = QAM_TOP_ANNEX_A;
5448 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5449 /* Env parameters */
5450 /* check for LOCKRANGE Extented */
5451 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005452
5453 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005454 if (status < 0) {
5455 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005456 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005457 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005458 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005459 setParamParameters[0] = QAM_TOP_ANNEX_A;
5460 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5461 if (status < 0)
5462 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005463
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005464 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005465 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005466 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5467 }
5468 if (status < 0)
5469 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005470
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005471 /*
5472 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005473 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005474 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005475#if 0
5476 status = SetFrequency(channel, tunerFreqOffset));
5477 if (status < 0)
5478 goto error;
5479#endif
5480 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5481 if (status < 0)
5482 goto error;
5483
5484 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005485 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005486 if (status < 0)
5487 goto error;
5488
5489 /* Reset default values */
5490 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5491 if (status < 0)
5492 goto error;
5493 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5494 if (status < 0)
5495 goto error;
5496
5497 /* Reset default LC values */
5498 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5499 if (status < 0)
5500 goto error;
5501 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5502 if (status < 0)
5503 goto error;
5504 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_MODE__A, 7);
5508 if (status < 0)
5509 goto error;
5510
5511 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5512 if (status < 0)
5513 goto error;
5514 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5515 if (status < 0)
5516 goto error;
5517 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5554 if (status < 0)
5555 goto error;
5556
5557 /* Mirroring, QAM-block starting point not inverted */
5558 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5559 if (status < 0)
5560 goto error;
5561
5562 /* Halt SCU to enable safe non-atomic accesses */
5563 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5564 if (status < 0)
5565 goto error;
5566
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005567 /* STEP 4: modulation specific setup */
5568 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005569 case QAM_16:
5570 status = SetQAM16(state);
5571 break;
5572 case QAM_32:
5573 status = SetQAM32(state);
5574 break;
5575 case QAM_AUTO:
5576 case QAM_64:
5577 status = SetQAM64(state);
5578 break;
5579 case QAM_128:
5580 status = SetQAM128(state);
5581 break;
5582 case QAM_256:
5583 status = SetQAM256(state);
5584 break;
5585 default:
5586 status = -EINVAL;
5587 break;
5588 }
5589 if (status < 0)
5590 goto error;
5591
5592 /* Activate SCU to enable SCU commands */
5593 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5594 if (status < 0)
5595 goto error;
5596
5597 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005598 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005599 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5600 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5601 if (status < 0)
5602 goto error;
5603
5604 /* Start processes */
5605 status = MPEGTSStart(state);
5606 if (status < 0)
5607 goto error;
5608 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617
5618 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5619 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5620 if (status < 0)
5621 goto error;
5622
5623 /* update global DRXK data container */
5624/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5625
5626error:
5627 if (status < 0)
5628 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005629 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005630}
5631
Oliver Endrissebc7de22011-07-03 13:49:44 -03005632static int SetQAMStandard(struct drxk_state *state,
5633 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005635 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636#ifdef DRXK_QAM_TAPS
5637#define DRXK_QAMA_TAPS_SELECT
5638#include "drxk_filters.h"
5639#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640#endif
5641
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005642 dprintk(1, "\n");
5643
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005644 /* added antenna switch */
5645 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005647 /* Ensure correct power-up mode */
5648 status = PowerUpQAM(state);
5649 if (status < 0)
5650 goto error;
5651 /* Reset QAM block */
5652 status = QAMResetQAM(state);
5653 if (status < 0)
5654 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005655
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005656 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005657
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005658 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5659 if (status < 0)
5660 goto error;
5661 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5662 if (status < 0)
5663 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005664
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005665 /* Upload IQM Channel Filter settings by
5666 boot loader from ROM table */
5667 switch (oMode) {
5668 case OM_QAM_ITU_A:
5669 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5670 break;
5671 case OM_QAM_ITU_C:
5672 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 -03005673 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005674 goto error;
5675 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5676 break;
5677 default:
5678 status = -EINVAL;
5679 }
5680 if (status < 0)
5681 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005682
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005683 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5684 if (status < 0)
5685 goto error;
5686 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5687 if (status < 0)
5688 goto error;
5689 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5690 if (status < 0)
5691 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005692
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005693 status = write16(state, IQM_RC_STRETCH__A, 21);
5694 if (status < 0)
5695 goto error;
5696 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5697 if (status < 0)
5698 goto error;
5699 status = write16(state, IQM_AF_CLP_TH__A, 448);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5706 if (status < 0)
5707 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005708
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005709 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5713 if (status < 0)
5714 goto error;
5715 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5719 if (status < 0)
5720 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005722 /* IQM Impulse Noise Processing Unit */
5723 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5724 if (status < 0)
5725 goto error;
5726 status = write16(state, IQM_CF_DATATH__A, 1000);
5727 if (status < 0)
5728 goto error;
5729 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_DET_LCT__A, 0);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_WND_LEN__A, 1);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_PKDTH__A, 1);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5742 if (status < 0)
5743 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005744
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 /* turn on IQMAF. Must be done before setAgc**() */
5746 status = SetIqmAf(state, true);
5747 if (status < 0)
5748 goto error;
5749 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5750 if (status < 0)
5751 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005753 /* IQM will not be reset from here, sync ADC and update/init AGC */
5754 status = ADCSynchronization(state);
5755 if (status < 0)
5756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005758 /* Set the FSM step period */
5759 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5760 if (status < 0)
5761 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005762
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005763 /* Halt SCU to enable safe non-atomic accesses */
5764 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5765 if (status < 0)
5766 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005767
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005768 /* No more resets of the IQM, current standard correctly set =>
5769 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005771 status = InitAGC(state, true);
5772 if (status < 0)
5773 goto error;
5774 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5775 if (status < 0)
5776 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005778 /* Configure AGC's */
5779 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5780 if (status < 0)
5781 goto error;
5782 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5783 if (status < 0)
5784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005786 /* Activate SCU to enable SCU commands */
5787 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5788error:
5789 if (status < 0)
5790 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005791 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005792}
5793
5794static int WriteGPIO(struct drxk_state *state)
5795{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005796 int status;
5797 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005798
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005799 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005800 /* stop lock indicator process */
5801 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5802 if (status < 0)
5803 goto error;
5804
5805 /* Write magic word to enable pdr reg write */
5806 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5807 if (status < 0)
5808 goto error;
5809
5810 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005811 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5812 /* write to io pad configuration register - output mode */
5813 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5814 if (status < 0)
5815 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005816
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005817 /* use corresponding bit in io data output registar */
5818 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5819 if (status < 0)
5820 goto error;
5821 if ((state->m_GPIO & 0x0001) == 0)
5822 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5823 else
5824 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5825 /* write back to io data output register */
5826 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5827 if (status < 0)
5828 goto error;
5829 }
5830 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5831 /* write to io pad configuration register - output mode */
5832 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5833 if (status < 0)
5834 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005835
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005836 /* use corresponding bit in io data output registar */
5837 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5838 if (status < 0)
5839 goto error;
5840 if ((state->m_GPIO & 0x0002) == 0)
5841 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5842 else
5843 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5844 /* write back to io data output register */
5845 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5846 if (status < 0)
5847 goto error;
5848 }
5849 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5850 /* write to io pad configuration register - output mode */
5851 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5852 if (status < 0)
5853 goto error;
5854
5855 /* use corresponding bit in io data output registar */
5856 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5857 if (status < 0)
5858 goto error;
5859 if ((state->m_GPIO & 0x0004) == 0)
5860 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5861 else
5862 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5863 /* write back to io data output register */
5864 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5865 if (status < 0)
5866 goto error;
5867 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005868 }
5869 /* Write magic word to disable pdr reg write */
5870 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5871error:
5872 if (status < 0)
5873 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005874 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875}
5876
5877static int SwitchAntennaToQAM(struct drxk_state *state)
5878{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005879 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005880 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005882 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005883
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005884 if (!state->antenna_gpio)
5885 return 0;
5886
5887 gpio_state = state->m_GPIO & state->antenna_gpio;
5888
5889 if (state->antenna_dvbt ^ gpio_state) {
5890 /* Antenna is on DVB-T mode. Switch */
5891 if (state->antenna_dvbt)
5892 state->m_GPIO &= ~state->antenna_gpio;
5893 else
5894 state->m_GPIO |= state->antenna_gpio;
5895 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005896 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005897 if (status < 0)
5898 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005899 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005900}
5901
5902static int SwitchAntennaToDVBT(struct drxk_state *state)
5903{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005904 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005905 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005906
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005907 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005908
5909 if (!state->antenna_gpio)
5910 return 0;
5911
5912 gpio_state = state->m_GPIO & state->antenna_gpio;
5913
5914 if (!(state->antenna_dvbt ^ gpio_state)) {
5915 /* Antenna is on DVB-C mode. Switch */
5916 if (state->antenna_dvbt)
5917 state->m_GPIO |= state->antenna_gpio;
5918 else
5919 state->m_GPIO &= ~state->antenna_gpio;
5920 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005921 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005922 if (status < 0)
5923 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005924 return status;
5925}
5926
5927
5928static int PowerDownDevice(struct drxk_state *state)
5929{
5930 /* Power down to requested mode */
5931 /* Backup some register settings */
5932 /* Set pins with possible pull-ups connected to them in input mode */
5933 /* Analog power down */
5934 /* ADC power down */
5935 /* Power down device */
5936 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005937
5938 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005939 if (state->m_bPDownOpenBridge) {
5940 /* Open I2C bridge before power down of DRXK */
5941 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005942 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005943 goto error;
5944 }
5945 /* driver 0.9.0 */
5946 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005950 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5951 if (status < 0)
5952 goto error;
5953 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5954 if (status < 0)
5955 goto error;
5956 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5957 status = HI_CfgCommand(state);
5958error:
5959 if (status < 0)
5960 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5961
5962 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963}
5964
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005965static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005966{
5967 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005968 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005970 dprintk(1, "\n");
5971
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5973 if (err < 0) {
5974 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005975 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005976 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005977 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 return err;
5979 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005980 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005981 release_firmware(fw);
5982 return err;
5983}
5984
5985static int init_drxk(struct drxk_state *state)
5986{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005987 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005988 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005989 u16 driverVersion;
5990
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005991 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005992 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005993 status = PowerUpDevice(state);
5994 if (status < 0)
5995 goto error;
5996 status = DRXX_Open(state);
5997 if (status < 0)
5998 goto error;
5999 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6000 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);
6001 if (status < 0)
6002 goto error;
6003 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6004 if (status < 0)
6005 goto error;
6006 /* TODO is this needed, if yes how much delay in worst case scenario */
6007 msleep(1);
6008 state->m_DRXK_A3_PATCH_CODE = true;
6009 status = GetDeviceCapabilities(state);
6010 if (status < 0)
6011 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006013 /* Bridge delay, uses oscilator clock */
6014 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6015 /* SDA brdige delay */
6016 state->m_HICfgBridgeDelay =
6017 (u16) ((state->m_oscClockFreq / 1000) *
6018 HI_I2C_BRIDGE_DELAY) / 1000;
6019 /* Clipping */
6020 if (state->m_HICfgBridgeDelay >
6021 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006022 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006023 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6024 }
6025 /* SCL bridge delay, same as SDA for now */
6026 state->m_HICfgBridgeDelay +=
6027 state->m_HICfgBridgeDelay <<
6028 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 status = InitHI(state);
6031 if (status < 0)
6032 goto error;
6033 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 if (!(state->m_DRXK_A1_ROM_CODE)
6036 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006037#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006038 {
6039 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6040 if (status < 0)
6041 goto error;
6042 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006044 /* disable MPEG port */
6045 status = MPEGTSDisable(state);
6046 if (status < 0)
6047 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006049 /* Stop AUD and SCU */
6050 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6051 if (status < 0)
6052 goto error;
6053 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6054 if (status < 0)
6055 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006056
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006057 /* enable token-ring bus through OFDM block for possible ucode upload */
6058 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6059 if (status < 0)
6060 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006062 /* include boot loader section */
6063 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6064 if (status < 0)
6065 goto error;
6066 status = BLChainCmd(state, 0, 6, 100);
6067 if (status < 0)
6068 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006069
Mauro Carvalho Chehabda989e02011-07-24 09:25:39 -03006070 if (state->microcode_name)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006071 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006072
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006073 /* disable token-ring bus through OFDM block for possible ucode upload */
6074 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6075 if (status < 0)
6076 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 /* Run SCU for a little while to initialize microcode version numbers */
6079 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6080 if (status < 0)
6081 goto error;
6082 status = DRXX_Open(state);
6083 if (status < 0)
6084 goto error;
6085 /* added for test */
6086 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006088 powerMode = DRXK_POWER_DOWN_OFDM;
6089 status = CtrlPowerMode(state, &powerMode);
6090 if (status < 0)
6091 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 /* Stamp driver version number in SCU data RAM in BCD code
6094 Done to enable field application engineers to retreive drxdriver version
6095 via I2C from SCU RAM.
6096 Not using SCU command interface for SCU register access since no
6097 microcode may be present.
6098 */
6099 driverVersion =
6100 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6101 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6102 ((DRXK_VERSION_MAJOR % 10) << 4) +
6103 (DRXK_VERSION_MINOR % 10);
6104 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6105 if (status < 0)
6106 goto error;
6107 driverVersion =
6108 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6109 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6110 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6111 (DRXK_VERSION_PATCH % 10);
6112 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6113 if (status < 0)
6114 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006116 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6117 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6118 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 /* Dirty fix of default values for ROM/PATCH microcode
6121 Dirty because this fix makes it impossible to setup suitable values
6122 before calling DRX_Open. This solution requires changes to RF AGC speed
6123 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006127 /* Reset driver debug flags to 0 */
6128 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6129 if (status < 0)
6130 goto error;
6131 /* driver 0.9.0 */
6132 /* Setup FEC OC:
6133 NOTE: No more full FEC resets allowed afterwards!! */
6134 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6135 if (status < 0)
6136 goto error;
6137 /* MPEGTS functions are still the same */
6138 status = MPEGTSDtoInit(state);
6139 if (status < 0)
6140 goto error;
6141 status = MPEGTSStop(state);
6142 if (status < 0)
6143 goto error;
6144 status = MPEGTSConfigurePolarity(state);
6145 if (status < 0)
6146 goto error;
6147 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6148 if (status < 0)
6149 goto error;
6150 /* added: configure GPIO */
6151 status = WriteGPIO(state);
6152 if (status < 0)
6153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006155 state->m_DrxkState = DRXK_STOPPED;
6156
6157 if (state->m_bPowerDown) {
6158 status = PowerDownDevice(state);
6159 if (status < 0)
6160 goto error;
6161 state->m_DrxkState = DRXK_POWERED_DOWN;
6162 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006163 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006164 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006165error:
6166 if (status < 0)
6167 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006169 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006170}
6171
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006172static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006173{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006174 struct drxk_state *state = fe->demodulator_priv;
6175
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006176 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177 kfree(state);
6178}
6179
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006180static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006182 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006184 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186 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
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006197static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006198{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006199 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006200 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201 struct drxk_state *state = fe->demodulator_priv;
6202 u32 IF;
6203
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006204 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006205
6206 if (!fe->ops.tuner_ops.get_if_frequency) {
6207 printk(KERN_ERR
6208 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6209 return -EINVAL;
6210 }
6211
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006212 if (fe->ops.i2c_gate_ctrl)
6213 fe->ops.i2c_gate_ctrl(fe, 1);
6214 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006215 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 if (fe->ops.i2c_gate_ctrl)
6217 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006218
6219 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006220 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006221
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006222 if (old_delsys != delsys) {
6223 ShutDown(state);
6224 switch (delsys) {
6225 case SYS_DVBC_ANNEX_A:
6226 case SYS_DVBC_ANNEX_C:
6227 if (!state->m_hasDVBC)
6228 return -EINVAL;
6229 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6230 if (state->m_itut_annex_c)
6231 SetOperationMode(state, OM_QAM_ITU_C);
6232 else
6233 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006234 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006235 case SYS_DVBT:
6236 if (!state->m_hasDVBT)
6237 return -EINVAL;
6238 SetOperationMode(state, OM_DVBT);
6239 break;
6240 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006241 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006242 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006243 }
6244
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006245 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006246 Start(state, 0, IF);
6247
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006248 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006249
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 return 0;
6251}
6252
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6254{
6255 struct drxk_state *state = fe->demodulator_priv;
6256 u32 stat;
6257
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006258 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006260 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006261 if (stat == MPEG_LOCK)
6262 *status |= 0x1f;
6263 if (stat == FEC_LOCK)
6264 *status |= 0x0f;
6265 if (stat == DEMOD_LOCK)
6266 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267 return 0;
6268}
6269
6270static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6271{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006272 dprintk(1, "\n");
6273
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 return 0;
6276}
6277
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278static int drxk_read_signal_strength(struct dvb_frontend *fe,
6279 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280{
6281 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006282 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006284 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006285 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006286 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006287 return 0;
6288}
6289
6290static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6291{
6292 struct drxk_state *state = fe->demodulator_priv;
6293 s32 snr2;
6294
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006295 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006296 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006297 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006298 return 0;
6299}
6300
6301static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6302{
6303 struct drxk_state *state = fe->demodulator_priv;
6304 u16 err;
6305
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006306 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006307 DVBTQAMGetAccPktErr(state, &err);
6308 *ucblocks = (u32) err;
6309 return 0;
6310}
6311
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006312static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006313 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006314{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006315 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006316
6317 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006318 switch (p->delivery_system) {
6319 case SYS_DVBC_ANNEX_A:
6320 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006321 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006322 sets->min_delay_ms = 3000;
6323 sets->max_drift = 0;
6324 sets->step_size = 0;
6325 return 0;
6326 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006327 return -EINVAL;
6328 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006329}
6330
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006331static struct dvb_frontend_ops drxk_ops = {
6332 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006333 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006334 .name = "DRXK",
6335 .frequency_min = 47000000,
6336 .frequency_max = 865000000,
6337 /* For DVB-C */
6338 .symbol_rate_min = 870000,
6339 .symbol_rate_max = 11700000,
6340 /* For DVB-T */
6341 .frequency_stepsize = 166667,
6342
6343 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6344 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6345 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6346 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6347 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6348 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6349 },
6350
6351 .release = drxk_release,
6352 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006353 .i2c_gate_ctrl = drxk_gate_ctrl,
6354
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006355 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006356 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006357
6358 .read_status = drxk_read_status,
6359 .read_ber = drxk_read_ber,
6360 .read_signal_strength = drxk_read_signal_strength,
6361 .read_snr = drxk_read_snr,
6362 .read_ucblocks = drxk_read_ucblocks,
6363};
6364
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006365struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006366 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006367{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006368 int n;
6369
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006370 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006371 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006372
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006373 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006374 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006375 if (!state)
6376 return NULL;
6377
Oliver Endrissebc7de22011-07-03 13:49:44 -03006378 state->i2c = i2c;
6379 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006380 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006381 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006382 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006383 state->antenna_gpio = config->antenna_gpio;
6384 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006385 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006386 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006387
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006388 if (config->dynamic_clk) {
6389 state->m_DVBTStaticCLK = 0;
6390 state->m_DVBCStaticCLK = 0;
6391 } else {
6392 state->m_DVBTStaticCLK = 1;
6393 state->m_DVBCStaticCLK = 1;
6394 }
6395
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006396
6397 if (config->mpeg_out_clk_strength)
6398 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6399 else
6400 state->m_TSClockkStrength = 0x06;
6401
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006402 if (config->parallel_ts)
6403 state->m_enableParallel = true;
6404 else
6405 state->m_enableParallel = false;
6406
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006407 /* NOTE: as more UIO bits will be used, add them to the mask */
6408 state->UIO_mask = config->antenna_gpio;
6409
6410 /* Default gpio to DVB-C */
6411 if (!state->antenna_dvbt && state->antenna_gpio)
6412 state->m_GPIO |= state->antenna_gpio;
6413 else
6414 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006415
6416 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006417
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006418 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6419 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006420
6421 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006422 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006423 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006424
6425 /* Initialize the supported delivery systems */
6426 n = 0;
6427 if (state->m_hasDVBC) {
6428 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6429 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6430 strlcat(state->frontend.ops.info.name, " DVB-C",
6431 sizeof(state->frontend.ops.info.name));
6432 }
6433 if (state->m_hasDVBT) {
6434 state->frontend.ops.delsys[n++] = SYS_DVBT;
6435 strlcat(state->frontend.ops.info.name, " DVB-T",
6436 sizeof(state->frontend.ops.info.name));
6437 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006438
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006439 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006440 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006441
6442error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006443 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006444 kfree(state);
6445 return NULL;
6446}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006447EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006448
6449MODULE_DESCRIPTION("DRX-K driver");
6450MODULE_AUTHOR("Ralph Metzler");
6451MODULE_LICENSE("GPL");