blob: 47bf16d44bc41f199601c470f54df0e0f383c37e [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)) ||
1523 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001524 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525
1526 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001527
1528 /* assume that the command register is ready
1529 since it is checked afterwards */
1530 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1531 buffer[cnt++] = (parameter[ii] & 0xFF);
1532 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1533 }
1534 buffer[cnt++] = (cmd & 0xFF);
1535 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1536
1537 write_block(state, SCU_RAM_PARAM_0__A -
1538 (parameterLen - 1), cnt, buffer);
1539 /* Wait until SCU has processed command */
1540 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001541 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001542 msleep(1);
1543 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1544 if (status < 0)
1545 goto error;
1546 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1547 if (curCmd != DRX_SCU_READY) {
1548 printk(KERN_ERR "drxk: SCU not ready\n");
1549 status = -EIO;
1550 goto error2;
1551 }
1552 /* read results */
1553 if ((resultLen > 0) && (result != NULL)) {
1554 s16 err;
1555 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001556
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001557 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1558 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001559 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001560 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001561 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001563 /* Check if an error was reported by SCU */
1564 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001565 if (err >= 0)
1566 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001568 /* check for the known error codes */
1569 switch (err) {
1570 case SCU_RESULT_UNKCMD:
1571 p = "SCU_RESULT_UNKCMD";
1572 break;
1573 case SCU_RESULT_UNKSTD:
1574 p = "SCU_RESULT_UNKSTD";
1575 break;
1576 case SCU_RESULT_SIZE:
1577 p = "SCU_RESULT_SIZE";
1578 break;
1579 case SCU_RESULT_INVPAR:
1580 p = "SCU_RESULT_INVPAR";
1581 break;
1582 default: /* Other negative values are errors */
1583 sprintf(errname, "ERROR: %d\n", err);
1584 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001585 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001586 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1587 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1588 status = -EINVAL;
1589 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001590 }
1591
1592error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001593 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001594 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595error2:
1596 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001597 return status;
1598}
1599
1600static int SetIqmAf(struct drxk_state *state, bool active)
1601{
1602 u16 data = 0;
1603 int status;
1604
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001605 dprintk(1, "\n");
1606
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001607 /* Configure IQM */
1608 status = read16(state, IQM_AF_STDBY__A, &data);
1609 if (status < 0)
1610 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001611
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001612 if (!active) {
1613 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1614 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1615 | IQM_AF_STDBY_STDBY_PD_STANDBY
1616 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1617 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1618 } else {
1619 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1620 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1621 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1622 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1624 );
1625 }
1626 status = write16(state, IQM_AF_STDBY__A, data);
1627
1628error:
1629 if (status < 0)
1630 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001631 return status;
1632}
1633
Oliver Endrissebc7de22011-07-03 13:49:44 -03001634static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001635{
1636 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001637 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001638
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001639 dprintk(1, "\n");
1640
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001641 /* Check arguments */
1642 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001643 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644
1645 switch (*mode) {
1646 case DRX_POWER_UP:
1647 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1648 break;
1649 case DRXK_POWER_DOWN_OFDM:
1650 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1651 break;
1652 case DRXK_POWER_DOWN_CORE:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1654 break;
1655 case DRXK_POWER_DOWN_PLL:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1657 break;
1658 case DRX_POWER_DOWN:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1660 break;
1661 default:
1662 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001663 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001664 }
1665
1666 /* If already in requested power mode, do nothing */
1667 if (state->m_currentPowerMode == *mode)
1668 return 0;
1669
1670 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001671 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001672 status = PowerUpDevice(state);
1673 if (status < 0)
1674 goto error;
1675 status = DVBTEnableOFDMTokenRing(state, true);
1676 if (status < 0)
1677 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001678 }
1679
1680 if (*mode == DRX_POWER_UP) {
1681 /* Restore analog & pin configuartion */
1682 } else {
1683 /* Power down to requested mode */
1684 /* Backup some register settings */
1685 /* Set pins with possible pull-ups connected
1686 to them in input mode */
1687 /* Analog power down */
1688 /* ADC power down */
1689 /* Power down device */
1690 /* stop all comm_exec */
1691 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001692 switch (state->m_OperationMode) {
1693 case OM_DVBT:
1694 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001695 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001696 goto error;
1697 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001698 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001699 goto error;
1700 break;
1701 case OM_QAM_ITU_A:
1702 case OM_QAM_ITU_C:
1703 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001704 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001705 goto error;
1706 status = PowerDownQAM(state);
1707 if (status < 0)
1708 goto error;
1709 break;
1710 default:
1711 break;
1712 }
1713 status = DVBTEnableOFDMTokenRing(state, false);
1714 if (status < 0)
1715 goto error;
1716 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1717 if (status < 0)
1718 goto error;
1719 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1720 if (status < 0)
1721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001723 if (*mode != DRXK_POWER_DOWN_OFDM) {
1724 state->m_HICfgCtrl |=
1725 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1726 status = HI_CfgCommand(state);
1727 if (status < 0)
1728 goto error;
1729 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001730 }
1731 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001732
1733error:
1734 if (status < 0)
1735 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1736
Oliver Endrissebc7de22011-07-03 13:49:44 -03001737 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001738}
1739
1740static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1741{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001742 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001743 u16 cmdResult = 0;
1744 u16 data = 0;
1745 int status;
1746
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001747 dprintk(1, "\n");
1748
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001749 status = read16(state, SCU_COMM_EXEC__A, &data);
1750 if (status < 0)
1751 goto error;
1752 if (data == SCU_COMM_EXEC_ACTIVE) {
1753 /* Send OFDM stop command */
1754 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 -03001755 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001756 goto error;
1757 /* Send OFDM reset command */
1758 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1759 if (status < 0)
1760 goto error;
1761 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001762
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001763 /* Reset datapath for OFDM, processors first */
1764 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1765 if (status < 0)
1766 goto error;
1767 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1768 if (status < 0)
1769 goto error;
1770 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1771 if (status < 0)
1772 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001774 /* powerdown AFE */
1775 status = SetIqmAf(state, false);
1776 if (status < 0)
1777 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001778
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001779 /* powerdown to OFDM mode */
1780 if (setPowerMode) {
1781 status = CtrlPowerMode(state, &powerMode);
1782 if (status < 0)
1783 goto error;
1784 }
1785error:
1786 if (status < 0)
1787 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001788 return status;
1789}
1790
Oliver Endrissebc7de22011-07-03 13:49:44 -03001791static int SetOperationMode(struct drxk_state *state,
1792 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001793{
1794 int status = 0;
1795
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001796 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001797 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001798 Stop and power down previous standard
1799 TODO investigate total power down instead of partial
1800 power down depending on "previous" standard.
1801 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001803 /* disable HW lock indicator */
1804 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1805 if (status < 0)
1806 goto error;
1807
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001808 /* Device is already at the required mode */
1809 if (state->m_OperationMode == oMode)
1810 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001811
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001812 switch (state->m_OperationMode) {
1813 /* OM_NONE was added for start up */
1814 case OM_NONE:
1815 break;
1816 case OM_DVBT:
1817 status = MPEGTSStop(state);
1818 if (status < 0)
1819 goto error;
1820 status = PowerDownDVBT(state, true);
1821 if (status < 0)
1822 goto error;
1823 state->m_OperationMode = OM_NONE;
1824 break;
1825 case OM_QAM_ITU_A: /* fallthrough */
1826 case OM_QAM_ITU_C:
1827 status = MPEGTSStop(state);
1828 if (status < 0)
1829 goto error;
1830 status = PowerDownQAM(state);
1831 if (status < 0)
1832 goto error;
1833 state->m_OperationMode = OM_NONE;
1834 break;
1835 case OM_QAM_ITU_B:
1836 default:
1837 status = -EINVAL;
1838 goto error;
1839 }
1840
1841 /*
1842 Power up new standard
1843 */
1844 switch (oMode) {
1845 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001846 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001847 state->m_OperationMode = oMode;
1848 status = SetDVBTStandard(state, oMode);
1849 if (status < 0)
1850 goto error;
1851 break;
1852 case OM_QAM_ITU_A: /* fallthrough */
1853 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001854 dprintk(1, ": DVB-C Annex %c\n",
1855 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001856 state->m_OperationMode = oMode;
1857 status = SetQAMStandard(state, oMode);
1858 if (status < 0)
1859 goto error;
1860 break;
1861 case OM_QAM_ITU_B:
1862 default:
1863 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001864 }
1865error:
1866 if (status < 0)
1867 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1868 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001869}
1870
1871static int Start(struct drxk_state *state, s32 offsetFreq,
1872 s32 IntermediateFrequency)
1873{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001874 int status = -EINVAL;
1875
1876 u16 IFreqkHz;
1877 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001879 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001880 if (state->m_DrxkState != DRXK_STOPPED &&
1881 state->m_DrxkState != DRXK_DTV_STARTED)
1882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001883
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001884 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001885
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886 if (IntermediateFrequency < 0) {
1887 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1888 IntermediateFrequency = -IntermediateFrequency;
1889 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001891 switch (state->m_OperationMode) {
1892 case OM_QAM_ITU_A:
1893 case OM_QAM_ITU_C:
1894 IFreqkHz = (IntermediateFrequency / 1000);
1895 status = SetQAM(state, IFreqkHz, OffsetkHz);
1896 if (status < 0)
1897 goto error;
1898 state->m_DrxkState = DRXK_DTV_STARTED;
1899 break;
1900 case OM_DVBT:
1901 IFreqkHz = (IntermediateFrequency / 1000);
1902 status = MPEGTSStop(state);
1903 if (status < 0)
1904 goto error;
1905 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1906 if (status < 0)
1907 goto error;
1908 status = DVBTStart(state);
1909 if (status < 0)
1910 goto error;
1911 state->m_DrxkState = DRXK_DTV_STARTED;
1912 break;
1913 default:
1914 break;
1915 }
1916error:
1917 if (status < 0)
1918 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001919 return status;
1920}
1921
1922static int ShutDown(struct drxk_state *state)
1923{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001924 dprintk(1, "\n");
1925
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001926 MPEGTSStop(state);
1927 return 0;
1928}
1929
Oliver Endrissebc7de22011-07-03 13:49:44 -03001930static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1931 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001932{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001933 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001935 dprintk(1, "\n");
1936
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001938 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939
1940 *pLockStatus = NOT_LOCKED;
1941
1942 /* define the SCU command code */
1943 switch (state->m_OperationMode) {
1944 case OM_QAM_ITU_A:
1945 case OM_QAM_ITU_B:
1946 case OM_QAM_ITU_C:
1947 status = GetQAMLockStatus(state, pLockStatus);
1948 break;
1949 case OM_DVBT:
1950 status = GetDVBTLockStatus(state, pLockStatus);
1951 break;
1952 default:
1953 break;
1954 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001955error:
1956 if (status < 0)
1957 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001958 return status;
1959}
1960
1961static int MPEGTSStart(struct drxk_state *state)
1962{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001964
1965 u16 fecOcSncMode = 0;
1966
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001967 /* Allow OC to sync again */
1968 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1969 if (status < 0)
1970 goto error;
1971 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1972 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1973 if (status < 0)
1974 goto error;
1975 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1976error:
1977 if (status < 0)
1978 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001979 return status;
1980}
1981
1982static int MPEGTSDtoInit(struct drxk_state *state)
1983{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001984 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001985
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001986 dprintk(1, "\n");
1987
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001988 /* Rate integration settings */
1989 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1990 if (status < 0)
1991 goto error;
1992 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1993 if (status < 0)
1994 goto error;
1995 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1996 if (status < 0)
1997 goto error;
1998 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1999 if (status < 0)
2000 goto error;
2001 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2002 if (status < 0)
2003 goto error;
2004 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2005 if (status < 0)
2006 goto error;
2007 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2011 if (status < 0)
2012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002014 /* Additional configuration */
2015 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2016 if (status < 0)
2017 goto error;
2018 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2019 if (status < 0)
2020 goto error;
2021 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2022error:
2023 if (status < 0)
2024 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2025
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002026 return status;
2027}
2028
Oliver Endrissebc7de22011-07-03 13:49:44 -03002029static int MPEGTSDtoSetup(struct drxk_state *state,
2030 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002031{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002032 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002033
Oliver Endrissebc7de22011-07-03 13:49:44 -03002034 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2035 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2036 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2037 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2038 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2039 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2040 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041 u16 fecOcTmdMode = 0;
2042 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002043 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044 bool staticCLK = false;
2045
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002046 dprintk(1, "\n");
2047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002048 /* Check insertion of the Reed-Solomon parity bytes */
2049 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2050 if (status < 0)
2051 goto error;
2052 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2053 if (status < 0)
2054 goto error;
2055 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2056 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2057 if (state->m_insertRSByte == true) {
2058 /* enable parity symbol forward */
2059 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2060 /* MVAL disable during parity bytes */
2061 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2062 /* TS burst length to 204 */
2063 fecOcDtoBurstLen = 204;
2064 }
2065
2066 /* Check serial or parrallel output */
2067 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2068 if (state->m_enableParallel == false) {
2069 /* MPEG data output is serial -> set ipr_mode[0] */
2070 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2071 }
2072
2073 switch (oMode) {
2074 case OM_DVBT:
2075 maxBitRate = state->m_DVBTBitrate;
2076 fecOcTmdMode = 3;
2077 fecOcRcnCtlRate = 0xC00000;
2078 staticCLK = state->m_DVBTStaticCLK;
2079 break;
2080 case OM_QAM_ITU_A: /* fallthrough */
2081 case OM_QAM_ITU_C:
2082 fecOcTmdMode = 0x0004;
2083 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2084 maxBitRate = state->m_DVBCBitrate;
2085 staticCLK = state->m_DVBCStaticCLK;
2086 break;
2087 default:
2088 status = -EINVAL;
2089 } /* switch (standard) */
2090 if (status < 0)
2091 goto error;
2092
2093 /* Configure DTO's */
2094 if (staticCLK) {
2095 u32 bitRate = 0;
2096
2097 /* Rational DTO for MCLK source (static MCLK rate),
2098 Dynamic DTO for optimal grouping
2099 (avoid intra-packet gaps),
2100 DTO offset enable to sync TS burst with MSTRT */
2101 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2102 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2103 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2104 FEC_OC_FCT_MODE_VIRT_ENA__M);
2105
2106 /* Check user defined bitrate */
2107 bitRate = maxBitRate;
2108 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2109 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002110 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002111 /* Rational DTO period:
2112 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002114 Result should be floored,
2115 to make sure >= requested bitrate
2116 */
2117 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2118 * 1000) / bitRate);
2119 if (fecOcDtoPeriod <= 2)
2120 fecOcDtoPeriod = 0;
2121 else
2122 fecOcDtoPeriod -= 2;
2123 fecOcTmdIntUpdRate = 8;
2124 } else {
2125 /* (commonAttr->staticCLK == false) => dynamic mode */
2126 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2127 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2128 fecOcTmdIntUpdRate = 5;
2129 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002131 /* Write appropriate registers with requested configuration */
2132 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2133 if (status < 0)
2134 goto error;
2135 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2136 if (status < 0)
2137 goto error;
2138 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2139 if (status < 0)
2140 goto error;
2141 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2142 if (status < 0)
2143 goto error;
2144 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2148 if (status < 0)
2149 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002150
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002151 /* Rate integration settings */
2152 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2153 if (status < 0)
2154 goto error;
2155 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2156 if (status < 0)
2157 goto error;
2158 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2159error:
2160 if (status < 0)
2161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002162 return status;
2163}
2164
2165static int MPEGTSConfigurePolarity(struct drxk_state *state)
2166{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002167 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002168
2169 /* Data mask for the output data byte */
2170 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002171 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2172 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2173 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2174 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002176 dprintk(1, "\n");
2177
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002178 /* Control selective inversion of output bits */
2179 fecOcRegIprInvert &= (~(InvertDataMask));
2180 if (state->m_invertDATA == true)
2181 fecOcRegIprInvert |= InvertDataMask;
2182 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2183 if (state->m_invertERR == true)
2184 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2185 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2186 if (state->m_invertSTR == true)
2187 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2188 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2189 if (state->m_invertVAL == true)
2190 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2191 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2192 if (state->m_invertCLK == true)
2193 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002194
2195 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002196}
2197
2198#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2199
2200static int SetAgcRf(struct drxk_state *state,
2201 struct SCfgAgc *pAgcCfg, bool isDTV)
2202{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002203 int status = -EINVAL;
2204 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002205 struct SCfgAgc *pIfAgcSettings;
2206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002207 dprintk(1, "\n");
2208
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002210 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002212 switch (pAgcCfg->ctrlMode) {
2213 case DRXK_AGC_CTRL_AUTO:
2214 /* Enable RF AGC DAC */
2215 status = read16(state, IQM_AF_STDBY__A, &data);
2216 if (status < 0)
2217 goto error;
2218 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2219 status = write16(state, IQM_AF_STDBY__A, data);
2220 if (status < 0)
2221 goto error;
2222 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2223 if (status < 0)
2224 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002225
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002226 /* Enable SCU RF AGC loop */
2227 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002229 /* Polarity */
2230 if (state->m_RfAgcPol)
2231 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2232 else
2233 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2234 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2235 if (status < 0)
2236 goto error;
2237
2238 /* Set speed (using complementary reduction value) */
2239 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2240 if (status < 0)
2241 goto error;
2242
2243 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2244 data |= (~(pAgcCfg->speed <<
2245 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2246 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2247
2248 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2249 if (status < 0)
2250 goto error;
2251
2252 if (IsDVBT(state))
2253 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2254 else if (IsQAM(state))
2255 pIfAgcSettings = &state->m_qamIfAgcCfg;
2256 else
2257 pIfAgcSettings = &state->m_atvIfAgcCfg;
2258 if (pIfAgcSettings == NULL) {
2259 status = -EINVAL;
2260 goto error;
2261 }
2262
2263 /* Set TOP, only if IF-AGC is in AUTO mode */
2264 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2265 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002266 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002267 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 /* Cut-Off current */
2270 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2271 if (status < 0)
2272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002274 /* Max. output level */
2275 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2276 if (status < 0)
2277 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002281 case DRXK_AGC_CTRL_USER:
2282 /* Enable RF AGC DAC */
2283 status = read16(state, IQM_AF_STDBY__A, &data);
2284 if (status < 0)
2285 goto error;
2286 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2287 status = write16(state, IQM_AF_STDBY__A, data);
2288 if (status < 0)
2289 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002290
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002291 /* Disable SCU RF AGC loop */
2292 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2293 if (status < 0)
2294 goto error;
2295 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2296 if (state->m_RfAgcPol)
2297 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2298 else
2299 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2300 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2301 if (status < 0)
2302 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002303
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002304 /* SCU c.o.c. to 0, enabling full control range */
2305 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2306 if (status < 0)
2307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002309 /* Write value to output pin */
2310 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2311 if (status < 0)
2312 goto error;
2313 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002314
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002315 case DRXK_AGC_CTRL_OFF:
2316 /* Disable RF AGC DAC */
2317 status = read16(state, IQM_AF_STDBY__A, &data);
2318 if (status < 0)
2319 goto error;
2320 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2321 status = write16(state, IQM_AF_STDBY__A, data);
2322 if (status < 0)
2323 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002324
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002325 /* Disable SCU RF AGC loop */
2326 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2327 if (status < 0)
2328 goto error;
2329 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2330 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2331 if (status < 0)
2332 goto error;
2333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002335 default:
2336 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002337
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002338 }
2339error:
2340 if (status < 0)
2341 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342 return status;
2343}
2344
2345#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2346
Oliver Endrissebc7de22011-07-03 13:49:44 -03002347static int SetAgcIf(struct drxk_state *state,
2348 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002349{
2350 u16 data = 0;
2351 int status = 0;
2352 struct SCfgAgc *pRfAgcSettings;
2353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002354 dprintk(1, "\n");
2355
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002356 switch (pAgcCfg->ctrlMode) {
2357 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002358
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002359 /* Enable IF AGC DAC */
2360 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002361 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002362 goto error;
2363 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2364 status = write16(state, IQM_AF_STDBY__A, data);
2365 if (status < 0)
2366 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002367
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002368 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2369 if (status < 0)
2370 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002371
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002372 /* Enable SCU IF AGC loop */
2373 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2374
2375 /* Polarity */
2376 if (state->m_IfAgcPol)
2377 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2378 else
2379 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2380 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 /* Set speed (using complementary reduction value) */
2385 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2386 if (status < 0)
2387 goto error;
2388 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2389 data |= (~(pAgcCfg->speed <<
2390 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2391 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2392
2393 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2394 if (status < 0)
2395 goto error;
2396
2397 if (IsQAM(state))
2398 pRfAgcSettings = &state->m_qamRfAgcCfg;
2399 else
2400 pRfAgcSettings = &state->m_atvRfAgcCfg;
2401 if (pRfAgcSettings == NULL)
2402 return -1;
2403 /* Restore TOP */
2404 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2405 if (status < 0)
2406 goto error;
2407 break;
2408
2409 case DRXK_AGC_CTRL_USER:
2410
2411 /* Enable IF AGC DAC */
2412 status = read16(state, IQM_AF_STDBY__A, &data);
2413 if (status < 0)
2414 goto error;
2415 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2416 status = write16(state, IQM_AF_STDBY__A, data);
2417 if (status < 0)
2418 goto error;
2419
2420 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2421 if (status < 0)
2422 goto error;
2423
2424 /* Disable SCU IF AGC loop */
2425 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2426
2427 /* Polarity */
2428 if (state->m_IfAgcPol)
2429 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2430 else
2431 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2432 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2433 if (status < 0)
2434 goto error;
2435
2436 /* Write value to output pin */
2437 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2438 if (status < 0)
2439 goto error;
2440 break;
2441
2442 case DRXK_AGC_CTRL_OFF:
2443
2444 /* Disable If AGC DAC */
2445 status = read16(state, IQM_AF_STDBY__A, &data);
2446 if (status < 0)
2447 goto error;
2448 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2449 status = write16(state, IQM_AF_STDBY__A, data);
2450 if (status < 0)
2451 goto error;
2452
2453 /* Disable SCU IF AGC loop */
2454 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2455 if (status < 0)
2456 goto error;
2457 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2458 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2459 if (status < 0)
2460 goto error;
2461 break;
2462 } /* switch (agcSettingsIf->ctrlMode) */
2463
2464 /* always set the top to support
2465 configurations without if-loop */
2466 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2467error:
2468 if (status < 0)
2469 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470 return status;
2471}
2472
2473static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2474{
2475 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002476 int status;
2477 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002479 dprintk(1, "\n");
2480
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002481 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2482 if (status < 0) {
2483 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2484 return status;
2485 }
2486
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002487 *pValue = 0;
2488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002489 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2490 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2491 if (Level < 14000)
2492 *pValue = (14000 - Level) / 4;
2493 else
2494 *pValue = 0;
2495
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002496 return status;
2497}
2498
Oliver Endrissebc7de22011-07-03 13:49:44 -03002499static int GetQAMSignalToNoise(struct drxk_state *state,
2500 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501{
2502 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002503 u16 qamSlErrPower = 0; /* accum. error between
2504 raw and sliced symbols */
2505 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002506 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002508
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002509 dprintk(1, "\n");
2510
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002513 /* get the register value needed for MER */
2514 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2515 if (status < 0) {
2516 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2517 return -EINVAL;
2518 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002519
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002520 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002521 case QAM_16:
2522 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2523 break;
2524 case QAM_32:
2525 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2526 break;
2527 case QAM_64:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2529 break;
2530 case QAM_128:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2532 break;
2533 default:
2534 case QAM_256:
2535 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2536 break;
2537 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002539 if (qamSlErrPower > 0) {
2540 qamSlMer = Log10Times100(qamSlSigPower) -
2541 Log10Times100((u32) qamSlErrPower);
2542 }
2543 *pSignalToNoise = qamSlMer;
2544
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545 return status;
2546}
2547
Oliver Endrissebc7de22011-07-03 13:49:44 -03002548static int GetDVBTSignalToNoise(struct drxk_state *state,
2549 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002550{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002551 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002552 u16 regData = 0;
2553 u32 EqRegTdSqrErrI = 0;
2554 u32 EqRegTdSqrErrQ = 0;
2555 u16 EqRegTdSqrErrExp = 0;
2556 u16 EqRegTdTpsPwrOfs = 0;
2557 u16 EqRegTdReqSmbCnt = 0;
2558 u32 tpsCnt = 0;
2559 u32 SqrErrIQ = 0;
2560 u32 a = 0;
2561 u32 b = 0;
2562 u32 c = 0;
2563 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002564 u16 transmissionParams = 0;
2565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002566 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002567
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002568 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2569 if (status < 0)
2570 goto error;
2571 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2572 if (status < 0)
2573 goto error;
2574 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2575 if (status < 0)
2576 goto error;
2577 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2578 if (status < 0)
2579 goto error;
2580 /* Extend SQR_ERR_I operational range */
2581 EqRegTdSqrErrI = (u32) regData;
2582 if ((EqRegTdSqrErrExp > 11) &&
2583 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2584 EqRegTdSqrErrI += 0x00010000UL;
2585 }
2586 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2587 if (status < 0)
2588 goto error;
2589 /* Extend SQR_ERR_Q operational range */
2590 EqRegTdSqrErrQ = (u32) regData;
2591 if ((EqRegTdSqrErrExp > 11) &&
2592 (EqRegTdSqrErrQ < 0x00000FFFUL))
2593 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002595 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2596 if (status < 0)
2597 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002599 /* Check input data for MER */
2600
2601 /* MER calculation (in 0.1 dB) without math.h */
2602 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2603 iMER = 0;
2604 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2605 /* No error at all, this must be the HW reset value
2606 * Apparently no first measurement yet
2607 * Set MER to 0.0 */
2608 iMER = 0;
2609 } else {
2610 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2611 EqRegTdSqrErrExp;
2612 if ((transmissionParams &
2613 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2614 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2615 tpsCnt = 17;
2616 else
2617 tpsCnt = 68;
2618
2619 /* IMER = 100 * log10 (x)
2620 where x = (EqRegTdTpsPwrOfs^2 *
2621 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2622
2623 => IMER = a + b -c
2624 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2625 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2626 c = 100 * log10 (SqrErrIQ)
2627 */
2628
2629 /* log(x) x = 9bits * 9bits->18 bits */
2630 a = Log10Times100(EqRegTdTpsPwrOfs *
2631 EqRegTdTpsPwrOfs);
2632 /* log(x) x = 16bits * 7bits->23 bits */
2633 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2634 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2635 c = Log10Times100(SqrErrIQ);
2636
2637 iMER = a + b;
2638 /* No negative MER, clip to zero */
2639 if (iMER > c)
2640 iMER -= c;
2641 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002642 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002643 }
2644 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002646error:
2647 if (status < 0)
2648 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002649 return status;
2650}
2651
2652static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2653{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002654 dprintk(1, "\n");
2655
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002656 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002657 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658 case OM_DVBT:
2659 return GetDVBTSignalToNoise(state, pSignalToNoise);
2660 case OM_QAM_ITU_A:
2661 case OM_QAM_ITU_C:
2662 return GetQAMSignalToNoise(state, pSignalToNoise);
2663 default:
2664 break;
2665 }
2666 return 0;
2667}
2668
2669#if 0
2670static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2671{
2672 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2673 int status = 0;
2674
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002675 dprintk(1, "\n");
2676
Oliver Endrissebc7de22011-07-03 13:49:44 -03002677 static s32 QE_SN[] = {
2678 51, /* QPSK 1/2 */
2679 69, /* QPSK 2/3 */
2680 79, /* QPSK 3/4 */
2681 89, /* QPSK 5/6 */
2682 97, /* QPSK 7/8 */
2683 108, /* 16-QAM 1/2 */
2684 131, /* 16-QAM 2/3 */
2685 146, /* 16-QAM 3/4 */
2686 156, /* 16-QAM 5/6 */
2687 160, /* 16-QAM 7/8 */
2688 165, /* 64-QAM 1/2 */
2689 187, /* 64-QAM 2/3 */
2690 202, /* 64-QAM 3/4 */
2691 216, /* 64-QAM 5/6 */
2692 225, /* 64-QAM 7/8 */
2693 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002694
2695 *pQuality = 0;
2696
2697 do {
2698 s32 SignalToNoise = 0;
2699 u16 Constellation = 0;
2700 u16 CodeRate = 0;
2701 u32 SignalToNoiseRel;
2702 u32 BERQuality;
2703
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002704 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2705 if (status < 0)
2706 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002707 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002708 if (status < 0)
2709 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002710 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2711
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002712 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002713 if (status < 0)
2714 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2716
2717 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2718 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2719 break;
2720 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002721 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722 BERQuality = 100;
2723
Oliver Endrissebc7de22011-07-03 13:49:44 -03002724 if (SignalToNoiseRel < -70)
2725 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002726 else if (SignalToNoiseRel < 30)
2727 *pQuality = ((SignalToNoiseRel + 70) *
2728 BERQuality) / 100;
2729 else
2730 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002731 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002732 return 0;
2733};
2734
Oliver Endrissebc7de22011-07-03 13:49:44 -03002735static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002736{
2737 int status = 0;
2738 *pQuality = 0;
2739
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002740 dprintk(1, "\n");
2741
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742 do {
2743 u32 SignalToNoise = 0;
2744 u32 BERQuality = 100;
2745 u32 SignalToNoiseRel = 0;
2746
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002747 status = GetQAMSignalToNoise(state, &SignalToNoise);
2748 if (status < 0)
2749 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002751 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752 case QAM_16:
2753 SignalToNoiseRel = SignalToNoise - 200;
2754 break;
2755 case QAM_32:
2756 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002757 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002758 case QAM_64:
2759 SignalToNoiseRel = SignalToNoise - 260;
2760 break;
2761 case QAM_128:
2762 SignalToNoiseRel = SignalToNoise - 290;
2763 break;
2764 default:
2765 case QAM_256:
2766 SignalToNoiseRel = SignalToNoise - 320;
2767 break;
2768 }
2769
2770 if (SignalToNoiseRel < -70)
2771 *pQuality = 0;
2772 else if (SignalToNoiseRel < 30)
2773 *pQuality = ((SignalToNoiseRel + 70) *
2774 BERQuality) / 100;
2775 else
2776 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002777 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002778
2779 return status;
2780}
2781
2782static int GetQuality(struct drxk_state *state, s32 *pQuality)
2783{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002784 dprintk(1, "\n");
2785
Oliver Endrissebc7de22011-07-03 13:49:44 -03002786 switch (state->m_OperationMode) {
2787 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002788 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002789 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002790 return GetDVBCQuality(state, pQuality);
2791 default:
2792 break;
2793 }
2794
2795 return 0;
2796}
2797#endif
2798
2799/* Free data ram in SIO HI */
2800#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2801#define SIO_HI_RA_RAM_USR_END__A 0x420060
2802
2803#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2804#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2805#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2806#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2807
2808#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2809#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2810#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2811
2812static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2813{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002814 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002815
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002816 dprintk(1, "\n");
2817
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002818 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002820 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002822
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002823 if (state->no_i2c_bridge)
2824 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002826 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2827 if (status < 0)
2828 goto error;
2829 if (bEnableBridge) {
2830 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 -03002831 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002832 goto error;
2833 } else {
2834 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2835 if (status < 0)
2836 goto error;
2837 }
2838
2839 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2840
2841error:
2842 if (status < 0)
2843 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002844 return status;
2845}
2846
Oliver Endrissebc7de22011-07-03 13:49:44 -03002847static int SetPreSaw(struct drxk_state *state,
2848 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002849{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002850 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002852 dprintk(1, "\n");
2853
Oliver Endrissebc7de22011-07-03 13:49:44 -03002854 if ((pPreSawCfg == NULL)
2855 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002856 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002858 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002859error:
2860 if (status < 0)
2861 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862 return status;
2863}
2864
2865static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002866 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002867{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002868 u16 blStatus = 0;
2869 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2870 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2871 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872 unsigned long end;
2873
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002874 dprintk(1, "\n");
2875
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002876 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002877 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2878 if (status < 0)
2879 goto error;
2880 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2881 if (status < 0)
2882 goto error;
2883 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2884 if (status < 0)
2885 goto error;
2886 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2887 if (status < 0)
2888 goto error;
2889 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2890 if (status < 0)
2891 goto error;
2892 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2893 if (status < 0)
2894 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002895
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002896 end = jiffies + msecs_to_jiffies(timeOut);
2897 do {
2898 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2899 if (status < 0)
2900 goto error;
2901 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2902 if (blStatus == 0x1) {
2903 printk(KERN_ERR "drxk: SIO not ready\n");
2904 status = -EINVAL;
2905 goto error2;
2906 }
2907error:
2908 if (status < 0)
2909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2910error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002911 mutex_unlock(&state->mutex);
2912 return status;
2913
2914}
2915
Oliver Endrissebc7de22011-07-03 13:49:44 -03002916static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917{
2918 u16 data = 0;
2919 int status;
2920
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002921 dprintk(1, "\n");
2922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002923 /* Start measurement */
2924 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2925 if (status < 0)
2926 goto error;
2927 status = write16(state, IQM_AF_START_LOCK__A, 1);
2928 if (status < 0)
2929 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002931 *count = 0;
2932 status = read16(state, IQM_AF_PHASE0__A, &data);
2933 if (status < 0)
2934 goto error;
2935 if (data == 127)
2936 *count = *count + 1;
2937 status = read16(state, IQM_AF_PHASE1__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942 status = read16(state, IQM_AF_PHASE2__A, &data);
2943 if (status < 0)
2944 goto error;
2945 if (data == 127)
2946 *count = *count + 1;
2947
2948error:
2949 if (status < 0)
2950 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002951 return status;
2952}
2953
2954static int ADCSynchronization(struct drxk_state *state)
2955{
2956 u16 count = 0;
2957 int status;
2958
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002959 dprintk(1, "\n");
2960
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002961 status = ADCSyncMeasurement(state, &count);
2962 if (status < 0)
2963 goto error;
2964
2965 if (count == 1) {
2966 /* Try sampling on a diffrent edge */
2967 u16 clkNeg = 0;
2968
2969 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2970 if (status < 0)
2971 goto error;
2972 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2973 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2974 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2975 clkNeg |=
2976 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2977 } else {
2978 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2979 clkNeg |=
2980 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2981 }
2982 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2983 if (status < 0)
2984 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002985 status = ADCSyncMeasurement(state, &count);
2986 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002987 goto error;
2988 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002990 if (count < 2)
2991 status = -EINVAL;
2992error:
2993 if (status < 0)
2994 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002995 return status;
2996}
2997
2998static int SetFrequencyShifter(struct drxk_state *state,
2999 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003000 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003001{
3002 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003003 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004 u32 fmFrequencyShift = 0;
3005 bool tunerMirror = !state->m_bMirrorFreqSpect;
3006 u32 adcFreq;
3007 bool adcFlip;
3008 int status;
3009 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003010 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003011 u32 frequencyShift;
3012 bool imageToSelect;
3013
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003014 dprintk(1, "\n");
3015
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003017 Program frequency shifter
3018 No need to account for mirroring on RF
3019 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 if (isDTV) {
3021 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3022 (state->m_OperationMode == OM_QAM_ITU_C) ||
3023 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003024 selectPosImage = true;
3025 else
3026 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003027 }
3028 if (tunerMirror)
3029 /* tuner doesn't mirror */
3030 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003031 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003032 else
3033 /* tuner mirrors */
3034 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 if (ifFreqActual > samplingFrequency / 2) {
3037 /* adc mirrors */
3038 adcFreq = samplingFrequency - ifFreqActual;
3039 adcFlip = true;
3040 } else {
3041 /* adc doesn't mirror */
3042 adcFreq = ifFreqActual;
3043 adcFlip = false;
3044 }
3045
3046 frequencyShift = adcFreq;
3047 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003048 adcFlip ^ selectPosImage;
3049 state->m_IqmFsRateOfs =
3050 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051
3052 if (imageToSelect)
3053 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3054
3055 /* Program frequency shifter with tuner offset compensation */
3056 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003057 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3058 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003059 if (status < 0)
3060 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003061 return status;
3062}
3063
3064static int InitAGC(struct drxk_state *state, bool isDTV)
3065{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003066 u16 ingainTgt = 0;
3067 u16 ingainTgtMin = 0;
3068 u16 ingainTgtMax = 0;
3069 u16 clpCyclen = 0;
3070 u16 clpSumMin = 0;
3071 u16 clpDirTo = 0;
3072 u16 snsSumMin = 0;
3073 u16 snsSumMax = 0;
3074 u16 clpSumMax = 0;
3075 u16 snsDirTo = 0;
3076 u16 kiInnergainMin = 0;
3077 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003078 u16 ifIaccuHiTgtMin = 0;
3079 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003080 u16 data = 0;
3081 u16 fastClpCtrlDelay = 0;
3082 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003083 int status = 0;
3084
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003085 dprintk(1, "\n");
3086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003087 /* Common settings */
3088 snsSumMax = 1023;
3089 ifIaccuHiTgtMin = 2047;
3090 clpCyclen = 500;
3091 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003092
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003093 /* AGCInit() not available for DVBT; init done in microcode */
3094 if (!IsQAM(state)) {
3095 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3096 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003097 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003098
3099 /* FIXME: Analog TV AGC require different settings */
3100
3101 /* Standard specific settings */
3102 clpSumMin = 8;
3103 clpDirTo = (u16) -9;
3104 clpCtrlMode = 0;
3105 snsSumMin = 8;
3106 snsDirTo = (u16) -9;
3107 kiInnergainMin = (u16) -1030;
3108 ifIaccuHiTgtMax = 0x2380;
3109 ifIaccuHiTgt = 0x2380;
3110 ingainTgtMin = 0x0511;
3111 ingainTgt = 0x0511;
3112 ingainTgtMax = 5119;
3113 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003115 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3116 if (status < 0)
3117 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003119 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3153 if (status < 0)
3154 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003155
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003156 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3157 if (status < 0)
3158 goto error;
3159 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3160 if (status < 0)
3161 goto error;
3162 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3163 if (status < 0)
3164 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003165
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003166 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3173 if (status < 0)
3174 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003176 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3231 if (status < 0)
3232 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003234 /* Initialize inner-loop KI gain factors */
3235 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3236 if (status < 0)
3237 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003238
3239 data = 0x0657;
3240 data &= ~SCU_RAM_AGC_KI_RF__M;
3241 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3242 data &= ~SCU_RAM_AGC_KI_IF__M;
3243 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3244
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003245 status = write16(state, SCU_RAM_AGC_KI__A, data);
3246error:
3247 if (status < 0)
3248 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003249 return status;
3250}
3251
Oliver Endrissebc7de22011-07-03 13:49:44 -03003252static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253{
3254 int status;
3255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003256 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003257 if (packetErr == NULL)
3258 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3259 else
3260 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3261 if (status < 0)
3262 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003263 return status;
3264}
3265
3266static int DVBTScCommand(struct drxk_state *state,
3267 u16 cmd, u16 subcmd,
3268 u16 param0, u16 param1, u16 param2,
3269 u16 param3, u16 param4)
3270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003271 u16 curCmd = 0;
3272 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003274 u16 scExec = 0;
3275 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003277 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003278 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 if (scExec != 1) {
3280 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003281 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003283 if (status < 0)
3284 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285
3286 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003287 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288 do {
3289 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003290 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291 retryCnt++;
3292 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003293 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3294 goto error;
3295
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 /* Write sub-command */
3297 switch (cmd) {
3298 /* All commands using sub-cmd */
3299 case OFDM_SC_RA_RAM_CMD_PROC_START:
3300 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3301 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003302 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3303 if (status < 0)
3304 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305 break;
3306 default:
3307 /* Do nothing */
3308 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003309 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310
3311 /* Write needed parameters and the command */
3312 switch (cmd) {
3313 /* All commands using 5 parameters */
3314 /* All commands using 4 parameters */
3315 /* All commands using 3 parameters */
3316 /* All commands using 2 parameters */
3317 case OFDM_SC_RA_RAM_CMD_PROC_START:
3318 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3319 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003320 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003321 /* All commands using 1 parameters */
3322 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3323 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003324 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 /* All commands using 0 parameters */
3326 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3327 case OFDM_SC_RA_RAM_CMD_NULL:
3328 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003329 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 break;
3331 default:
3332 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003333 status = -EINVAL;
3334 }
3335 if (status < 0)
3336 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003337
3338 /* Wait until sc is ready processing command */
3339 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003340 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003342 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003344 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003345 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3346 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347
3348 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003349 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003350 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003352 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003353 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003354 if (status < 0)
3355 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356
3357 /* Retreive results parameters from SC */
3358 switch (cmd) {
3359 /* All commands yielding 5 results */
3360 /* All commands yielding 4 results */
3361 /* All commands yielding 3 results */
3362 /* All commands yielding 2 results */
3363 /* All commands yielding 1 result */
3364 case OFDM_SC_RA_RAM_CMD_USER_IO:
3365 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003366 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003367 /* All commands yielding 0 results */
3368 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3369 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3370 case OFDM_SC_RA_RAM_CMD_PROC_START:
3371 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3372 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3373 case OFDM_SC_RA_RAM_CMD_NULL:
3374 break;
3375 default:
3376 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003377 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003378 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003379 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380error:
3381 if (status < 0)
3382 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 return status;
3384}
3385
Oliver Endrissebc7de22011-07-03 13:49:44 -03003386static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003388 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 int status;
3390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003391 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003392 status = CtrlPowerMode(state, &powerMode);
3393 if (status < 0)
3394 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395 return status;
3396}
3397
Oliver Endrissebc7de22011-07-03 13:49:44 -03003398static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003399{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003400 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003402 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003404 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003405 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003406 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003407 if (status < 0)
3408 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409 return status;
3410}
3411
3412#define DEFAULT_FR_THRES_8K 4000
3413static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3414{
3415
3416 int status;
3417
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003418 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003419 if (*enabled == true) {
3420 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003421 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003422 DEFAULT_FR_THRES_8K);
3423 } else {
3424 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003425 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003426 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003427 if (status < 0)
3428 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429
3430 return status;
3431}
3432
3433static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3434 struct DRXKCfgDvbtEchoThres_t *echoThres)
3435{
3436 u16 data = 0;
3437 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003438
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003439 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003440 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3441 if (status < 0)
3442 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003444 switch (echoThres->fftMode) {
3445 case DRX_FFTMODE_2K:
3446 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3447 data |= ((echoThres->threshold <<
3448 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3449 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003450 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003451 case DRX_FFTMODE_8K:
3452 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3453 data |= ((echoThres->threshold <<
3454 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3455 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003456 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003457 default:
3458 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003460
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003461 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3462error:
3463 if (status < 0)
3464 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003465 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003466}
3467
3468static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003469 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003471 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003472
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003473 dprintk(1, "\n");
3474
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475 switch (*speed) {
3476 case DRXK_DVBT_SQI_SPEED_FAST:
3477 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3478 case DRXK_DVBT_SQI_SPEED_SLOW:
3479 break;
3480 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003481 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003482 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003483 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003484 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003485error:
3486 if (status < 0)
3487 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488 return status;
3489}
3490
3491/*============================================================================*/
3492
3493/**
3494* \brief Activate DVBT specific presets
3495* \param demod instance of demodulator.
3496* \return DRXStatus_t.
3497*
3498* Called in DVBTSetStandard
3499*
3500*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003501static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003502{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003503 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003504 bool setincenable = false;
3505 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003506
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3508 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003509
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003510 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003511 status = DVBTCtrlSetIncEnable(state, &setincenable);
3512 if (status < 0)
3513 goto error;
3514 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3515 if (status < 0)
3516 goto error;
3517 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3521 if (status < 0)
3522 goto error;
3523 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3524error:
3525 if (status < 0)
3526 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003527 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003528}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003529
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530/*============================================================================*/
3531
3532/**
3533* \brief Initialize channelswitch-independent settings for DVBT.
3534* \param demod instance of demodulator.
3535* \return DRXStatus_t.
3536*
3537* For ROM code channel filter taps are loaded from the bootloader. For microcode
3538* the DVB-T taps from the drxk_filters.h are used.
3539*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003540static int SetDVBTStandard(struct drxk_state *state,
3541 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003542{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003543 u16 cmdResult = 0;
3544 u16 data = 0;
3545 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003546
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003547 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003549 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003550 /* added antenna switch */
3551 SwitchAntennaToDVBT(state);
3552 /* send OFDM reset command */
3553 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 -03003554 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003555 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003556
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003557 /* send OFDM setenv command */
3558 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3559 if (status < 0)
3560 goto error;
3561
3562 /* reset datapath for OFDM, processors first */
3563 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3564 if (status < 0)
3565 goto error;
3566 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3567 if (status < 0)
3568 goto error;
3569 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3570 if (status < 0)
3571 goto error;
3572
3573 /* IQM setup */
3574 /* synchronize on ofdstate->m_festart */
3575 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3576 if (status < 0)
3577 goto error;
3578 /* window size for clipping ADC detection */
3579 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3580 if (status < 0)
3581 goto error;
3582 /* window size for for sense pre-SAW detection */
3583 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3584 if (status < 0)
3585 goto error;
3586 /* sense threshold for sense pre-SAW detection */
3587 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3588 if (status < 0)
3589 goto error;
3590 status = SetIqmAf(state, true);
3591 if (status < 0)
3592 goto error;
3593
3594 status = write16(state, IQM_AF_AGC_RF__A, 0);
3595 if (status < 0)
3596 goto error;
3597
3598 /* Impulse noise cruncher setup */
3599 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3600 if (status < 0)
3601 goto error;
3602 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3603 if (status < 0)
3604 goto error;
3605 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3606 if (status < 0)
3607 goto error;
3608
3609 status = write16(state, IQM_RC_STRETCH__A, 16);
3610 if (status < 0)
3611 goto error;
3612 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3613 if (status < 0)
3614 goto error;
3615 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_SCALE__A, 1600);
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3622 if (status < 0)
3623 goto error;
3624
3625 /* virtual clipping threshold for clipping ADC detection */
3626 status = write16(state, IQM_AF_CLP_TH__A, 448);
3627 if (status < 0)
3628 goto error;
3629 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3630 if (status < 0)
3631 goto error;
3632
3633 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3634 if (status < 0)
3635 goto error;
3636
3637 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3638 if (status < 0)
3639 goto error;
3640 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3641 if (status < 0)
3642 goto error;
3643 /* enable power measurement interrupt */
3644 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3645 if (status < 0)
3646 goto error;
3647 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3648 if (status < 0)
3649 goto error;
3650
3651 /* IQM will not be reset from here, sync ADC and update/init AGC */
3652 status = ADCSynchronization(state);
3653 if (status < 0)
3654 goto error;
3655 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3656 if (status < 0)
3657 goto error;
3658
3659 /* Halt SCU to enable safe non-atomic accesses */
3660 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3661 if (status < 0)
3662 goto error;
3663
3664 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3665 if (status < 0)
3666 goto error;
3667 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3668 if (status < 0)
3669 goto error;
3670
3671 /* Set Noise Estimation notch width and enable DC fix */
3672 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3673 if (status < 0)
3674 goto error;
3675 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3676 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3677 if (status < 0)
3678 goto error;
3679
3680 /* Activate SCU to enable SCU commands */
3681 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3682 if (status < 0)
3683 goto error;
3684
3685 if (!state->m_DRXK_A3_ROM_CODE) {
3686 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3687 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3688 if (status < 0)
3689 goto error;
3690 }
3691
3692 /* OFDM_SC setup */
3693#ifdef COMPILE_FOR_NONRT
3694 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3695 if (status < 0)
3696 goto error;
3697 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3698 if (status < 0)
3699 goto error;
3700#endif
3701
3702 /* FEC setup */
3703 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3704 if (status < 0)
3705 goto error;
3706
3707
3708#ifdef COMPILE_FOR_NONRT
3709 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3710 if (status < 0)
3711 goto error;
3712#else
3713 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3714 if (status < 0)
3715 goto error;
3716#endif
3717 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3718 if (status < 0)
3719 goto error;
3720
3721 /* Setup MPEG bus */
3722 status = MPEGTSDtoSetup(state, OM_DVBT);
3723 if (status < 0)
3724 goto error;
3725 /* Set DVBT Presets */
3726 status = DVBTActivatePresets(state);
3727 if (status < 0)
3728 goto error;
3729
3730error:
3731 if (status < 0)
3732 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003733 return status;
3734}
3735
3736/*============================================================================*/
3737/**
3738* \brief Start dvbt demodulating for channel.
3739* \param demod instance of demodulator.
3740* \return DRXStatus_t.
3741*/
3742static int DVBTStart(struct drxk_state *state)
3743{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003744 u16 param1;
3745 int status;
3746 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003747
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003748 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003749 /* Start correct processes to get in lock */
3750 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003751 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3752 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3753 if (status < 0)
3754 goto error;
3755 /* Start FEC OC */
3756 status = MPEGTSStart(state);
3757 if (status < 0)
3758 goto error;
3759 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3760 if (status < 0)
3761 goto error;
3762error:
3763 if (status < 0)
3764 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003765 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003766}
3767
3768
3769/*============================================================================*/
3770
3771/**
3772* \brief Set up dvbt demodulator for channel.
3773* \param demod instance of demodulator.
3774* \return DRXStatus_t.
3775* // original DVBTSetChannel()
3776*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003777static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3778 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003779{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003780 u16 cmdResult = 0;
3781 u16 transmissionParams = 0;
3782 u16 operationMode = 0;
3783 u32 iqmRcRateOfs = 0;
3784 u32 bandwidth = 0;
3785 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786 int status;
3787
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003788 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003789
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003790 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3791 if (status < 0)
3792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 /* Halt SCU to enable safe non-atomic accesses */
3795 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3796 if (status < 0)
3797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 /* Stop processors */
3800 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3801 if (status < 0)
3802 goto error;
3803 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3804 if (status < 0)
3805 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003807 /* Mandatory fix, always stop CP, required to set spl offset back to
3808 hardware default (is set to 0 by ucode during pilot detection */
3809 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3810 if (status < 0)
3811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003816 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003817 case TRANSMISSION_MODE_AUTO:
3818 default:
3819 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3820 /* fall through , try first guess DRX_FFTMODE_8K */
3821 case TRANSMISSION_MODE_8K:
3822 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003823 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003824 case TRANSMISSION_MODE_2K:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003826 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003830 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003831 default:
3832 case GUARD_INTERVAL_AUTO:
3833 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3834 /* fall through , try first guess DRX_GUARD_1DIV4 */
3835 case GUARD_INTERVAL_1_4:
3836 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003837 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003838 case GUARD_INTERVAL_1_32:
3839 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003840 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003841 case GUARD_INTERVAL_1_16:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003843 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 case GUARD_INTERVAL_1_8:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003846 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003847 }
3848
3849 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003850 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003851 case HIERARCHY_AUTO:
3852 case HIERARCHY_NONE:
3853 default:
3854 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3855 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3856 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3857 /* break; */
3858 case HIERARCHY_1:
3859 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3860 break;
3861 case HIERARCHY_2:
3862 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3863 break;
3864 case HIERARCHY_4:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3866 break;
3867 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003868
3869
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003870 /* modulation */
3871 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003872 case QAM_AUTO:
3873 default:
3874 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3875 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3876 case QAM_64:
3877 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3878 break;
3879 case QPSK:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3881 break;
3882 case QAM_16:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3884 break;
3885 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003886#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003887 /* No hierachical channels support in BDA */
3888 /* Priority (only for hierarchical channels) */
3889 switch (channel->priority) {
3890 case DRX_PRIORITY_LOW:
3891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3892 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3893 OFDM_EC_SB_PRIOR_LO);
3894 break;
3895 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003897 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3898 OFDM_EC_SB_PRIOR_HI));
3899 break;
3900 case DRX_PRIORITY_UNKNOWN: /* fall through */
3901 default:
3902 status = -EINVAL;
3903 goto error;
3904 }
3905#else
3906 /* Set Priorty high */
3907 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3908 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3909 if (status < 0)
3910 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003911#endif
3912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003913 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003914 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003915 case FEC_AUTO:
3916 default:
3917 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3918 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3919 case FEC_2_3:
3920 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3921 break;
3922 case FEC_1_2:
3923 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3924 break;
3925 case FEC_3_4:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3927 break;
3928 case FEC_5_6:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3930 break;
3931 case FEC_7_8:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3933 break;
3934 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003936 /* SAW filter selection: normaly not necesarry, but if wanted
3937 the application can select a SAW filter via the driver by using UIOs */
3938 /* First determine real bandwidth (Hz) */
3939 /* Also set delay for impulse noise cruncher */
3940 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3941 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3942 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003943 switch (state->props.bandwidth_hz) {
3944 case 0:
3945 state->props.bandwidth_hz = 8000000;
3946 /* fall though */
3947 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003948 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3949 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003950 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003951 goto error;
3952 /* cochannel protection for PAL 8 MHz */
3953 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3954 if (status < 0)
3955 goto error;
3956 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3957 if (status < 0)
3958 goto error;
3959 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3960 if (status < 0)
3961 goto error;
3962 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3963 if (status < 0)
3964 goto error;
3965 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003966 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003967 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3968 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3969 if (status < 0)
3970 goto error;
3971 /* cochannel protection for PAL 7 MHz */
3972 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3973 if (status < 0)
3974 goto error;
3975 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3976 if (status < 0)
3977 goto error;
3978 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3979 if (status < 0)
3980 goto error;
3981 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3982 if (status < 0)
3983 goto error;
3984 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003985 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003986 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3987 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3988 if (status < 0)
3989 goto error;
3990 /* cochannel protection for NTSC 6 MHz */
3991 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3992 if (status < 0)
3993 goto error;
3994 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3995 if (status < 0)
3996 goto error;
3997 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3998 if (status < 0)
3999 goto error;
4000 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4001 if (status < 0)
4002 goto error;
4003 break;
4004 default:
4005 status = -EINVAL;
4006 goto error;
4007 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004008
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004009 if (iqmRcRateOfs == 0) {
4010 /* Now compute IQM_RC_RATE_OFS
4011 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4012 =>
4013 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4014 */
4015 /* (SysFreq / BandWidth) * (2^28) */
4016 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4017 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4018 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4019 iqmRcRateOfs = Frac28a((u32)
4020 ((state->m_sysClockFreq *
4021 1000) / 3), bandwidth);
4022 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4023 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4024 iqmRcRateOfs += 0x80L;
4025 iqmRcRateOfs = iqmRcRateOfs >> 7;
4026 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4027 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4028 }
4029
4030 iqmRcRateOfs &=
4031 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4032 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4033 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4034 if (status < 0)
4035 goto error;
4036
4037 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004038
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004039#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004040 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4041 if (status < 0)
4042 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004043#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004044 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4045 if (status < 0)
4046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004048 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004049
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004050 /* Activate SCU to enable SCU commands */
4051 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4052 if (status < 0)
4053 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004054
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004055 /* Enable SC after setting all other parameters */
4056 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4057 if (status < 0)
4058 goto error;
4059 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4060 if (status < 0)
4061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
4063
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004064 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4065 if (status < 0)
4066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004068 /* Write SC parameter registers, set all AUTO flags in operation mode */
4069 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4070 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4071 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4072 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4073 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4074 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4075 0, transmissionParams, param1, 0, 0, 0);
4076 if (status < 0)
4077 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004078
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004079 if (!state->m_DRXK_A3_ROM_CODE)
4080 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4081error:
4082 if (status < 0)
4083 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004084
4085 return status;
4086}
4087
4088
4089/*============================================================================*/
4090
4091/**
4092* \brief Retreive lock status .
4093* \param demod Pointer to demodulator instance.
4094* \param lockStat Pointer to lock status structure.
4095* \return DRXStatus_t.
4096*
4097*/
4098static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4099{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004100 int status;
4101 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4102 OFDM_SC_RA_RAM_LOCK_FEC__M);
4103 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4104 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004105
Oliver Endrissebc7de22011-07-03 13:49:44 -03004106 u16 ScRaRamLock = 0;
4107 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004108
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004109 dprintk(1, "\n");
4110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004111 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004112 /* driver 0.9.0 */
4113 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004114 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004115 if (status < 0)
4116 goto end;
4117 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4118 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004119
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004120 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004121 if (status < 0)
4122 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Oliver Endrissebc7de22011-07-03 13:49:44 -03004124 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4125 *pLockStatus = MPEG_LOCK;
4126 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4127 *pLockStatus = FEC_LOCK;
4128 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4129 *pLockStatus = DEMOD_LOCK;
4130 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4131 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004132end:
4133 if (status < 0)
4134 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004135
Oliver Endrissebc7de22011-07-03 13:49:44 -03004136 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004137}
4138
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004142 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004144 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004145 status = CtrlPowerMode(state, &powerMode);
4146 if (status < 0)
4147 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004148
Oliver Endrissebc7de22011-07-03 13:49:44 -03004149 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004150}
4151
4152
Oliver Endrissebc7de22011-07-03 13:49:44 -03004153/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154static int PowerDownQAM(struct drxk_state *state)
4155{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004156 u16 data = 0;
4157 u16 cmdResult;
4158 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004159
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004160 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004161 status = read16(state, SCU_COMM_EXEC__A, &data);
4162 if (status < 0)
4163 goto error;
4164 if (data == SCU_COMM_EXEC_ACTIVE) {
4165 /*
4166 STOP demodulator
4167 QAM and HW blocks
4168 */
4169 /* stop all comstate->m_exec */
4170 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004171 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004172 goto error;
4173 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 -03004174 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004175 goto error;
4176 }
4177 /* powerdown AFE */
4178 status = SetIqmAf(state, false);
4179
4180error:
4181 if (status < 0)
4182 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004183
Oliver Endrissebc7de22011-07-03 13:49:44 -03004184 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004185}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004186
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004187/*============================================================================*/
4188
4189/**
4190* \brief Setup of the QAM Measurement intervals for signal quality
4191* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004192* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004193* \return DRXStatus_t.
4194*
4195* NOTE:
4196* Take into account that for certain settings the errorcounters can overflow.
4197* The implementation does not check this.
4198*
4199*/
4200static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004201 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004202 u32 symbolRate)
4203{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004204 u32 fecBitsDesired = 0; /* BER accounting period */
4205 u32 fecRsPeriodTotal = 0; /* Total period */
4206 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4207 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004208 int status = 0;
4209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004210 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004211
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004212 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004213 /* fecBitsDesired = symbolRate [kHz] *
4214 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004215 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004216 SyncLoss (== 1) *
4217 ViterbiLoss (==1)
4218 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004219 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004220 case DRX_CONSTELLATION_QAM16:
4221 fecBitsDesired = 4 * symbolRate;
4222 break;
4223 case DRX_CONSTELLATION_QAM32:
4224 fecBitsDesired = 5 * symbolRate;
4225 break;
4226 case DRX_CONSTELLATION_QAM64:
4227 fecBitsDesired = 6 * symbolRate;
4228 break;
4229 case DRX_CONSTELLATION_QAM128:
4230 fecBitsDesired = 7 * symbolRate;
4231 break;
4232 case DRX_CONSTELLATION_QAM256:
4233 fecBitsDesired = 8 * symbolRate;
4234 break;
4235 default:
4236 status = -EINVAL;
4237 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004238 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004239 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004240
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004241 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4242 fecBitsDesired *= 500; /* meas. period [ms] */
4243
4244 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4245 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4246 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4247
4248 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4249 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4250 if (fecRsPrescale == 0) {
4251 /* Divide by zero (though impossible) */
4252 status = -EINVAL;
4253 if (status < 0)
4254 goto error;
4255 }
4256 fecRsPeriod =
4257 ((u16) fecRsPeriodTotal +
4258 (fecRsPrescale >> 1)) / fecRsPrescale;
4259
4260 /* write corresponding registers */
4261 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4262 if (status < 0)
4263 goto error;
4264 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4265 if (status < 0)
4266 goto error;
4267 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4268error:
4269 if (status < 0)
4270 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004271 return status;
4272}
4273
Oliver Endrissebc7de22011-07-03 13:49:44 -03004274static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004275{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004276 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004277
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004278 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004279 /* QAM Equalizer Setup */
4280 /* Equalizer */
4281 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4294 if (status < 0)
4295 goto error;
4296 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4297 if (status < 0)
4298 goto error;
4299 /* Decision Feedback Equalizer */
4300 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4301 if (status < 0)
4302 goto error;
4303 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4304 if (status < 0)
4305 goto error;
4306 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4316 if (status < 0)
4317 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004318
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004319 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4320 if (status < 0)
4321 goto error;
4322 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4323 if (status < 0)
4324 goto error;
4325 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4326 if (status < 0)
4327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004329 /* QAM Slicer Settings */
4330 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4331 if (status < 0)
4332 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004334 /* QAM Loop Controller Coeficients */
4335 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4351 if (status < 0)
4352 goto error;
4353 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4354 if (status < 0)
4355 goto error;
4356 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4357 if (status < 0)
4358 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004360 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4361 if (status < 0)
4362 goto error;
4363 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4364 if (status < 0)
4365 goto error;
4366 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4367 if (status < 0)
4368 goto error;
4369 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4370 if (status < 0)
4371 goto error;
4372 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4373 if (status < 0)
4374 goto error;
4375 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4391 if (status < 0)
4392 goto error;
4393 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4394 if (status < 0)
4395 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004396
4397
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004398 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004399
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004400 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4401 if (status < 0)
4402 goto error;
4403 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4404 if (status < 0)
4405 goto error;
4406 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4407 if (status < 0)
4408 goto error;
4409 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4410 if (status < 0)
4411 goto error;
4412 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4413 if (status < 0)
4414 goto error;
4415 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4416 if (status < 0)
4417 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004418
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004419 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4420 if (status < 0)
4421 goto error;
4422 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4423 if (status < 0)
4424 goto error;
4425 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4426 if (status < 0)
4427 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004428
4429
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004430 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004431
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004432 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4433 if (status < 0)
4434 goto error;
4435 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4436 if (status < 0)
4437 goto error;
4438 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4439 if (status < 0)
4440 goto error;
4441 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4442 if (status < 0)
4443 goto error;
4444 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4445 if (status < 0)
4446 goto error;
4447 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4448 if (status < 0)
4449 goto error;
4450 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4451 if (status < 0)
4452 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004453
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004454error:
4455 if (status < 0)
4456 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004457 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004458}
4459
4460/*============================================================================*/
4461
4462/**
4463* \brief QAM32 specific setup
4464* \param demod instance of demod.
4465* \return DRXStatus_t.
4466*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004467static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004468{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004469 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004470
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004471 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004472
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004473 /* QAM Equalizer Setup */
4474 /* Equalizer */
4475 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4476 if (status < 0)
4477 goto error;
4478 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4479 if (status < 0)
4480 goto error;
4481 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4482 if (status < 0)
4483 goto error;
4484 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4485 if (status < 0)
4486 goto error;
4487 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4488 if (status < 0)
4489 goto error;
4490 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4491 if (status < 0)
4492 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004493
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004494 /* Decision Feedback Equalizer */
4495 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4496 if (status < 0)
4497 goto error;
4498 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4511 if (status < 0)
4512 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004513
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004514 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4515 if (status < 0)
4516 goto error;
4517 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4518 if (status < 0)
4519 goto error;
4520 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4521 if (status < 0)
4522 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004523
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004524 /* QAM Slicer Settings */
4525
4526 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4527 if (status < 0)
4528 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
4530
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004531 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004532
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004533 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4552 if (status < 0)
4553 goto error;
4554 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4555 if (status < 0)
4556 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004557
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004558 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4559 if (status < 0)
4560 goto error;
4561 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4562 if (status < 0)
4563 goto error;
4564 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4589 if (status < 0)
4590 goto error;
4591 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4592 if (status < 0)
4593 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004594
4595
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004596 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004597
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004598 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4605 if (status < 0)
4606 goto error;
4607 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4608 if (status < 0)
4609 goto error;
4610 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4611 if (status < 0)
4612 goto error;
4613 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4614 if (status < 0)
4615 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004616
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004617 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4618 if (status < 0)
4619 goto error;
4620 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4621 if (status < 0)
4622 goto error;
4623 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4624 if (status < 0)
4625 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004626
4627
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004628 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004629
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004630 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4649error:
4650 if (status < 0)
4651 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004652 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004653}
4654
4655/*============================================================================*/
4656
4657/**
4658* \brief QAM64 specific setup
4659* \param demod instance of demod.
4660* \return DRXStatus_t.
4661*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004662static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004663{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004664 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004665
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004666 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004667 /* QAM Equalizer Setup */
4668 /* Equalizer */
4669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4685 if (status < 0)
4686 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004687
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004688 /* Decision Feedback Equalizer */
4689 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4705 if (status < 0)
4706 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004708 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4709 if (status < 0)
4710 goto error;
4711 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4712 if (status < 0)
4713 goto error;
4714 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4715 if (status < 0)
4716 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004717
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004718 /* QAM Slicer Settings */
4719 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4720 if (status < 0)
4721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
4723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004724 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004726 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4742 if (status < 0)
4743 goto error;
4744 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4745 if (status < 0)
4746 goto error;
4747 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4748 if (status < 0)
4749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004751 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4752 if (status < 0)
4753 goto error;
4754 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4755 if (status < 0)
4756 goto error;
4757 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4758 if (status < 0)
4759 goto error;
4760 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4761 if (status < 0)
4762 goto error;
4763 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4779 if (status < 0)
4780 goto error;
4781 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4782 if (status < 0)
4783 goto error;
4784 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4785 if (status < 0)
4786 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004787
4788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004789 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004791 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4792 if (status < 0)
4793 goto error;
4794 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4795 if (status < 0)
4796 goto error;
4797 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4798 if (status < 0)
4799 goto error;
4800 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4801 if (status < 0)
4802 goto error;
4803 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4804 if (status < 0)
4805 goto error;
4806 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4807 if (status < 0)
4808 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004810 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4811 if (status < 0)
4812 goto error;
4813 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4814 if (status < 0)
4815 goto error;
4816 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4817 if (status < 0)
4818 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004819
4820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004821 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004823 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4824 if (status < 0)
4825 goto error;
4826 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4842error:
4843 if (status < 0)
4844 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004845
Oliver Endrissebc7de22011-07-03 13:49:44 -03004846 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847}
4848
4849/*============================================================================*/
4850
4851/**
4852* \brief QAM128 specific setup
4853* \param demod: instance of demod.
4854* \return DRXStatus_t.
4855*/
4856static int SetQAM128(struct drxk_state *state)
4857{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004858 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004859
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004860 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004861 /* QAM Equalizer Setup */
4862 /* Equalizer */
4863 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4864 if (status < 0)
4865 goto error;
4866 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4867 if (status < 0)
4868 goto error;
4869 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4870 if (status < 0)
4871 goto error;
4872 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4876 if (status < 0)
4877 goto error;
4878 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4879 if (status < 0)
4880 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004881
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004882 /* Decision Feedback Equalizer */
4883 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4884 if (status < 0)
4885 goto error;
4886 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4887 if (status < 0)
4888 goto error;
4889 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4890 if (status < 0)
4891 goto error;
4892 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4893 if (status < 0)
4894 goto error;
4895 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4896 if (status < 0)
4897 goto error;
4898 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4899 if (status < 0)
4900 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004901
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004902 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4903 if (status < 0)
4904 goto error;
4905 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4906 if (status < 0)
4907 goto error;
4908 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4909 if (status < 0)
4910 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004911
4912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004913 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004914
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004915 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4916 if (status < 0)
4917 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
4919
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004920 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004921
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004922 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4944 if (status < 0)
4945 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004946
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004947 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4948 if (status < 0)
4949 goto error;
4950 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4951 if (status < 0)
4952 goto error;
4953 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4954 if (status < 0)
4955 goto error;
4956 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4957 if (status < 0)
4958 goto error;
4959 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4975 if (status < 0)
4976 goto error;
4977 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4978 if (status < 0)
4979 goto error;
4980 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4981 if (status < 0)
4982 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004983
4984
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004985 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004987 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4988 if (status < 0)
4989 goto error;
4990 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4991 if (status < 0)
4992 goto error;
4993 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4994 if (status < 0)
4995 goto error;
4996 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4997 if (status < 0)
4998 goto error;
4999 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5000 if (status < 0)
5001 goto error;
5002 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5003 if (status < 0)
5004 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005006 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5007 if (status < 0)
5008 goto error;
5009 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5010 if (status < 0)
5011 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005012
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005013 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5014 if (status < 0)
5015 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005017 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005019 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5020 if (status < 0)
5021 goto error;
5022 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5023 if (status < 0)
5024 goto error;
5025 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5026 if (status < 0)
5027 goto error;
5028 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5029 if (status < 0)
5030 goto error;
5031 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5032 if (status < 0)
5033 goto error;
5034 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5035 if (status < 0)
5036 goto error;
5037 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5038error:
5039 if (status < 0)
5040 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005041
Oliver Endrissebc7de22011-07-03 13:49:44 -03005042 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005043}
5044
5045/*============================================================================*/
5046
5047/**
5048* \brief QAM256 specific setup
5049* \param demod: instance of demod.
5050* \return DRXStatus_t.
5051*/
5052static int SetQAM256(struct drxk_state *state)
5053{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005054 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005055
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005056 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005057 /* QAM Equalizer Setup */
5058 /* Equalizer */
5059 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5060 if (status < 0)
5061 goto error;
5062 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5063 if (status < 0)
5064 goto error;
5065 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5066 if (status < 0)
5067 goto error;
5068 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5069 if (status < 0)
5070 goto error;
5071 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5072 if (status < 0)
5073 goto error;
5074 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5075 if (status < 0)
5076 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005078 /* Decision Feedback Equalizer */
5079 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5080 if (status < 0)
5081 goto error;
5082 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5095 if (status < 0)
5096 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005097
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005098 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5099 if (status < 0)
5100 goto error;
5101 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5102 if (status < 0)
5103 goto error;
5104 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5105 if (status < 0)
5106 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005108 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005110 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5111 if (status < 0)
5112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
5114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005115 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005117 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5139 if (status < 0)
5140 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005141
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005142 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5143 if (status < 0)
5144 goto error;
5145 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5146 if (status < 0)
5147 goto error;
5148 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5173 if (status < 0)
5174 goto error;
5175 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5176 if (status < 0)
5177 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005178
5179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005180 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005182 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5183 if (status < 0)
5184 goto error;
5185 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5186 if (status < 0)
5187 goto error;
5188 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5189 if (status < 0)
5190 goto error;
5191 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5192 if (status < 0)
5193 goto error;
5194 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5195 if (status < 0)
5196 goto error;
5197 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5198 if (status < 0)
5199 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005200
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005201 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5202 if (status < 0)
5203 goto error;
5204 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5205 if (status < 0)
5206 goto error;
5207 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5208 if (status < 0)
5209 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005210
5211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005212 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005213
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005214 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5215 if (status < 0)
5216 goto error;
5217 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5233error:
5234 if (status < 0)
5235 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005236 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005237}
5238
5239
5240/*============================================================================*/
5241/**
5242* \brief Reset QAM block.
5243* \param demod: instance of demod.
5244* \param channel: pointer to channel data.
5245* \return DRXStatus_t.
5246*/
5247static int QAMResetQAM(struct drxk_state *state)
5248{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005249 int status;
5250 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005252 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005253 /* Stop QAM comstate->m_exec */
5254 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5255 if (status < 0)
5256 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005257
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005258 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5259error:
5260 if (status < 0)
5261 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005262 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005263}
5264
5265/*============================================================================*/
5266
5267/**
5268* \brief Set QAM symbolrate.
5269* \param demod: instance of demod.
5270* \param channel: pointer to channel data.
5271* \return DRXStatus_t.
5272*/
5273static int QAMSetSymbolrate(struct drxk_state *state)
5274{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005275 u32 adcFrequency = 0;
5276 u32 symbFreq = 0;
5277 u32 iqmRcRate = 0;
5278 u16 ratesel = 0;
5279 u32 lcSymbRate = 0;
5280 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005282 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005283 /* Select & calculate correct IQM rate */
5284 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5285 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005286 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5287 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005288 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005289 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005290 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005291 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005292 ratesel = 1;
5293 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5294 if (status < 0)
5295 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005296
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005297 /*
5298 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5299 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005300 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005301 if (symbFreq == 0) {
5302 /* Divide by zero */
5303 status = -EINVAL;
5304 goto error;
5305 }
5306 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5307 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5308 (1 << 23);
5309 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5310 if (status < 0)
5311 goto error;
5312 state->m_iqmRcRate = iqmRcRate;
5313 /*
5314 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5315 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005316 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005317 if (adcFrequency == 0) {
5318 /* Divide by zero */
5319 status = -EINVAL;
5320 goto error;
5321 }
5322 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5323 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5324 16);
5325 if (lcSymbRate > 511)
5326 lcSymbRate = 511;
5327 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005329error:
5330 if (status < 0)
5331 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005332 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005333}
5334
5335/*============================================================================*/
5336
5337/**
5338* \brief Get QAM lock status.
5339* \param demod: instance of demod.
5340* \param channel: pointer to channel data.
5341* \return DRXStatus_t.
5342*/
5343
5344static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5345{
5346 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005347 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005348
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005349 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005350 *pLockStatus = NOT_LOCKED;
5351 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352 SCU_RAM_COMMAND_STANDARD_QAM |
5353 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5354 Result);
5355 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005356 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357
5358 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005359 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005360 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005361 /* 0x4000 DEMOD LOCKED */
5362 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005363 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005364 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5365 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005366 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005367 /* 0xC000 NEVER LOCKED */
5368 /* (system will never be able to lock to the signal) */
5369 /* TODO: check this, intermediate & standard specific lock states are not
5370 taken into account here */
5371 *pLockStatus = NEVER_LOCK;
5372 }
5373 return status;
5374}
5375
5376#define QAM_MIRROR__M 0x03
5377#define QAM_MIRROR_NORMAL 0x00
5378#define QAM_MIRRORED 0x01
5379#define QAM_MIRROR_AUTO_ON 0x02
5380#define QAM_LOCKRANGE__M 0x10
5381#define QAM_LOCKRANGE_NORMAL 0x10
5382
Oliver Endrissebc7de22011-07-03 13:49:44 -03005383static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5384 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005385{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005386 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005387 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5388 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005390 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005391 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005392 * STEP 1: reset demodulator
5393 * resets FEC DI and FEC RS
5394 * resets QAM block
5395 * resets SCU variables
5396 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005397 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005398 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005399 goto error;
5400 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5401 if (status < 0)
5402 goto error;
5403 status = QAMResetQAM(state);
5404 if (status < 0)
5405 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005406
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005407 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005408 * STEP 2: configure demodulator
5409 * -set params; resets IQM,QAM,FEC HW; initializes some
5410 * SCU variables
5411 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005412 status = QAMSetSymbolrate(state);
5413 if (status < 0)
5414 goto error;
5415
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005416 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005417 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005418 case QAM_256:
5419 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5420 break;
5421 case QAM_AUTO:
5422 case QAM_64:
5423 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5424 break;
5425 case QAM_16:
5426 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5427 break;
5428 case QAM_32:
5429 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5430 break;
5431 case QAM_128:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5433 break;
5434 default:
5435 status = -EINVAL;
5436 break;
5437 }
5438 if (status < 0)
5439 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005440 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005441 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005442 if (state->m_OperationMode == OM_QAM_ITU_C)
5443 setParamParameters[2] = QAM_TOP_ANNEX_C;
5444 else
5445 setParamParameters[2] = QAM_TOP_ANNEX_A;
5446 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5447 /* Env parameters */
5448 /* check for LOCKRANGE Extented */
5449 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005450
5451 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 -03005452 if (status < 0) {
5453 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005454 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005455 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005456 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005457 setParamParameters[0] = QAM_TOP_ANNEX_A;
5458 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5459 if (status < 0)
5460 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005461
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005462 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005463 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005464 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5465 }
5466 if (status < 0)
5467 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005468
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005469 /*
5470 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005471 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005472 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005473#if 0
5474 status = SetFrequency(channel, tunerFreqOffset));
5475 if (status < 0)
5476 goto error;
5477#endif
5478 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5479 if (status < 0)
5480 goto error;
5481
5482 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005483 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005484 if (status < 0)
5485 goto error;
5486
5487 /* Reset default values */
5488 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5489 if (status < 0)
5490 goto error;
5491 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5492 if (status < 0)
5493 goto error;
5494
5495 /* Reset default LC values */
5496 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5497 if (status < 0)
5498 goto error;
5499 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5500 if (status < 0)
5501 goto error;
5502 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5503 if (status < 0)
5504 goto error;
5505 status = write16(state, QAM_LC_MODE__A, 7);
5506 if (status < 0)
5507 goto error;
5508
5509 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5510 if (status < 0)
5511 goto error;
5512 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5513 if (status < 0)
5514 goto error;
5515 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5516 if (status < 0)
5517 goto error;
5518 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5519 if (status < 0)
5520 goto error;
5521 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5522 if (status < 0)
5523 goto error;
5524 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5525 if (status < 0)
5526 goto error;
5527 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5528 if (status < 0)
5529 goto error;
5530 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5531 if (status < 0)
5532 goto error;
5533 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5534 if (status < 0)
5535 goto error;
5536 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5537 if (status < 0)
5538 goto error;
5539 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5540 if (status < 0)
5541 goto error;
5542 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5543 if (status < 0)
5544 goto error;
5545 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5546 if (status < 0)
5547 goto error;
5548 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5549 if (status < 0)
5550 goto error;
5551 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5552 if (status < 0)
5553 goto error;
5554
5555 /* Mirroring, QAM-block starting point not inverted */
5556 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5557 if (status < 0)
5558 goto error;
5559
5560 /* Halt SCU to enable safe non-atomic accesses */
5561 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5562 if (status < 0)
5563 goto error;
5564
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005565 /* STEP 4: modulation specific setup */
5566 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005567 case QAM_16:
5568 status = SetQAM16(state);
5569 break;
5570 case QAM_32:
5571 status = SetQAM32(state);
5572 break;
5573 case QAM_AUTO:
5574 case QAM_64:
5575 status = SetQAM64(state);
5576 break;
5577 case QAM_128:
5578 status = SetQAM128(state);
5579 break;
5580 case QAM_256:
5581 status = SetQAM256(state);
5582 break;
5583 default:
5584 status = -EINVAL;
5585 break;
5586 }
5587 if (status < 0)
5588 goto error;
5589
5590 /* Activate SCU to enable SCU commands */
5591 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5592 if (status < 0)
5593 goto error;
5594
5595 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005596 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005597 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5598 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5599 if (status < 0)
5600 goto error;
5601
5602 /* Start processes */
5603 status = MPEGTSStart(state);
5604 if (status < 0)
5605 goto error;
5606 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5607 if (status < 0)
5608 goto error;
5609 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5610 if (status < 0)
5611 goto error;
5612 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5613 if (status < 0)
5614 goto error;
5615
5616 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5617 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5618 if (status < 0)
5619 goto error;
5620
5621 /* update global DRXK data container */
5622/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5623
5624error:
5625 if (status < 0)
5626 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005627 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005628}
5629
Oliver Endrissebc7de22011-07-03 13:49:44 -03005630static int SetQAMStandard(struct drxk_state *state,
5631 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005632{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005633 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634#ifdef DRXK_QAM_TAPS
5635#define DRXK_QAMA_TAPS_SELECT
5636#include "drxk_filters.h"
5637#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005638#endif
5639
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005640 dprintk(1, "\n");
5641
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005642 /* added antenna switch */
5643 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005644
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005645 /* Ensure correct power-up mode */
5646 status = PowerUpQAM(state);
5647 if (status < 0)
5648 goto error;
5649 /* Reset QAM block */
5650 status = QAMResetQAM(state);
5651 if (status < 0)
5652 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005653
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005654 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005655
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005656 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5657 if (status < 0)
5658 goto error;
5659 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5660 if (status < 0)
5661 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005662
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005663 /* Upload IQM Channel Filter settings by
5664 boot loader from ROM table */
5665 switch (oMode) {
5666 case OM_QAM_ITU_A:
5667 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5668 break;
5669 case OM_QAM_ITU_C:
5670 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 -03005671 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005672 goto error;
5673 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5674 break;
5675 default:
5676 status = -EINVAL;
5677 }
5678 if (status < 0)
5679 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005680
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005681 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5682 if (status < 0)
5683 goto error;
5684 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5685 if (status < 0)
5686 goto error;
5687 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5688 if (status < 0)
5689 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005691 status = write16(state, IQM_RC_STRETCH__A, 21);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5695 if (status < 0)
5696 goto error;
5697 status = write16(state, IQM_AF_CLP_TH__A, 448);
5698 if (status < 0)
5699 goto error;
5700 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5701 if (status < 0)
5702 goto error;
5703 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5704 if (status < 0)
5705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005707 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5708 if (status < 0)
5709 goto error;
5710 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5711 if (status < 0)
5712 goto error;
5713 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5714 if (status < 0)
5715 goto error;
5716 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5717 if (status < 0)
5718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005720 /* IQM Impulse Noise Processing Unit */
5721 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5722 if (status < 0)
5723 goto error;
5724 status = write16(state, IQM_CF_DATATH__A, 1000);
5725 if (status < 0)
5726 goto error;
5727 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5728 if (status < 0)
5729 goto error;
5730 status = write16(state, IQM_CF_DET_LCT__A, 0);
5731 if (status < 0)
5732 goto error;
5733 status = write16(state, IQM_CF_WND_LEN__A, 1);
5734 if (status < 0)
5735 goto error;
5736 status = write16(state, IQM_CF_PKDTH__A, 1);
5737 if (status < 0)
5738 goto error;
5739 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5740 if (status < 0)
5741 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005742
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005743 /* turn on IQMAF. Must be done before setAgc**() */
5744 status = SetIqmAf(state, true);
5745 if (status < 0)
5746 goto error;
5747 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5748 if (status < 0)
5749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 /* IQM will not be reset from here, sync ADC and update/init AGC */
5752 status = ADCSynchronization(state);
5753 if (status < 0)
5754 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005755
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005756 /* Set the FSM step period */
5757 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5758 if (status < 0)
5759 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005761 /* Halt SCU to enable safe non-atomic accesses */
5762 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5763 if (status < 0)
5764 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005766 /* No more resets of the IQM, current standard correctly set =>
5767 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005769 status = InitAGC(state, true);
5770 if (status < 0)
5771 goto error;
5772 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5773 if (status < 0)
5774 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005776 /* Configure AGC's */
5777 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5778 if (status < 0)
5779 goto error;
5780 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5781 if (status < 0)
5782 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005784 /* Activate SCU to enable SCU commands */
5785 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5786error:
5787 if (status < 0)
5788 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005789 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005790}
5791
5792static int WriteGPIO(struct drxk_state *state)
5793{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005794 int status;
5795 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005796
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005797 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005798 /* stop lock indicator process */
5799 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5800 if (status < 0)
5801 goto error;
5802
5803 /* Write magic word to enable pdr reg write */
5804 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5805 if (status < 0)
5806 goto error;
5807
5808 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005809 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5810 /* write to io pad configuration register - output mode */
5811 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5812 if (status < 0)
5813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005814
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005815 /* use corresponding bit in io data output registar */
5816 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5817 if (status < 0)
5818 goto error;
5819 if ((state->m_GPIO & 0x0001) == 0)
5820 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5821 else
5822 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5823 /* write back to io data output register */
5824 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5825 if (status < 0)
5826 goto error;
5827 }
5828 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5829 /* write to io pad configuration register - output mode */
5830 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5831 if (status < 0)
5832 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005833
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005834 /* use corresponding bit in io data output registar */
5835 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5836 if (status < 0)
5837 goto error;
5838 if ((state->m_GPIO & 0x0002) == 0)
5839 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5840 else
5841 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5842 /* write back to io data output register */
5843 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5844 if (status < 0)
5845 goto error;
5846 }
5847 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5848 /* write to io pad configuration register - output mode */
5849 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5850 if (status < 0)
5851 goto error;
5852
5853 /* use corresponding bit in io data output registar */
5854 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5855 if (status < 0)
5856 goto error;
5857 if ((state->m_GPIO & 0x0004) == 0)
5858 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5859 else
5860 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5861 /* write back to io data output register */
5862 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5863 if (status < 0)
5864 goto error;
5865 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005866 }
5867 /* Write magic word to disable pdr reg write */
5868 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5869error:
5870 if (status < 0)
5871 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005872 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005873}
5874
5875static int SwitchAntennaToQAM(struct drxk_state *state)
5876{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005877 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005878 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005879
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005880 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005881
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005882 if (!state->antenna_gpio)
5883 return 0;
5884
5885 gpio_state = state->m_GPIO & state->antenna_gpio;
5886
5887 if (state->antenna_dvbt ^ gpio_state) {
5888 /* Antenna is on DVB-T mode. Switch */
5889 if (state->antenna_dvbt)
5890 state->m_GPIO &= ~state->antenna_gpio;
5891 else
5892 state->m_GPIO |= state->antenna_gpio;
5893 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005894 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005895 if (status < 0)
5896 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005897 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005898}
5899
5900static int SwitchAntennaToDVBT(struct drxk_state *state)
5901{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005902 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005903 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005904
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005905 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005906
5907 if (!state->antenna_gpio)
5908 return 0;
5909
5910 gpio_state = state->m_GPIO & state->antenna_gpio;
5911
5912 if (!(state->antenna_dvbt ^ gpio_state)) {
5913 /* Antenna is on DVB-C mode. Switch */
5914 if (state->antenna_dvbt)
5915 state->m_GPIO |= state->antenna_gpio;
5916 else
5917 state->m_GPIO &= ~state->antenna_gpio;
5918 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005919 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005920 if (status < 0)
5921 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005922 return status;
5923}
5924
5925
5926static int PowerDownDevice(struct drxk_state *state)
5927{
5928 /* Power down to requested mode */
5929 /* Backup some register settings */
5930 /* Set pins with possible pull-ups connected to them in input mode */
5931 /* Analog power down */
5932 /* ADC power down */
5933 /* Power down device */
5934 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005935
5936 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005937 if (state->m_bPDownOpenBridge) {
5938 /* Open I2C bridge before power down of DRXK */
5939 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005940 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005941 goto error;
5942 }
5943 /* driver 0.9.0 */
5944 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005945 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005946 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5949 if (status < 0)
5950 goto error;
5951 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5952 if (status < 0)
5953 goto error;
5954 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5955 status = HI_CfgCommand(state);
5956error:
5957 if (status < 0)
5958 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5959
5960 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005961}
5962
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005963static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005964{
5965 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005966 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005967
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005968 dprintk(1, "\n");
5969
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005970 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5971 if (err < 0) {
5972 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005973 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005975 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005976 return err;
5977 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005978 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005979 release_firmware(fw);
5980 return err;
5981}
5982
5983static int init_drxk(struct drxk_state *state)
5984{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005985 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005986 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005987 u16 driverVersion;
5988
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005989 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005990 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005991 status = PowerUpDevice(state);
5992 if (status < 0)
5993 goto error;
5994 status = DRXX_Open(state);
5995 if (status < 0)
5996 goto error;
5997 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5998 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);
5999 if (status < 0)
6000 goto error;
6001 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6002 if (status < 0)
6003 goto error;
6004 /* TODO is this needed, if yes how much delay in worst case scenario */
6005 msleep(1);
6006 state->m_DRXK_A3_PATCH_CODE = true;
6007 status = GetDeviceCapabilities(state);
6008 if (status < 0)
6009 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006011 /* Bridge delay, uses oscilator clock */
6012 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6013 /* SDA brdige delay */
6014 state->m_HICfgBridgeDelay =
6015 (u16) ((state->m_oscClockFreq / 1000) *
6016 HI_I2C_BRIDGE_DELAY) / 1000;
6017 /* Clipping */
6018 if (state->m_HICfgBridgeDelay >
6019 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006020 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006021 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6022 }
6023 /* SCL bridge delay, same as SDA for now */
6024 state->m_HICfgBridgeDelay +=
6025 state->m_HICfgBridgeDelay <<
6026 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006027
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006028 status = InitHI(state);
6029 if (status < 0)
6030 goto error;
6031 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006032#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006033 if (!(state->m_DRXK_A1_ROM_CODE)
6034 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006035#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006036 {
6037 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6038 if (status < 0)
6039 goto error;
6040 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006041
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006042 /* disable MPEG port */
6043 status = MPEGTSDisable(state);
6044 if (status < 0)
6045 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006047 /* Stop AUD and SCU */
6048 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6049 if (status < 0)
6050 goto error;
6051 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6052 if (status < 0)
6053 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006054
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006055 /* enable token-ring bus through OFDM block for possible ucode upload */
6056 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6057 if (status < 0)
6058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006059
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006060 /* include boot loader section */
6061 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6062 if (status < 0)
6063 goto error;
6064 status = BLChainCmd(state, 0, 6, 100);
6065 if (status < 0)
6066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067
Mauro Carvalho Chehabda989e02011-07-24 09:25:39 -03006068 if (state->microcode_name)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006069 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006071 /* disable token-ring bus through OFDM block for possible ucode upload */
6072 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6073 if (status < 0)
6074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 /* Run SCU for a little while to initialize microcode version numbers */
6077 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6078 if (status < 0)
6079 goto error;
6080 status = DRXX_Open(state);
6081 if (status < 0)
6082 goto error;
6083 /* added for test */
6084 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006085
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006086 powerMode = DRXK_POWER_DOWN_OFDM;
6087 status = CtrlPowerMode(state, &powerMode);
6088 if (status < 0)
6089 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006091 /* Stamp driver version number in SCU data RAM in BCD code
6092 Done to enable field application engineers to retreive drxdriver version
6093 via I2C from SCU RAM.
6094 Not using SCU command interface for SCU register access since no
6095 microcode may be present.
6096 */
6097 driverVersion =
6098 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6099 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6100 ((DRXK_VERSION_MAJOR % 10) << 4) +
6101 (DRXK_VERSION_MINOR % 10);
6102 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6103 if (status < 0)
6104 goto error;
6105 driverVersion =
6106 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6107 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6108 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6109 (DRXK_VERSION_PATCH % 10);
6110 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6111 if (status < 0)
6112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006114 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6115 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6116 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006118 /* Dirty fix of default values for ROM/PATCH microcode
6119 Dirty because this fix makes it impossible to setup suitable values
6120 before calling DRX_Open. This solution requires changes to RF AGC speed
6121 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006123 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* Reset driver debug flags to 0 */
6126 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6127 if (status < 0)
6128 goto error;
6129 /* driver 0.9.0 */
6130 /* Setup FEC OC:
6131 NOTE: No more full FEC resets allowed afterwards!! */
6132 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6133 if (status < 0)
6134 goto error;
6135 /* MPEGTS functions are still the same */
6136 status = MPEGTSDtoInit(state);
6137 if (status < 0)
6138 goto error;
6139 status = MPEGTSStop(state);
6140 if (status < 0)
6141 goto error;
6142 status = MPEGTSConfigurePolarity(state);
6143 if (status < 0)
6144 goto error;
6145 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6146 if (status < 0)
6147 goto error;
6148 /* added: configure GPIO */
6149 status = WriteGPIO(state);
6150 if (status < 0)
6151 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006152
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006153 state->m_DrxkState = DRXK_STOPPED;
6154
6155 if (state->m_bPowerDown) {
6156 status = PowerDownDevice(state);
6157 if (status < 0)
6158 goto error;
6159 state->m_DrxkState = DRXK_POWERED_DOWN;
6160 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006161 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006163error:
6164 if (status < 0)
6165 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006166
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006167 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168}
6169
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006170static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006171{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006172 struct drxk_state *state = fe->demodulator_priv;
6173
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006174 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175 kfree(state);
6176}
6177
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006178static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006179{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006180 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006182 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006183 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006184 return 0;
6185}
6186
Oliver Endrissebc7de22011-07-03 13:49:44 -03006187static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188{
6189 struct drxk_state *state = fe->demodulator_priv;
6190
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006191 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006192 return ConfigureI2CBridge(state, enable ? true : false);
6193}
6194
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006195static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006196{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006197 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006198 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006199 struct drxk_state *state = fe->demodulator_priv;
6200 u32 IF;
6201
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006202 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006203
6204 if (!fe->ops.tuner_ops.get_if_frequency) {
6205 printk(KERN_ERR
6206 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6207 return -EINVAL;
6208 }
6209
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210 if (fe->ops.i2c_gate_ctrl)
6211 fe->ops.i2c_gate_ctrl(fe, 1);
6212 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006213 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 if (fe->ops.i2c_gate_ctrl)
6215 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006216
6217 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006218 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006219
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006220 if (old_delsys != delsys) {
6221 ShutDown(state);
6222 switch (delsys) {
6223 case SYS_DVBC_ANNEX_A:
6224 case SYS_DVBC_ANNEX_C:
6225 if (!state->m_hasDVBC)
6226 return -EINVAL;
6227 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6228 if (state->m_itut_annex_c)
6229 SetOperationMode(state, OM_QAM_ITU_C);
6230 else
6231 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006232 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006233 case SYS_DVBT:
6234 if (!state->m_hasDVBT)
6235 return -EINVAL;
6236 SetOperationMode(state, OM_DVBT);
6237 break;
6238 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006239 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006240 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006241 }
6242
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006243 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006244 Start(state, 0, IF);
6245
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006246 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006247
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248 return 0;
6249}
6250
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006251static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6252{
6253 struct drxk_state *state = fe->demodulator_priv;
6254 u32 stat;
6255
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006256 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006257 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006258 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259 if (stat == MPEG_LOCK)
6260 *status |= 0x1f;
6261 if (stat == FEC_LOCK)
6262 *status |= 0x0f;
6263 if (stat == DEMOD_LOCK)
6264 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265 return 0;
6266}
6267
6268static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6269{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006270 dprintk(1, "\n");
6271
Oliver Endrissebc7de22011-07-03 13:49:44 -03006272 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006273 return 0;
6274}
6275
Oliver Endrissebc7de22011-07-03 13:49:44 -03006276static int drxk_read_signal_strength(struct dvb_frontend *fe,
6277 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278{
6279 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006280 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006281
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006282 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006284 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006285 return 0;
6286}
6287
6288static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6289{
6290 struct drxk_state *state = fe->demodulator_priv;
6291 s32 snr2;
6292
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006293 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006294 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006295 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006296 return 0;
6297}
6298
6299static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6300{
6301 struct drxk_state *state = fe->demodulator_priv;
6302 u16 err;
6303
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006304 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006305 DVBTQAMGetAccPktErr(state, &err);
6306 *ucblocks = (u32) err;
6307 return 0;
6308}
6309
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006310static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006311 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006312{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006313 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006314
6315 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006316 switch (p->delivery_system) {
6317 case SYS_DVBC_ANNEX_A:
6318 case SYS_DVBC_ANNEX_C:
6319 sets->min_delay_ms = 3000;
6320 sets->max_drift = 0;
6321 sets->step_size = 0;
6322 return 0;
6323 default:
6324 /*
6325 * For DVB-T, let it use the default DVB core way, that is:
6326 * fepriv->step_size = fe->ops.info.frequency_stepsize * 2
6327 */
6328 return -EINVAL;
6329 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006330}
6331
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006332static struct dvb_frontend_ops drxk_ops = {
6333 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006334 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006335 .name = "DRXK",
6336 .frequency_min = 47000000,
6337 .frequency_max = 865000000,
6338 /* For DVB-C */
6339 .symbol_rate_min = 870000,
6340 .symbol_rate_max = 11700000,
6341 /* For DVB-T */
6342 .frequency_stepsize = 166667,
6343
6344 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6345 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6346 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6347 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6348 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6349 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6350 },
6351
6352 .release = drxk_release,
6353 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006354 .i2c_gate_ctrl = drxk_gate_ctrl,
6355
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006356 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006357 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006358
6359 .read_status = drxk_read_status,
6360 .read_ber = drxk_read_ber,
6361 .read_signal_strength = drxk_read_signal_strength,
6362 .read_snr = drxk_read_snr,
6363 .read_ucblocks = drxk_read_ucblocks,
6364};
6365
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006366struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006367 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006368{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006369 int n;
6370
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006371 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006372 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006373
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006374 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006375 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376 if (!state)
6377 return NULL;
6378
Oliver Endrissebc7de22011-07-03 13:49:44 -03006379 state->i2c = i2c;
6380 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006381 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006382 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006383 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006384 state->antenna_gpio = config->antenna_gpio;
6385 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006386 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006387 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006388
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006389 if (config->dynamic_clk) {
6390 state->m_DVBTStaticCLK = 0;
6391 state->m_DVBCStaticCLK = 0;
6392 } else {
6393 state->m_DVBTStaticCLK = 1;
6394 state->m_DVBCStaticCLK = 1;
6395 }
6396
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006397
6398 if (config->mpeg_out_clk_strength)
6399 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6400 else
6401 state->m_TSClockkStrength = 0x06;
6402
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006403 if (config->parallel_ts)
6404 state->m_enableParallel = true;
6405 else
6406 state->m_enableParallel = false;
6407
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006408 /* NOTE: as more UIO bits will be used, add them to the mask */
6409 state->UIO_mask = config->antenna_gpio;
6410
6411 /* Default gpio to DVB-C */
6412 if (!state->antenna_dvbt && state->antenna_gpio)
6413 state->m_GPIO |= state->antenna_gpio;
6414 else
6415 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006416
6417 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006418
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006419 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6420 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006421
6422 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006423 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006424 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006425
6426 /* Initialize the supported delivery systems */
6427 n = 0;
6428 if (state->m_hasDVBC) {
6429 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6430 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6431 strlcat(state->frontend.ops.info.name, " DVB-C",
6432 sizeof(state->frontend.ops.info.name));
6433 }
6434 if (state->m_hasDVBT) {
6435 state->frontend.ops.delsys[n++] = SYS_DVBT;
6436 strlcat(state->frontend.ops.info.name, " DVB-T",
6437 sizeof(state->frontend.ops.info.name));
6438 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006439
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006440 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006441 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006442
6443error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006444 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006445 kfree(state);
6446 return NULL;
6447}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006448EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006449
6450MODULE_DESCRIPTION("DRX-K driver");
6451MODULE_AUTHOR("Ralph Metzler");
6452MODULE_LICENSE("GPL");