blob: 4cb8d1e83fb0ab82f6147bfef7b52a698092e140 [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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001383 u32 Address;
1384 u16 nBlocks;
1385 u16 BlockSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001386 u32 offset = 0;
1387 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001388 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001390 dprintk(1, "\n");
1391
Hans Verkuil5becbc52012-05-14 10:22:58 -03001392 /* down the drain (we don't care about MAGIC_WORD) */
1393#if 0
1394 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395 Drain = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001396#endif
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
Hans Verkuil5becbc52012-05-14 10:22:58 -03001413#if 0
1414 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415 Flags = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001416#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419
Hans Verkuil5becbc52012-05-14 10:22:58 -03001420#if 0
1421 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001423#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001424 pSrc += sizeof(u16);
1425 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001426
1427 if (offset + BlockSize > Length) {
1428 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1429 return -EINVAL;
1430 }
1431
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001432 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001433 if (status < 0) {
1434 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001436 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 pSrc += BlockSize;
1438 offset += BlockSize;
1439 }
1440 return status;
1441}
1442
1443static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1444{
1445 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001446 u16 data = 0;
1447 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1449 unsigned long end;
1450
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001451 dprintk(1, "\n");
1452
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001453 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001454 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1456 }
1457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001458 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1459 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 /* tokenring already has correct status */
1461 return status;
1462 }
1463 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465
Oliver Endrissebc7de22011-07-03 13:49:44 -03001466 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001467 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001468 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001469 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001470 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001471 msleep(1);
1472 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001474 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001475 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001476 }
1477 return status;
1478}
1479
1480static int MPEGTSStop(struct drxk_state *state)
1481{
1482 int status = 0;
1483 u16 fecOcSncMode = 0;
1484 u16 fecOcIprMode = 0;
1485
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001486 dprintk(1, "\n");
1487
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001488 /* Gracefull shutdown (byte boundaries) */
1489 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1490 if (status < 0)
1491 goto error;
1492 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1493 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1494 if (status < 0)
1495 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001497 /* Suppress MCLK during absence of data */
1498 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1499 if (status < 0)
1500 goto error;
1501 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1502 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1503
1504error:
1505 if (status < 0)
1506 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1507
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001508 return status;
1509}
1510
1511static int scu_command(struct drxk_state *state,
1512 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001513 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514{
1515#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1516#error DRXK register mapping no longer compatible with this routine!
1517#endif
1518 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001519 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001521 u8 buffer[34];
1522 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001523 const char *p;
1524 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001526 dprintk(1, "\n");
1527
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001528 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001529 ((resultLen > 0) && (result == NULL))) {
1530 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1531 return status;
1532 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001533
1534 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001535
1536 /* assume that the command register is ready
1537 since it is checked afterwards */
1538 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1539 buffer[cnt++] = (parameter[ii] & 0xFF);
1540 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1541 }
1542 buffer[cnt++] = (cmd & 0xFF);
1543 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1544
1545 write_block(state, SCU_RAM_PARAM_0__A -
1546 (parameterLen - 1), cnt, buffer);
1547 /* Wait until SCU has processed command */
1548 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001549 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001550 msleep(1);
1551 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1552 if (status < 0)
1553 goto error;
1554 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1555 if (curCmd != DRX_SCU_READY) {
1556 printk(KERN_ERR "drxk: SCU not ready\n");
1557 status = -EIO;
1558 goto error2;
1559 }
1560 /* read results */
1561 if ((resultLen > 0) && (result != NULL)) {
1562 s16 err;
1563 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001564
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001565 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1566 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001567 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001568 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001569 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001570
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001571 /* Check if an error was reported by SCU */
1572 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001573 if (err >= 0)
1574 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001575
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001576 /* check for the known error codes */
1577 switch (err) {
1578 case SCU_RESULT_UNKCMD:
1579 p = "SCU_RESULT_UNKCMD";
1580 break;
1581 case SCU_RESULT_UNKSTD:
1582 p = "SCU_RESULT_UNKSTD";
1583 break;
1584 case SCU_RESULT_SIZE:
1585 p = "SCU_RESULT_SIZE";
1586 break;
1587 case SCU_RESULT_INVPAR:
1588 p = "SCU_RESULT_INVPAR";
1589 break;
1590 default: /* Other negative values are errors */
1591 sprintf(errname, "ERROR: %d\n", err);
1592 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001593 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001594 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1595 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1596 status = -EINVAL;
1597 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001598 }
1599
1600error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001601 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001602 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001603error2:
1604 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001605 return status;
1606}
1607
1608static int SetIqmAf(struct drxk_state *state, bool active)
1609{
1610 u16 data = 0;
1611 int status;
1612
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001613 dprintk(1, "\n");
1614
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001615 /* Configure IQM */
1616 status = read16(state, IQM_AF_STDBY__A, &data);
1617 if (status < 0)
1618 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001619
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001620 if (!active) {
1621 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1622 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1623 | IQM_AF_STDBY_STDBY_PD_STANDBY
1624 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1625 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1626 } else {
1627 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1628 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1629 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1630 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1631 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1632 );
1633 }
1634 status = write16(state, IQM_AF_STDBY__A, data);
1635
1636error:
1637 if (status < 0)
1638 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001639 return status;
1640}
1641
Oliver Endrissebc7de22011-07-03 13:49:44 -03001642static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001643{
1644 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001645 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001646
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001647 dprintk(1, "\n");
1648
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001649 /* Check arguments */
1650 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001651 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001652
1653 switch (*mode) {
1654 case DRX_POWER_UP:
1655 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1656 break;
1657 case DRXK_POWER_DOWN_OFDM:
1658 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1659 break;
1660 case DRXK_POWER_DOWN_CORE:
1661 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1662 break;
1663 case DRXK_POWER_DOWN_PLL:
1664 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1665 break;
1666 case DRX_POWER_DOWN:
1667 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1668 break;
1669 default:
1670 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001671 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001672 }
1673
1674 /* If already in requested power mode, do nothing */
1675 if (state->m_currentPowerMode == *mode)
1676 return 0;
1677
1678 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001679 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001680 status = PowerUpDevice(state);
1681 if (status < 0)
1682 goto error;
1683 status = DVBTEnableOFDMTokenRing(state, true);
1684 if (status < 0)
1685 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001686 }
1687
1688 if (*mode == DRX_POWER_UP) {
1689 /* Restore analog & pin configuartion */
1690 } else {
1691 /* Power down to requested mode */
1692 /* Backup some register settings */
1693 /* Set pins with possible pull-ups connected
1694 to them in input mode */
1695 /* Analog power down */
1696 /* ADC power down */
1697 /* Power down device */
1698 /* stop all comm_exec */
1699 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001700 switch (state->m_OperationMode) {
1701 case OM_DVBT:
1702 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001703 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001704 goto error;
1705 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001706 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001707 goto error;
1708 break;
1709 case OM_QAM_ITU_A:
1710 case OM_QAM_ITU_C:
1711 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001712 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001713 goto error;
1714 status = PowerDownQAM(state);
1715 if (status < 0)
1716 goto error;
1717 break;
1718 default:
1719 break;
1720 }
1721 status = DVBTEnableOFDMTokenRing(state, false);
1722 if (status < 0)
1723 goto error;
1724 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1725 if (status < 0)
1726 goto error;
1727 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1728 if (status < 0)
1729 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001730
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001731 if (*mode != DRXK_POWER_DOWN_OFDM) {
1732 state->m_HICfgCtrl |=
1733 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1734 status = HI_CfgCommand(state);
1735 if (status < 0)
1736 goto error;
1737 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001738 }
1739 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001740
1741error:
1742 if (status < 0)
1743 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1744
Oliver Endrissebc7de22011-07-03 13:49:44 -03001745 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001746}
1747
1748static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1749{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001750 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751 u16 cmdResult = 0;
1752 u16 data = 0;
1753 int status;
1754
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001755 dprintk(1, "\n");
1756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001757 status = read16(state, SCU_COMM_EXEC__A, &data);
1758 if (status < 0)
1759 goto error;
1760 if (data == SCU_COMM_EXEC_ACTIVE) {
1761 /* Send OFDM stop command */
1762 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 -03001763 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001764 goto error;
1765 /* Send OFDM reset command */
1766 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1767 if (status < 0)
1768 goto error;
1769 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001771 /* Reset datapath for OFDM, processors first */
1772 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1773 if (status < 0)
1774 goto error;
1775 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1776 if (status < 0)
1777 goto error;
1778 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1779 if (status < 0)
1780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001782 /* powerdown AFE */
1783 status = SetIqmAf(state, false);
1784 if (status < 0)
1785 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001787 /* powerdown to OFDM mode */
1788 if (setPowerMode) {
1789 status = CtrlPowerMode(state, &powerMode);
1790 if (status < 0)
1791 goto error;
1792 }
1793error:
1794 if (status < 0)
1795 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001796 return status;
1797}
1798
Oliver Endrissebc7de22011-07-03 13:49:44 -03001799static int SetOperationMode(struct drxk_state *state,
1800 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801{
1802 int status = 0;
1803
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001804 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001805 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001806 Stop and power down previous standard
1807 TODO investigate total power down instead of partial
1808 power down depending on "previous" standard.
1809 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001811 /* disable HW lock indicator */
1812 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1813 if (status < 0)
1814 goto error;
1815
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001816 /* Device is already at the required mode */
1817 if (state->m_OperationMode == oMode)
1818 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001819
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001820 switch (state->m_OperationMode) {
1821 /* OM_NONE was added for start up */
1822 case OM_NONE:
1823 break;
1824 case OM_DVBT:
1825 status = MPEGTSStop(state);
1826 if (status < 0)
1827 goto error;
1828 status = PowerDownDVBT(state, true);
1829 if (status < 0)
1830 goto error;
1831 state->m_OperationMode = OM_NONE;
1832 break;
1833 case OM_QAM_ITU_A: /* fallthrough */
1834 case OM_QAM_ITU_C:
1835 status = MPEGTSStop(state);
1836 if (status < 0)
1837 goto error;
1838 status = PowerDownQAM(state);
1839 if (status < 0)
1840 goto error;
1841 state->m_OperationMode = OM_NONE;
1842 break;
1843 case OM_QAM_ITU_B:
1844 default:
1845 status = -EINVAL;
1846 goto error;
1847 }
1848
1849 /*
1850 Power up new standard
1851 */
1852 switch (oMode) {
1853 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001854 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001855 state->m_OperationMode = oMode;
1856 status = SetDVBTStandard(state, oMode);
1857 if (status < 0)
1858 goto error;
1859 break;
1860 case OM_QAM_ITU_A: /* fallthrough */
1861 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001862 dprintk(1, ": DVB-C Annex %c\n",
1863 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001864 state->m_OperationMode = oMode;
1865 status = SetQAMStandard(state, oMode);
1866 if (status < 0)
1867 goto error;
1868 break;
1869 case OM_QAM_ITU_B:
1870 default:
1871 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001872 }
1873error:
1874 if (status < 0)
1875 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1876 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001877}
1878
1879static int Start(struct drxk_state *state, s32 offsetFreq,
1880 s32 IntermediateFrequency)
1881{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001882 int status = -EINVAL;
1883
1884 u16 IFreqkHz;
1885 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001887 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001888 if (state->m_DrxkState != DRXK_STOPPED &&
1889 state->m_DrxkState != DRXK_DTV_STARTED)
1890 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001891
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001892 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001893
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001894 if (IntermediateFrequency < 0) {
1895 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1896 IntermediateFrequency = -IntermediateFrequency;
1897 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001898
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001899 switch (state->m_OperationMode) {
1900 case OM_QAM_ITU_A:
1901 case OM_QAM_ITU_C:
1902 IFreqkHz = (IntermediateFrequency / 1000);
1903 status = SetQAM(state, IFreqkHz, OffsetkHz);
1904 if (status < 0)
1905 goto error;
1906 state->m_DrxkState = DRXK_DTV_STARTED;
1907 break;
1908 case OM_DVBT:
1909 IFreqkHz = (IntermediateFrequency / 1000);
1910 status = MPEGTSStop(state);
1911 if (status < 0)
1912 goto error;
1913 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1914 if (status < 0)
1915 goto error;
1916 status = DVBTStart(state);
1917 if (status < 0)
1918 goto error;
1919 state->m_DrxkState = DRXK_DTV_STARTED;
1920 break;
1921 default:
1922 break;
1923 }
1924error:
1925 if (status < 0)
1926 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001927 return status;
1928}
1929
1930static int ShutDown(struct drxk_state *state)
1931{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001932 dprintk(1, "\n");
1933
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001934 MPEGTSStop(state);
1935 return 0;
1936}
1937
Oliver Endrissebc7de22011-07-03 13:49:44 -03001938static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1939 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001940{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001941 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001942
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001943 dprintk(1, "\n");
1944
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001945 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001946 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001947
1948 *pLockStatus = NOT_LOCKED;
1949
1950 /* define the SCU command code */
1951 switch (state->m_OperationMode) {
1952 case OM_QAM_ITU_A:
1953 case OM_QAM_ITU_B:
1954 case OM_QAM_ITU_C:
1955 status = GetQAMLockStatus(state, pLockStatus);
1956 break;
1957 case OM_DVBT:
1958 status = GetDVBTLockStatus(state, pLockStatus);
1959 break;
1960 default:
1961 break;
1962 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963error:
1964 if (status < 0)
1965 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001966 return status;
1967}
1968
1969static int MPEGTSStart(struct drxk_state *state)
1970{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001971 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001972
1973 u16 fecOcSncMode = 0;
1974
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001975 /* Allow OC to sync again */
1976 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1977 if (status < 0)
1978 goto error;
1979 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1980 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1981 if (status < 0)
1982 goto error;
1983 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1984error:
1985 if (status < 0)
1986 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001987 return status;
1988}
1989
1990static int MPEGTSDtoInit(struct drxk_state *state)
1991{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001992 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001993
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001994 dprintk(1, "\n");
1995
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001996 /* Rate integration settings */
1997 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1998 if (status < 0)
1999 goto error;
2000 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
2001 if (status < 0)
2002 goto error;
2003 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2004 if (status < 0)
2005 goto error;
2006 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2007 if (status < 0)
2008 goto error;
2009 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2010 if (status < 0)
2011 goto error;
2012 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2013 if (status < 0)
2014 goto error;
2015 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2016 if (status < 0)
2017 goto error;
2018 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2019 if (status < 0)
2020 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002021
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002022 /* Additional configuration */
2023 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2024 if (status < 0)
2025 goto error;
2026 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2027 if (status < 0)
2028 goto error;
2029 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2030error:
2031 if (status < 0)
2032 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2033
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002034 return status;
2035}
2036
Oliver Endrissebc7de22011-07-03 13:49:44 -03002037static int MPEGTSDtoSetup(struct drxk_state *state,
2038 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002039{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002040 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041
Oliver Endrissebc7de22011-07-03 13:49:44 -03002042 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2043 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2044 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2045 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2046 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2047 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2048 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002049 u16 fecOcTmdMode = 0;
2050 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002051 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002052 bool staticCLK = false;
2053
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002054 dprintk(1, "\n");
2055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002056 /* Check insertion of the Reed-Solomon parity bytes */
2057 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2058 if (status < 0)
2059 goto error;
2060 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2061 if (status < 0)
2062 goto error;
2063 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2064 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2065 if (state->m_insertRSByte == true) {
2066 /* enable parity symbol forward */
2067 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2068 /* MVAL disable during parity bytes */
2069 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2070 /* TS burst length to 204 */
2071 fecOcDtoBurstLen = 204;
2072 }
2073
2074 /* Check serial or parrallel output */
2075 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2076 if (state->m_enableParallel == false) {
2077 /* MPEG data output is serial -> set ipr_mode[0] */
2078 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2079 }
2080
2081 switch (oMode) {
2082 case OM_DVBT:
2083 maxBitRate = state->m_DVBTBitrate;
2084 fecOcTmdMode = 3;
2085 fecOcRcnCtlRate = 0xC00000;
2086 staticCLK = state->m_DVBTStaticCLK;
2087 break;
2088 case OM_QAM_ITU_A: /* fallthrough */
2089 case OM_QAM_ITU_C:
2090 fecOcTmdMode = 0x0004;
2091 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2092 maxBitRate = state->m_DVBCBitrate;
2093 staticCLK = state->m_DVBCStaticCLK;
2094 break;
2095 default:
2096 status = -EINVAL;
2097 } /* switch (standard) */
2098 if (status < 0)
2099 goto error;
2100
2101 /* Configure DTO's */
2102 if (staticCLK) {
2103 u32 bitRate = 0;
2104
2105 /* Rational DTO for MCLK source (static MCLK rate),
2106 Dynamic DTO for optimal grouping
2107 (avoid intra-packet gaps),
2108 DTO offset enable to sync TS burst with MSTRT */
2109 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2110 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2111 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2112 FEC_OC_FCT_MODE_VIRT_ENA__M);
2113
2114 /* Check user defined bitrate */
2115 bitRate = maxBitRate;
2116 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2117 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002118 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002119 /* Rational DTO period:
2120 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002122 Result should be floored,
2123 to make sure >= requested bitrate
2124 */
2125 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2126 * 1000) / bitRate);
2127 if (fecOcDtoPeriod <= 2)
2128 fecOcDtoPeriod = 0;
2129 else
2130 fecOcDtoPeriod -= 2;
2131 fecOcTmdIntUpdRate = 8;
2132 } else {
2133 /* (commonAttr->staticCLK == false) => dynamic mode */
2134 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2135 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2136 fecOcTmdIntUpdRate = 5;
2137 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002138
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002139 /* Write appropriate registers with requested configuration */
2140 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2141 if (status < 0)
2142 goto error;
2143 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2144 if (status < 0)
2145 goto error;
2146 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2147 if (status < 0)
2148 goto error;
2149 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2150 if (status < 0)
2151 goto error;
2152 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2153 if (status < 0)
2154 goto error;
2155 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2156 if (status < 0)
2157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002158
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002159 /* Rate integration settings */
2160 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2161 if (status < 0)
2162 goto error;
2163 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2164 if (status < 0)
2165 goto error;
2166 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2167error:
2168 if (status < 0)
2169 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170 return status;
2171}
2172
2173static int MPEGTSConfigurePolarity(struct drxk_state *state)
2174{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002175 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002176
2177 /* Data mask for the output data byte */
2178 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002179 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2180 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2181 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2182 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002183
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002184 dprintk(1, "\n");
2185
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002186 /* Control selective inversion of output bits */
2187 fecOcRegIprInvert &= (~(InvertDataMask));
2188 if (state->m_invertDATA == true)
2189 fecOcRegIprInvert |= InvertDataMask;
2190 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2191 if (state->m_invertERR == true)
2192 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2193 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2194 if (state->m_invertSTR == true)
2195 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2196 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2197 if (state->m_invertVAL == true)
2198 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2199 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2200 if (state->m_invertCLK == true)
2201 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002202
2203 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002204}
2205
2206#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2207
2208static int SetAgcRf(struct drxk_state *state,
2209 struct SCfgAgc *pAgcCfg, bool isDTV)
2210{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002211 int status = -EINVAL;
2212 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213 struct SCfgAgc *pIfAgcSettings;
2214
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002215 dprintk(1, "\n");
2216
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002217 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002218 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002219
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002220 switch (pAgcCfg->ctrlMode) {
2221 case DRXK_AGC_CTRL_AUTO:
2222 /* Enable RF AGC DAC */
2223 status = read16(state, IQM_AF_STDBY__A, &data);
2224 if (status < 0)
2225 goto error;
2226 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2227 status = write16(state, IQM_AF_STDBY__A, data);
2228 if (status < 0)
2229 goto error;
2230 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2231 if (status < 0)
2232 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002234 /* Enable SCU RF AGC loop */
2235 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002236
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002237 /* Polarity */
2238 if (state->m_RfAgcPol)
2239 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2240 else
2241 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2242 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2243 if (status < 0)
2244 goto error;
2245
2246 /* Set speed (using complementary reduction value) */
2247 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2248 if (status < 0)
2249 goto error;
2250
2251 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2252 data |= (~(pAgcCfg->speed <<
2253 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2254 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2255
2256 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2257 if (status < 0)
2258 goto error;
2259
2260 if (IsDVBT(state))
2261 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2262 else if (IsQAM(state))
2263 pIfAgcSettings = &state->m_qamIfAgcCfg;
2264 else
2265 pIfAgcSettings = &state->m_atvIfAgcCfg;
2266 if (pIfAgcSettings == NULL) {
2267 status = -EINVAL;
2268 goto error;
2269 }
2270
2271 /* Set TOP, only if IF-AGC is in AUTO mode */
2272 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2273 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002274 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002275 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002276
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002277 /* Cut-Off current */
2278 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2279 if (status < 0)
2280 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002281
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002282 /* Max. output level */
2283 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2284 if (status < 0)
2285 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002286
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002287 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002288
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002289 case DRXK_AGC_CTRL_USER:
2290 /* Enable RF AGC DAC */
2291 status = read16(state, IQM_AF_STDBY__A, &data);
2292 if (status < 0)
2293 goto error;
2294 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2295 status = write16(state, IQM_AF_STDBY__A, data);
2296 if (status < 0)
2297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 /* Disable SCU RF AGC loop */
2300 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2301 if (status < 0)
2302 goto error;
2303 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2304 if (state->m_RfAgcPol)
2305 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2306 else
2307 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2308 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2309 if (status < 0)
2310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002311
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002312 /* SCU c.o.c. to 0, enabling full control range */
2313 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2314 if (status < 0)
2315 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002317 /* Write value to output pin */
2318 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2319 if (status < 0)
2320 goto error;
2321 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002323 case DRXK_AGC_CTRL_OFF:
2324 /* Disable RF AGC DAC */
2325 status = read16(state, IQM_AF_STDBY__A, &data);
2326 if (status < 0)
2327 goto error;
2328 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2329 status = write16(state, IQM_AF_STDBY__A, data);
2330 if (status < 0)
2331 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002333 /* Disable SCU RF AGC loop */
2334 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2335 if (status < 0)
2336 goto error;
2337 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2338 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2339 if (status < 0)
2340 goto error;
2341 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002342
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002343 default:
2344 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002345
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002346 }
2347error:
2348 if (status < 0)
2349 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002350 return status;
2351}
2352
2353#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2354
Oliver Endrissebc7de22011-07-03 13:49:44 -03002355static int SetAgcIf(struct drxk_state *state,
2356 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002357{
2358 u16 data = 0;
2359 int status = 0;
2360 struct SCfgAgc *pRfAgcSettings;
2361
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002362 dprintk(1, "\n");
2363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002364 switch (pAgcCfg->ctrlMode) {
2365 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002366
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002367 /* Enable IF AGC DAC */
2368 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002369 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002370 goto error;
2371 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2372 status = write16(state, IQM_AF_STDBY__A, data);
2373 if (status < 0)
2374 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002375
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002376 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2377 if (status < 0)
2378 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002379
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002380 /* Enable SCU IF AGC loop */
2381 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2382
2383 /* Polarity */
2384 if (state->m_IfAgcPol)
2385 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2386 else
2387 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2388 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2389 if (status < 0)
2390 goto error;
2391
2392 /* Set speed (using complementary reduction value) */
2393 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2394 if (status < 0)
2395 goto error;
2396 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2397 data |= (~(pAgcCfg->speed <<
2398 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2399 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2400
2401 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2402 if (status < 0)
2403 goto error;
2404
2405 if (IsQAM(state))
2406 pRfAgcSettings = &state->m_qamRfAgcCfg;
2407 else
2408 pRfAgcSettings = &state->m_atvRfAgcCfg;
2409 if (pRfAgcSettings == NULL)
2410 return -1;
2411 /* Restore TOP */
2412 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2413 if (status < 0)
2414 goto error;
2415 break;
2416
2417 case DRXK_AGC_CTRL_USER:
2418
2419 /* Enable IF AGC DAC */
2420 status = read16(state, IQM_AF_STDBY__A, &data);
2421 if (status < 0)
2422 goto error;
2423 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2424 status = write16(state, IQM_AF_STDBY__A, data);
2425 if (status < 0)
2426 goto error;
2427
2428 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2429 if (status < 0)
2430 goto error;
2431
2432 /* Disable SCU IF AGC loop */
2433 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2434
2435 /* Polarity */
2436 if (state->m_IfAgcPol)
2437 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2438 else
2439 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2440 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2441 if (status < 0)
2442 goto error;
2443
2444 /* Write value to output pin */
2445 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2446 if (status < 0)
2447 goto error;
2448 break;
2449
2450 case DRXK_AGC_CTRL_OFF:
2451
2452 /* Disable If AGC DAC */
2453 status = read16(state, IQM_AF_STDBY__A, &data);
2454 if (status < 0)
2455 goto error;
2456 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2457 status = write16(state, IQM_AF_STDBY__A, data);
2458 if (status < 0)
2459 goto error;
2460
2461 /* Disable SCU IF AGC loop */
2462 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2463 if (status < 0)
2464 goto error;
2465 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2466 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2467 if (status < 0)
2468 goto error;
2469 break;
2470 } /* switch (agcSettingsIf->ctrlMode) */
2471
2472 /* always set the top to support
2473 configurations without if-loop */
2474 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2475error:
2476 if (status < 0)
2477 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002478 return status;
2479}
2480
2481static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2482{
2483 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002484 int status;
2485 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002486
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002487 dprintk(1, "\n");
2488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002489 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2490 if (status < 0) {
2491 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2492 return status;
2493 }
2494
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002495 *pValue = 0;
2496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002497 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2498 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2499 if (Level < 14000)
2500 *pValue = (14000 - Level) / 4;
2501 else
2502 *pValue = 0;
2503
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002504 return status;
2505}
2506
Oliver Endrissebc7de22011-07-03 13:49:44 -03002507static int GetQAMSignalToNoise(struct drxk_state *state,
2508 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002509{
2510 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 u16 qamSlErrPower = 0; /* accum. error between
2512 raw and sliced symbols */
2513 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002514 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002515 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002516
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002517 dprintk(1, "\n");
2518
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002519 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002520
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002521 /* get the register value needed for MER */
2522 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2523 if (status < 0) {
2524 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2525 return -EINVAL;
2526 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002527
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002528 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002529 case QAM_16:
2530 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2531 break;
2532 case QAM_32:
2533 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2534 break;
2535 case QAM_64:
2536 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2537 break;
2538 case QAM_128:
2539 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2540 break;
2541 default:
2542 case QAM_256:
2543 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2544 break;
2545 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002546
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002547 if (qamSlErrPower > 0) {
2548 qamSlMer = Log10Times100(qamSlSigPower) -
2549 Log10Times100((u32) qamSlErrPower);
2550 }
2551 *pSignalToNoise = qamSlMer;
2552
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002553 return status;
2554}
2555
Oliver Endrissebc7de22011-07-03 13:49:44 -03002556static int GetDVBTSignalToNoise(struct drxk_state *state,
2557 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002559 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002560 u16 regData = 0;
2561 u32 EqRegTdSqrErrI = 0;
2562 u32 EqRegTdSqrErrQ = 0;
2563 u16 EqRegTdSqrErrExp = 0;
2564 u16 EqRegTdTpsPwrOfs = 0;
2565 u16 EqRegTdReqSmbCnt = 0;
2566 u32 tpsCnt = 0;
2567 u32 SqrErrIQ = 0;
2568 u32 a = 0;
2569 u32 b = 0;
2570 u32 c = 0;
2571 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002572 u16 transmissionParams = 0;
2573
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002574 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002575
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002576 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2577 if (status < 0)
2578 goto error;
2579 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2580 if (status < 0)
2581 goto error;
2582 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2583 if (status < 0)
2584 goto error;
2585 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2586 if (status < 0)
2587 goto error;
2588 /* Extend SQR_ERR_I operational range */
2589 EqRegTdSqrErrI = (u32) regData;
2590 if ((EqRegTdSqrErrExp > 11) &&
2591 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2592 EqRegTdSqrErrI += 0x00010000UL;
2593 }
2594 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2595 if (status < 0)
2596 goto error;
2597 /* Extend SQR_ERR_Q operational range */
2598 EqRegTdSqrErrQ = (u32) regData;
2599 if ((EqRegTdSqrErrExp > 11) &&
2600 (EqRegTdSqrErrQ < 0x00000FFFUL))
2601 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002603 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2604 if (status < 0)
2605 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002606
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002607 /* Check input data for MER */
2608
2609 /* MER calculation (in 0.1 dB) without math.h */
2610 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2611 iMER = 0;
2612 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2613 /* No error at all, this must be the HW reset value
2614 * Apparently no first measurement yet
2615 * Set MER to 0.0 */
2616 iMER = 0;
2617 } else {
2618 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2619 EqRegTdSqrErrExp;
2620 if ((transmissionParams &
2621 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2622 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2623 tpsCnt = 17;
2624 else
2625 tpsCnt = 68;
2626
2627 /* IMER = 100 * log10 (x)
2628 where x = (EqRegTdTpsPwrOfs^2 *
2629 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2630
2631 => IMER = a + b -c
2632 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2633 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2634 c = 100 * log10 (SqrErrIQ)
2635 */
2636
2637 /* log(x) x = 9bits * 9bits->18 bits */
2638 a = Log10Times100(EqRegTdTpsPwrOfs *
2639 EqRegTdTpsPwrOfs);
2640 /* log(x) x = 16bits * 7bits->23 bits */
2641 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2642 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2643 c = Log10Times100(SqrErrIQ);
2644
2645 iMER = a + b;
2646 /* No negative MER, clip to zero */
2647 if (iMER > c)
2648 iMER -= c;
2649 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002651 }
2652 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002653
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002654error:
2655 if (status < 0)
2656 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002657 return status;
2658}
2659
2660static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2661{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002662 dprintk(1, "\n");
2663
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002664 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002665 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002666 case OM_DVBT:
2667 return GetDVBTSignalToNoise(state, pSignalToNoise);
2668 case OM_QAM_ITU_A:
2669 case OM_QAM_ITU_C:
2670 return GetQAMSignalToNoise(state, pSignalToNoise);
2671 default:
2672 break;
2673 }
2674 return 0;
2675}
2676
2677#if 0
2678static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2679{
2680 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2681 int status = 0;
2682
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002683 dprintk(1, "\n");
2684
Oliver Endrissebc7de22011-07-03 13:49:44 -03002685 static s32 QE_SN[] = {
2686 51, /* QPSK 1/2 */
2687 69, /* QPSK 2/3 */
2688 79, /* QPSK 3/4 */
2689 89, /* QPSK 5/6 */
2690 97, /* QPSK 7/8 */
2691 108, /* 16-QAM 1/2 */
2692 131, /* 16-QAM 2/3 */
2693 146, /* 16-QAM 3/4 */
2694 156, /* 16-QAM 5/6 */
2695 160, /* 16-QAM 7/8 */
2696 165, /* 64-QAM 1/2 */
2697 187, /* 64-QAM 2/3 */
2698 202, /* 64-QAM 3/4 */
2699 216, /* 64-QAM 5/6 */
2700 225, /* 64-QAM 7/8 */
2701 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002702
2703 *pQuality = 0;
2704
2705 do {
2706 s32 SignalToNoise = 0;
2707 u16 Constellation = 0;
2708 u16 CodeRate = 0;
2709 u32 SignalToNoiseRel;
2710 u32 BERQuality;
2711
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002712 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2713 if (status < 0)
2714 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002715 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002716 if (status < 0)
2717 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2719
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002720 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002721 if (status < 0)
2722 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002723 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2724
2725 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2726 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2727 break;
2728 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 BERQuality = 100;
2731
Oliver Endrissebc7de22011-07-03 13:49:44 -03002732 if (SignalToNoiseRel < -70)
2733 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002734 else if (SignalToNoiseRel < 30)
2735 *pQuality = ((SignalToNoiseRel + 70) *
2736 BERQuality) / 100;
2737 else
2738 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002739 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740 return 0;
2741};
2742
Oliver Endrissebc7de22011-07-03 13:49:44 -03002743static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002744{
2745 int status = 0;
2746 *pQuality = 0;
2747
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002748 dprintk(1, "\n");
2749
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750 do {
2751 u32 SignalToNoise = 0;
2752 u32 BERQuality = 100;
2753 u32 SignalToNoiseRel = 0;
2754
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002755 status = GetQAMSignalToNoise(state, &SignalToNoise);
2756 if (status < 0)
2757 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002758
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002759 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002760 case QAM_16:
2761 SignalToNoiseRel = SignalToNoise - 200;
2762 break;
2763 case QAM_32:
2764 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002765 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002766 case QAM_64:
2767 SignalToNoiseRel = SignalToNoise - 260;
2768 break;
2769 case QAM_128:
2770 SignalToNoiseRel = SignalToNoise - 290;
2771 break;
2772 default:
2773 case QAM_256:
2774 SignalToNoiseRel = SignalToNoise - 320;
2775 break;
2776 }
2777
2778 if (SignalToNoiseRel < -70)
2779 *pQuality = 0;
2780 else if (SignalToNoiseRel < 30)
2781 *pQuality = ((SignalToNoiseRel + 70) *
2782 BERQuality) / 100;
2783 else
2784 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002785 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002786
2787 return status;
2788}
2789
2790static int GetQuality(struct drxk_state *state, s32 *pQuality)
2791{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002792 dprintk(1, "\n");
2793
Oliver Endrissebc7de22011-07-03 13:49:44 -03002794 switch (state->m_OperationMode) {
2795 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002796 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002797 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002798 return GetDVBCQuality(state, pQuality);
2799 default:
2800 break;
2801 }
2802
2803 return 0;
2804}
2805#endif
2806
2807/* Free data ram in SIO HI */
2808#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2809#define SIO_HI_RA_RAM_USR_END__A 0x420060
2810
2811#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2812#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2813#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2814#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2815
2816#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2817#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2818#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2819
2820static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2821{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002822 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002824 dprintk(1, "\n");
2825
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002826 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002827 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002828 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002829 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002831 if (state->no_i2c_bridge)
2832 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002833
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002834 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2835 if (status < 0)
2836 goto error;
2837 if (bEnableBridge) {
2838 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 -03002839 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002840 goto error;
2841 } else {
2842 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2843 if (status < 0)
2844 goto error;
2845 }
2846
2847 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2848
2849error:
2850 if (status < 0)
2851 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002852 return status;
2853}
2854
Oliver Endrissebc7de22011-07-03 13:49:44 -03002855static int SetPreSaw(struct drxk_state *state,
2856 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002858 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002860 dprintk(1, "\n");
2861
Oliver Endrissebc7de22011-07-03 13:49:44 -03002862 if ((pPreSawCfg == NULL)
2863 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002864 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002865
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002866 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002867error:
2868 if (status < 0)
2869 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002870 return status;
2871}
2872
2873static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002874 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002875{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002876 u16 blStatus = 0;
2877 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2878 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2879 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002880 unsigned long end;
2881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002882 dprintk(1, "\n");
2883
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002884 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002885 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2886 if (status < 0)
2887 goto error;
2888 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2889 if (status < 0)
2890 goto error;
2891 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2892 if (status < 0)
2893 goto error;
2894 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2895 if (status < 0)
2896 goto error;
2897 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2898 if (status < 0)
2899 goto error;
2900 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2901 if (status < 0)
2902 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002903
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002904 end = jiffies + msecs_to_jiffies(timeOut);
2905 do {
2906 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2907 if (status < 0)
2908 goto error;
2909 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2910 if (blStatus == 0x1) {
2911 printk(KERN_ERR "drxk: SIO not ready\n");
2912 status = -EINVAL;
2913 goto error2;
2914 }
2915error:
2916 if (status < 0)
2917 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2918error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919 mutex_unlock(&state->mutex);
2920 return status;
2921
2922}
2923
Oliver Endrissebc7de22011-07-03 13:49:44 -03002924static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002925{
2926 u16 data = 0;
2927 int status;
2928
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002929 dprintk(1, "\n");
2930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002931 /* Start measurement */
2932 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2933 if (status < 0)
2934 goto error;
2935 status = write16(state, IQM_AF_START_LOCK__A, 1);
2936 if (status < 0)
2937 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002938
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002939 *count = 0;
2940 status = read16(state, IQM_AF_PHASE0__A, &data);
2941 if (status < 0)
2942 goto error;
2943 if (data == 127)
2944 *count = *count + 1;
2945 status = read16(state, IQM_AF_PHASE1__A, &data);
2946 if (status < 0)
2947 goto error;
2948 if (data == 127)
2949 *count = *count + 1;
2950 status = read16(state, IQM_AF_PHASE2__A, &data);
2951 if (status < 0)
2952 goto error;
2953 if (data == 127)
2954 *count = *count + 1;
2955
2956error:
2957 if (status < 0)
2958 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002959 return status;
2960}
2961
2962static int ADCSynchronization(struct drxk_state *state)
2963{
2964 u16 count = 0;
2965 int status;
2966
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002967 dprintk(1, "\n");
2968
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002969 status = ADCSyncMeasurement(state, &count);
2970 if (status < 0)
2971 goto error;
2972
2973 if (count == 1) {
2974 /* Try sampling on a diffrent edge */
2975 u16 clkNeg = 0;
2976
2977 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2978 if (status < 0)
2979 goto error;
2980 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2981 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2982 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2983 clkNeg |=
2984 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2985 } else {
2986 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2987 clkNeg |=
2988 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2989 }
2990 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2991 if (status < 0)
2992 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002993 status = ADCSyncMeasurement(state, &count);
2994 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002995 goto error;
2996 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002997
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002998 if (count < 2)
2999 status = -EINVAL;
3000error:
3001 if (status < 0)
3002 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003003 return status;
3004}
3005
3006static int SetFrequencyShifter(struct drxk_state *state,
3007 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003008 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009{
3010 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003011 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003012 u32 fmFrequencyShift = 0;
3013 bool tunerMirror = !state->m_bMirrorFreqSpect;
3014 u32 adcFreq;
3015 bool adcFlip;
3016 int status;
3017 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003018 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019 u32 frequencyShift;
3020 bool imageToSelect;
3021
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003022 dprintk(1, "\n");
3023
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003025 Program frequency shifter
3026 No need to account for mirroring on RF
3027 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 if (isDTV) {
3029 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3030 (state->m_OperationMode == OM_QAM_ITU_C) ||
3031 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003032 selectPosImage = true;
3033 else
3034 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035 }
3036 if (tunerMirror)
3037 /* tuner doesn't mirror */
3038 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 else
3041 /* tuner mirrors */
3042 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003043 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003044 if (ifFreqActual > samplingFrequency / 2) {
3045 /* adc mirrors */
3046 adcFreq = samplingFrequency - ifFreqActual;
3047 adcFlip = true;
3048 } else {
3049 /* adc doesn't mirror */
3050 adcFreq = ifFreqActual;
3051 adcFlip = false;
3052 }
3053
3054 frequencyShift = adcFreq;
3055 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003056 adcFlip ^ selectPosImage;
3057 state->m_IqmFsRateOfs =
3058 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003059
3060 if (imageToSelect)
3061 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3062
3063 /* Program frequency shifter with tuner offset compensation */
3064 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003065 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3066 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003067 if (status < 0)
3068 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003069 return status;
3070}
3071
3072static int InitAGC(struct drxk_state *state, bool isDTV)
3073{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003074 u16 ingainTgt = 0;
3075 u16 ingainTgtMin = 0;
3076 u16 ingainTgtMax = 0;
3077 u16 clpCyclen = 0;
3078 u16 clpSumMin = 0;
3079 u16 clpDirTo = 0;
3080 u16 snsSumMin = 0;
3081 u16 snsSumMax = 0;
3082 u16 clpSumMax = 0;
3083 u16 snsDirTo = 0;
3084 u16 kiInnergainMin = 0;
3085 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003086 u16 ifIaccuHiTgtMin = 0;
3087 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003088 u16 data = 0;
3089 u16 fastClpCtrlDelay = 0;
3090 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003091 int status = 0;
3092
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003093 dprintk(1, "\n");
3094
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003095 /* Common settings */
3096 snsSumMax = 1023;
3097 ifIaccuHiTgtMin = 2047;
3098 clpCyclen = 500;
3099 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003100
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003101 /* AGCInit() not available for DVBT; init done in microcode */
3102 if (!IsQAM(state)) {
3103 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3104 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003105 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003106
3107 /* FIXME: Analog TV AGC require different settings */
3108
3109 /* Standard specific settings */
3110 clpSumMin = 8;
3111 clpDirTo = (u16) -9;
3112 clpCtrlMode = 0;
3113 snsSumMin = 8;
3114 snsDirTo = (u16) -9;
3115 kiInnergainMin = (u16) -1030;
3116 ifIaccuHiTgtMax = 0x2380;
3117 ifIaccuHiTgt = 0x2380;
3118 ingainTgtMin = 0x0511;
3119 ingainTgt = 0x0511;
3120 ingainTgtMax = 5119;
3121 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003123 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3124 if (status < 0)
3125 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003127 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3131 if (status < 0)
3132 goto error;
3133 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3134 if (status < 0)
3135 goto error;
3136 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3137 if (status < 0)
3138 goto error;
3139 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3161 if (status < 0)
3162 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003163
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003164 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3168 if (status < 0)
3169 goto error;
3170 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3171 if (status < 0)
3172 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003173
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003174 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3178 if (status < 0)
3179 goto error;
3180 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3181 if (status < 0)
3182 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003183
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003184 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3188 if (status < 0)
3189 goto error;
3190 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3191 if (status < 0)
3192 goto error;
3193 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3194 if (status < 0)
3195 goto error;
3196 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3233 if (status < 0)
3234 goto error;
3235 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3236 if (status < 0)
3237 goto error;
3238 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3239 if (status < 0)
3240 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003242 /* Initialize inner-loop KI gain factors */
3243 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3244 if (status < 0)
3245 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003246
3247 data = 0x0657;
3248 data &= ~SCU_RAM_AGC_KI_RF__M;
3249 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3250 data &= ~SCU_RAM_AGC_KI_IF__M;
3251 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3252
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003253 status = write16(state, SCU_RAM_AGC_KI__A, data);
3254error:
3255 if (status < 0)
3256 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257 return status;
3258}
3259
Oliver Endrissebc7de22011-07-03 13:49:44 -03003260static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003261{
3262 int status;
3263
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003264 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003265 if (packetErr == NULL)
3266 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3267 else
3268 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3269 if (status < 0)
3270 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271 return status;
3272}
3273
3274static int DVBTScCommand(struct drxk_state *state,
3275 u16 cmd, u16 subcmd,
3276 u16 param0, u16 param1, u16 param2,
3277 u16 param3, u16 param4)
3278{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003279 u16 curCmd = 0;
3280 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003281 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003282 u16 scExec = 0;
3283 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003285 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003286 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287 if (scExec != 1) {
3288 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003289 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003291 if (status < 0)
3292 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293
3294 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003295 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 do {
3297 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003298 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 retryCnt++;
3300 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003301 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3302 goto error;
3303
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003304 /* Write sub-command */
3305 switch (cmd) {
3306 /* All commands using sub-cmd */
3307 case OFDM_SC_RA_RAM_CMD_PROC_START:
3308 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3309 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003310 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3311 if (status < 0)
3312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003313 break;
3314 default:
3315 /* Do nothing */
3316 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003317 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003318
3319 /* Write needed parameters and the command */
3320 switch (cmd) {
3321 /* All commands using 5 parameters */
3322 /* All commands using 4 parameters */
3323 /* All commands using 3 parameters */
3324 /* All commands using 2 parameters */
3325 case OFDM_SC_RA_RAM_CMD_PROC_START:
3326 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3327 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 /* All commands using 1 parameters */
3330 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3331 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003332 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003333 /* All commands using 0 parameters */
3334 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3335 case OFDM_SC_RA_RAM_CMD_NULL:
3336 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003337 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003338 break;
3339 default:
3340 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003341 status = -EINVAL;
3342 }
3343 if (status < 0)
3344 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345
3346 /* Wait until sc is ready processing command */
3347 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003348 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003350 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003352 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003353 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3354 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355
3356 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003357 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003358 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003359 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003360 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003362 if (status < 0)
3363 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003364
3365 /* Retreive results parameters from SC */
3366 switch (cmd) {
3367 /* All commands yielding 5 results */
3368 /* All commands yielding 4 results */
3369 /* All commands yielding 3 results */
3370 /* All commands yielding 2 results */
3371 /* All commands yielding 1 result */
3372 case OFDM_SC_RA_RAM_CMD_USER_IO:
3373 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003374 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003375 /* All commands yielding 0 results */
3376 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3377 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3378 case OFDM_SC_RA_RAM_CMD_PROC_START:
3379 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3380 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3381 case OFDM_SC_RA_RAM_CMD_NULL:
3382 break;
3383 default:
3384 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003385 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003387 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003388error:
3389 if (status < 0)
3390 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391 return status;
3392}
3393
Oliver Endrissebc7de22011-07-03 13:49:44 -03003394static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003396 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003397 int status;
3398
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003399 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003400 status = CtrlPowerMode(state, &powerMode);
3401 if (status < 0)
3402 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403 return status;
3404}
3405
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003407{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003408 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003410 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003411 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003412 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003413 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003414 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003415 if (status < 0)
3416 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003417 return status;
3418}
3419
3420#define DEFAULT_FR_THRES_8K 4000
3421static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3422{
3423
3424 int status;
3425
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003426 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 if (*enabled == true) {
3428 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003429 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430 DEFAULT_FR_THRES_8K);
3431 } else {
3432 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003433 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003434 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003435 if (status < 0)
3436 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003437
3438 return status;
3439}
3440
3441static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3442 struct DRXKCfgDvbtEchoThres_t *echoThres)
3443{
3444 u16 data = 0;
3445 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003447 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003448 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3449 if (status < 0)
3450 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003451
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003452 switch (echoThres->fftMode) {
3453 case DRX_FFTMODE_2K:
3454 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3455 data |= ((echoThres->threshold <<
3456 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3457 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003458 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 case DRX_FFTMODE_8K:
3460 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3461 data |= ((echoThres->threshold <<
3462 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3463 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003464 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003465 default:
3466 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003467 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003468
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003469 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3470error:
3471 if (status < 0)
3472 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003473 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003474}
3475
3476static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003477 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003479 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003480
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003481 dprintk(1, "\n");
3482
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483 switch (*speed) {
3484 case DRXK_DVBT_SQI_SPEED_FAST:
3485 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3486 case DRXK_DVBT_SQI_SPEED_SLOW:
3487 break;
3488 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003489 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003491 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003492 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003493error:
3494 if (status < 0)
3495 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003496 return status;
3497}
3498
3499/*============================================================================*/
3500
3501/**
3502* \brief Activate DVBT specific presets
3503* \param demod instance of demodulator.
3504* \return DRXStatus_t.
3505*
3506* Called in DVBTSetStandard
3507*
3508*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003509static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003511 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003512 bool setincenable = false;
3513 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003514
Oliver Endrissebc7de22011-07-03 13:49:44 -03003515 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3516 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003518 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003519 status = DVBTCtrlSetIncEnable(state, &setincenable);
3520 if (status < 0)
3521 goto error;
3522 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3523 if (status < 0)
3524 goto error;
3525 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3526 if (status < 0)
3527 goto error;
3528 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3529 if (status < 0)
3530 goto error;
3531 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3532error:
3533 if (status < 0)
3534 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003535 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003536}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003537
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003538/*============================================================================*/
3539
3540/**
3541* \brief Initialize channelswitch-independent settings for DVBT.
3542* \param demod instance of demodulator.
3543* \return DRXStatus_t.
3544*
3545* For ROM code channel filter taps are loaded from the bootloader. For microcode
3546* the DVB-T taps from the drxk_filters.h are used.
3547*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003548static int SetDVBTStandard(struct drxk_state *state,
3549 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003550{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003551 u16 cmdResult = 0;
3552 u16 data = 0;
3553 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003554
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003555 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003556
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003557 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003558 /* added antenna switch */
3559 SwitchAntennaToDVBT(state);
3560 /* send OFDM reset command */
3561 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 -03003562 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003563 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003564
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003565 /* send OFDM setenv command */
3566 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3567 if (status < 0)
3568 goto error;
3569
3570 /* reset datapath for OFDM, processors first */
3571 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3572 if (status < 0)
3573 goto error;
3574 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3575 if (status < 0)
3576 goto error;
3577 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3578 if (status < 0)
3579 goto error;
3580
3581 /* IQM setup */
3582 /* synchronize on ofdstate->m_festart */
3583 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3584 if (status < 0)
3585 goto error;
3586 /* window size for clipping ADC detection */
3587 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3588 if (status < 0)
3589 goto error;
3590 /* window size for for sense pre-SAW detection */
3591 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3592 if (status < 0)
3593 goto error;
3594 /* sense threshold for sense pre-SAW detection */
3595 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3596 if (status < 0)
3597 goto error;
3598 status = SetIqmAf(state, true);
3599 if (status < 0)
3600 goto error;
3601
3602 status = write16(state, IQM_AF_AGC_RF__A, 0);
3603 if (status < 0)
3604 goto error;
3605
3606 /* Impulse noise cruncher setup */
3607 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3611 if (status < 0)
3612 goto error;
3613 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3614 if (status < 0)
3615 goto error;
3616
3617 status = write16(state, IQM_RC_STRETCH__A, 16);
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3621 if (status < 0)
3622 goto error;
3623 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3624 if (status < 0)
3625 goto error;
3626 status = write16(state, IQM_CF_SCALE__A, 1600);
3627 if (status < 0)
3628 goto error;
3629 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3630 if (status < 0)
3631 goto error;
3632
3633 /* virtual clipping threshold for clipping ADC detection */
3634 status = write16(state, IQM_AF_CLP_TH__A, 448);
3635 if (status < 0)
3636 goto error;
3637 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3638 if (status < 0)
3639 goto error;
3640
3641 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3642 if (status < 0)
3643 goto error;
3644
3645 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3646 if (status < 0)
3647 goto error;
3648 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3649 if (status < 0)
3650 goto error;
3651 /* enable power measurement interrupt */
3652 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3653 if (status < 0)
3654 goto error;
3655 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3656 if (status < 0)
3657 goto error;
3658
3659 /* IQM will not be reset from here, sync ADC and update/init AGC */
3660 status = ADCSynchronization(state);
3661 if (status < 0)
3662 goto error;
3663 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3664 if (status < 0)
3665 goto error;
3666
3667 /* Halt SCU to enable safe non-atomic accesses */
3668 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3669 if (status < 0)
3670 goto error;
3671
3672 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3673 if (status < 0)
3674 goto error;
3675 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3676 if (status < 0)
3677 goto error;
3678
3679 /* Set Noise Estimation notch width and enable DC fix */
3680 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3681 if (status < 0)
3682 goto error;
3683 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3684 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3685 if (status < 0)
3686 goto error;
3687
3688 /* Activate SCU to enable SCU commands */
3689 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3690 if (status < 0)
3691 goto error;
3692
3693 if (!state->m_DRXK_A3_ROM_CODE) {
3694 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3695 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3696 if (status < 0)
3697 goto error;
3698 }
3699
3700 /* OFDM_SC setup */
3701#ifdef COMPILE_FOR_NONRT
3702 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3703 if (status < 0)
3704 goto error;
3705 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3706 if (status < 0)
3707 goto error;
3708#endif
3709
3710 /* FEC setup */
3711 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3712 if (status < 0)
3713 goto error;
3714
3715
3716#ifdef COMPILE_FOR_NONRT
3717 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3718 if (status < 0)
3719 goto error;
3720#else
3721 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3722 if (status < 0)
3723 goto error;
3724#endif
3725 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3726 if (status < 0)
3727 goto error;
3728
3729 /* Setup MPEG bus */
3730 status = MPEGTSDtoSetup(state, OM_DVBT);
3731 if (status < 0)
3732 goto error;
3733 /* Set DVBT Presets */
3734 status = DVBTActivatePresets(state);
3735 if (status < 0)
3736 goto error;
3737
3738error:
3739 if (status < 0)
3740 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003741 return status;
3742}
3743
3744/*============================================================================*/
3745/**
3746* \brief Start dvbt demodulating for channel.
3747* \param demod instance of demodulator.
3748* \return DRXStatus_t.
3749*/
3750static int DVBTStart(struct drxk_state *state)
3751{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003752 u16 param1;
3753 int status;
3754 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003755
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003756 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003757 /* Start correct processes to get in lock */
3758 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003759 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3760 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3761 if (status < 0)
3762 goto error;
3763 /* Start FEC OC */
3764 status = MPEGTSStart(state);
3765 if (status < 0)
3766 goto error;
3767 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3768 if (status < 0)
3769 goto error;
3770error:
3771 if (status < 0)
3772 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003773 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774}
3775
3776
3777/*============================================================================*/
3778
3779/**
3780* \brief Set up dvbt demodulator for channel.
3781* \param demod instance of demodulator.
3782* \return DRXStatus_t.
3783* // original DVBTSetChannel()
3784*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003785static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3786 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003788 u16 cmdResult = 0;
3789 u16 transmissionParams = 0;
3790 u16 operationMode = 0;
3791 u32 iqmRcRateOfs = 0;
3792 u32 bandwidth = 0;
3793 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794 int status;
3795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003798 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3799 if (status < 0)
3800 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003802 /* Halt SCU to enable safe non-atomic accesses */
3803 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3804 if (status < 0)
3805 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003807 /* Stop processors */
3808 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3809 if (status < 0)
3810 goto error;
3811 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3812 if (status < 0)
3813 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 /* Mandatory fix, always stop CP, required to set spl offset back to
3816 hardware default (is set to 0 by ucode during pilot detection */
3817 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3818 if (status < 0)
3819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003821 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003823 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003824 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003825 case TRANSMISSION_MODE_AUTO:
3826 default:
3827 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3828 /* fall through , try first guess DRX_FFTMODE_8K */
3829 case TRANSMISSION_MODE_8K:
3830 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003831 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 case TRANSMISSION_MODE_2K:
3833 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003834 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003836
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003837 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003838 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003839 default:
3840 case GUARD_INTERVAL_AUTO:
3841 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3842 /* fall through , try first guess DRX_GUARD_1DIV4 */
3843 case GUARD_INTERVAL_1_4:
3844 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003845 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 case GUARD_INTERVAL_1_32:
3847 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003848 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 case GUARD_INTERVAL_1_16:
3850 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003851 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 case GUARD_INTERVAL_1_8:
3853 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003854 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003855 }
3856
3857 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003858 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003859 case HIERARCHY_AUTO:
3860 case HIERARCHY_NONE:
3861 default:
3862 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3863 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3864 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3865 /* break; */
3866 case HIERARCHY_1:
3867 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3868 break;
3869 case HIERARCHY_2:
3870 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3871 break;
3872 case HIERARCHY_4:
3873 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3874 break;
3875 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003876
3877
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003878 /* modulation */
3879 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003880 case QAM_AUTO:
3881 default:
3882 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3883 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3884 case QAM_64:
3885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3886 break;
3887 case QPSK:
3888 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3889 break;
3890 case QAM_16:
3891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3892 break;
3893 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003894#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003895 /* No hierachical channels support in BDA */
3896 /* Priority (only for hierarchical channels) */
3897 switch (channel->priority) {
3898 case DRX_PRIORITY_LOW:
3899 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3900 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3901 OFDM_EC_SB_PRIOR_LO);
3902 break;
3903 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003904 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003905 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3906 OFDM_EC_SB_PRIOR_HI));
3907 break;
3908 case DRX_PRIORITY_UNKNOWN: /* fall through */
3909 default:
3910 status = -EINVAL;
3911 goto error;
3912 }
3913#else
3914 /* Set Priorty high */
3915 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3916 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3917 if (status < 0)
3918 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003919#endif
3920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003921 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003922 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003923 case FEC_AUTO:
3924 default:
3925 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3926 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3927 case FEC_2_3:
3928 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3929 break;
3930 case FEC_1_2:
3931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3932 break;
3933 case FEC_3_4:
3934 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3935 break;
3936 case FEC_5_6:
3937 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3938 break;
3939 case FEC_7_8:
3940 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3941 break;
3942 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003943
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003944 /* SAW filter selection: normaly not necesarry, but if wanted
3945 the application can select a SAW filter via the driver by using UIOs */
3946 /* First determine real bandwidth (Hz) */
3947 /* Also set delay for impulse noise cruncher */
3948 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3949 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3950 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003951 switch (state->props.bandwidth_hz) {
3952 case 0:
3953 state->props.bandwidth_hz = 8000000;
3954 /* fall though */
3955 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003956 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3957 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003958 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003959 goto error;
3960 /* cochannel protection for PAL 8 MHz */
3961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3962 if (status < 0)
3963 goto error;
3964 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3965 if (status < 0)
3966 goto error;
3967 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3968 if (status < 0)
3969 goto error;
3970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3971 if (status < 0)
3972 goto error;
3973 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003974 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003975 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3976 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3977 if (status < 0)
3978 goto error;
3979 /* cochannel protection for PAL 7 MHz */
3980 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3981 if (status < 0)
3982 goto error;
3983 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3984 if (status < 0)
3985 goto error;
3986 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3987 if (status < 0)
3988 goto error;
3989 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3990 if (status < 0)
3991 goto error;
3992 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003993 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003994 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3995 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3996 if (status < 0)
3997 goto error;
3998 /* cochannel protection for NTSC 6 MHz */
3999 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
4000 if (status < 0)
4001 goto error;
4002 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4003 if (status < 0)
4004 goto error;
4005 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4006 if (status < 0)
4007 goto error;
4008 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4009 if (status < 0)
4010 goto error;
4011 break;
4012 default:
4013 status = -EINVAL;
4014 goto error;
4015 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004017 if (iqmRcRateOfs == 0) {
4018 /* Now compute IQM_RC_RATE_OFS
4019 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4020 =>
4021 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4022 */
4023 /* (SysFreq / BandWidth) * (2^28) */
4024 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4025 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4026 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4027 iqmRcRateOfs = Frac28a((u32)
4028 ((state->m_sysClockFreq *
4029 1000) / 3), bandwidth);
4030 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4031 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4032 iqmRcRateOfs += 0x80L;
4033 iqmRcRateOfs = iqmRcRateOfs >> 7;
4034 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4035 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4036 }
4037
4038 iqmRcRateOfs &=
4039 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4040 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4041 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4042 if (status < 0)
4043 goto error;
4044
4045 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004046
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004047#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004048 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4049 if (status < 0)
4050 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004051#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004052 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4053 if (status < 0)
4054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004056 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004057
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004058 /* Activate SCU to enable SCU commands */
4059 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4060 if (status < 0)
4061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004063 /* Enable SC after setting all other parameters */
4064 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4065 if (status < 0)
4066 goto error;
4067 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4068 if (status < 0)
4069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004070
4071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004072 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4073 if (status < 0)
4074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004076 /* Write SC parameter registers, set all AUTO flags in operation mode */
4077 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4078 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4079 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4080 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4081 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4082 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4083 0, transmissionParams, param1, 0, 0, 0);
4084 if (status < 0)
4085 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004087 if (!state->m_DRXK_A3_ROM_CODE)
4088 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4089error:
4090 if (status < 0)
4091 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004092
4093 return status;
4094}
4095
4096
4097/*============================================================================*/
4098
4099/**
4100* \brief Retreive lock status .
4101* \param demod Pointer to demodulator instance.
4102* \param lockStat Pointer to lock status structure.
4103* \return DRXStatus_t.
4104*
4105*/
4106static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4107{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004108 int status;
4109 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4110 OFDM_SC_RA_RAM_LOCK_FEC__M);
4111 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4112 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004113
Oliver Endrissebc7de22011-07-03 13:49:44 -03004114 u16 ScRaRamLock = 0;
4115 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004116
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004117 dprintk(1, "\n");
4118
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004119 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004120 /* driver 0.9.0 */
4121 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004122 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004123 if (status < 0)
4124 goto end;
4125 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4126 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004127
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004128 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004129 if (status < 0)
4130 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004131
Oliver Endrissebc7de22011-07-03 13:49:44 -03004132 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4133 *pLockStatus = MPEG_LOCK;
4134 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4135 *pLockStatus = FEC_LOCK;
4136 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4137 *pLockStatus = DEMOD_LOCK;
4138 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4139 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004140end:
4141 if (status < 0)
4142 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004145}
4146
Oliver Endrissebc7de22011-07-03 13:49:44 -03004147static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004148{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004149 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004150 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004152 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004153 status = CtrlPowerMode(state, &powerMode);
4154 if (status < 0)
4155 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156
Oliver Endrissebc7de22011-07-03 13:49:44 -03004157 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004158}
4159
4160
Oliver Endrissebc7de22011-07-03 13:49:44 -03004161/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004162static int PowerDownQAM(struct drxk_state *state)
4163{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004164 u16 data = 0;
4165 u16 cmdResult;
4166 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004167
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004168 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004169 status = read16(state, SCU_COMM_EXEC__A, &data);
4170 if (status < 0)
4171 goto error;
4172 if (data == SCU_COMM_EXEC_ACTIVE) {
4173 /*
4174 STOP demodulator
4175 QAM and HW blocks
4176 */
4177 /* stop all comstate->m_exec */
4178 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004179 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004180 goto error;
4181 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 -03004182 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004183 goto error;
4184 }
4185 /* powerdown AFE */
4186 status = SetIqmAf(state, false);
4187
4188error:
4189 if (status < 0)
4190 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191
Oliver Endrissebc7de22011-07-03 13:49:44 -03004192 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004193}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004194
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004195/*============================================================================*/
4196
4197/**
4198* \brief Setup of the QAM Measurement intervals for signal quality
4199* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004200* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004201* \return DRXStatus_t.
4202*
4203* NOTE:
4204* Take into account that for certain settings the errorcounters can overflow.
4205* The implementation does not check this.
4206*
4207*/
4208static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004209 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004210 u32 symbolRate)
4211{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004212 u32 fecBitsDesired = 0; /* BER accounting period */
4213 u32 fecRsPeriodTotal = 0; /* Total period */
4214 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4215 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004216 int status = 0;
4217
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004218 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004219
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004220 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004221 /* fecBitsDesired = symbolRate [kHz] *
4222 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004223 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004224 SyncLoss (== 1) *
4225 ViterbiLoss (==1)
4226 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004227 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004228 case DRX_CONSTELLATION_QAM16:
4229 fecBitsDesired = 4 * symbolRate;
4230 break;
4231 case DRX_CONSTELLATION_QAM32:
4232 fecBitsDesired = 5 * symbolRate;
4233 break;
4234 case DRX_CONSTELLATION_QAM64:
4235 fecBitsDesired = 6 * symbolRate;
4236 break;
4237 case DRX_CONSTELLATION_QAM128:
4238 fecBitsDesired = 7 * symbolRate;
4239 break;
4240 case DRX_CONSTELLATION_QAM256:
4241 fecBitsDesired = 8 * symbolRate;
4242 break;
4243 default:
4244 status = -EINVAL;
4245 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004246 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004247 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004249 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4250 fecBitsDesired *= 500; /* meas. period [ms] */
4251
4252 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4253 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4254 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4255
4256 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4257 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4258 if (fecRsPrescale == 0) {
4259 /* Divide by zero (though impossible) */
4260 status = -EINVAL;
4261 if (status < 0)
4262 goto error;
4263 }
4264 fecRsPeriod =
4265 ((u16) fecRsPeriodTotal +
4266 (fecRsPrescale >> 1)) / fecRsPrescale;
4267
4268 /* write corresponding registers */
4269 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4270 if (status < 0)
4271 goto error;
4272 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4273 if (status < 0)
4274 goto error;
4275 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4276error:
4277 if (status < 0)
4278 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004279 return status;
4280}
4281
Oliver Endrissebc7de22011-07-03 13:49:44 -03004282static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004283{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004284 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004285
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004286 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004287 /* QAM Equalizer Setup */
4288 /* Equalizer */
4289 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4290 if (status < 0)
4291 goto error;
4292 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4293 if (status < 0)
4294 goto error;
4295 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4305 if (status < 0)
4306 goto error;
4307 /* Decision Feedback Equalizer */
4308 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4309 if (status < 0)
4310 goto error;
4311 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4312 if (status < 0)
4313 goto error;
4314 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4315 if (status < 0)
4316 goto error;
4317 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4324 if (status < 0)
4325 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004326
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004327 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4328 if (status < 0)
4329 goto error;
4330 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4331 if (status < 0)
4332 goto error;
4333 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4334 if (status < 0)
4335 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004336
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004337 /* QAM Slicer Settings */
4338 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4339 if (status < 0)
4340 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004341
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004342 /* QAM Loop Controller Coeficients */
4343 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4344 if (status < 0)
4345 goto error;
4346 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4347 if (status < 0)
4348 goto error;
4349 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4350 if (status < 0)
4351 goto error;
4352 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4353 if (status < 0)
4354 goto error;
4355 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4365 if (status < 0)
4366 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004367
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004368 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4372 if (status < 0)
4373 goto error;
4374 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4375 if (status < 0)
4376 goto error;
4377 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4378 if (status < 0)
4379 goto error;
4380 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4387 if (status < 0)
4388 goto error;
4389 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4390 if (status < 0)
4391 goto error;
4392 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4393 if (status < 0)
4394 goto error;
4395 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4402 if (status < 0)
4403 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004404
4405
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004406 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004407
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004408 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4412 if (status < 0)
4413 goto error;
4414 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4424 if (status < 0)
4425 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004426
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004427 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4428 if (status < 0)
4429 goto error;
4430 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4431 if (status < 0)
4432 goto error;
4433 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4434 if (status < 0)
4435 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004436
4437
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004438 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004439
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004440 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4444 if (status < 0)
4445 goto error;
4446 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4447 if (status < 0)
4448 goto error;
4449 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4450 if (status < 0)
4451 goto error;
4452 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4453 if (status < 0)
4454 goto error;
4455 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4456 if (status < 0)
4457 goto error;
4458 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4459 if (status < 0)
4460 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004461
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004462error:
4463 if (status < 0)
4464 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004465 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004466}
4467
4468/*============================================================================*/
4469
4470/**
4471* \brief QAM32 specific setup
4472* \param demod instance of demod.
4473* \return DRXStatus_t.
4474*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004475static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004476{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004477 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004479 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004480
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004481 /* QAM Equalizer Setup */
4482 /* Equalizer */
4483 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4487 if (status < 0)
4488 goto error;
4489 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4490 if (status < 0)
4491 goto error;
4492 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4493 if (status < 0)
4494 goto error;
4495 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4496 if (status < 0)
4497 goto error;
4498 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4499 if (status < 0)
4500 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004501
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004502 /* Decision Feedback Equalizer */
4503 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4504 if (status < 0)
4505 goto error;
4506 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4507 if (status < 0)
4508 goto error;
4509 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4510 if (status < 0)
4511 goto error;
4512 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4513 if (status < 0)
4514 goto error;
4515 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4516 if (status < 0)
4517 goto error;
4518 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4519 if (status < 0)
4520 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004521
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004522 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4523 if (status < 0)
4524 goto error;
4525 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4526 if (status < 0)
4527 goto error;
4528 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4529 if (status < 0)
4530 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004531
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004532 /* QAM Slicer Settings */
4533
4534 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4535 if (status < 0)
4536 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004537
4538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004539 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004540
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004541 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4542 if (status < 0)
4543 goto error;
4544 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4545 if (status < 0)
4546 goto error;
4547 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4548 if (status < 0)
4549 goto error;
4550 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4551 if (status < 0)
4552 goto error;
4553 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4563 if (status < 0)
4564 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004565
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004566 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4567 if (status < 0)
4568 goto error;
4569 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4585 if (status < 0)
4586 goto error;
4587 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4588 if (status < 0)
4589 goto error;
4590 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4600 if (status < 0)
4601 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004602
4603
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004604 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004605
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004606 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4607 if (status < 0)
4608 goto error;
4609 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4610 if (status < 0)
4611 goto error;
4612 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4613 if (status < 0)
4614 goto error;
4615 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4616 if (status < 0)
4617 goto error;
4618 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4622 if (status < 0)
4623 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004624
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004625 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4626 if (status < 0)
4627 goto error;
4628 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4629 if (status < 0)
4630 goto error;
4631 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4632 if (status < 0)
4633 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004634
4635
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004636 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004637
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004638 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4642 if (status < 0)
4643 goto error;
4644 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4645 if (status < 0)
4646 goto error;
4647 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4648 if (status < 0)
4649 goto error;
4650 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4651 if (status < 0)
4652 goto error;
4653 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4654 if (status < 0)
4655 goto error;
4656 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4657error:
4658 if (status < 0)
4659 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004660 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004661}
4662
4663/*============================================================================*/
4664
4665/**
4666* \brief QAM64 specific setup
4667* \param demod instance of demod.
4668* \return DRXStatus_t.
4669*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004670static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004671{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004672 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004673
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004674 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004675 /* QAM Equalizer Setup */
4676 /* Equalizer */
4677 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4678 if (status < 0)
4679 goto error;
4680 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4681 if (status < 0)
4682 goto error;
4683 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4684 if (status < 0)
4685 goto error;
4686 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4687 if (status < 0)
4688 goto error;
4689 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4693 if (status < 0)
4694 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004695
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004696 /* Decision Feedback Equalizer */
4697 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4707 if (status < 0)
4708 goto error;
4709 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4710 if (status < 0)
4711 goto error;
4712 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4713 if (status < 0)
4714 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004715
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004716 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4717 if (status < 0)
4718 goto error;
4719 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4720 if (status < 0)
4721 goto error;
4722 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4723 if (status < 0)
4724 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004726 /* QAM Slicer Settings */
4727 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4728 if (status < 0)
4729 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004730
4731
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004732 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004733
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004734 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4735 if (status < 0)
4736 goto error;
4737 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4738 if (status < 0)
4739 goto error;
4740 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4741 if (status < 0)
4742 goto error;
4743 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4744 if (status < 0)
4745 goto error;
4746 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4756 if (status < 0)
4757 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004759 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4760 if (status < 0)
4761 goto error;
4762 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4763 if (status < 0)
4764 goto error;
4765 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4766 if (status < 0)
4767 goto error;
4768 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4769 if (status < 0)
4770 goto error;
4771 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4772 if (status < 0)
4773 goto error;
4774 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4775 if (status < 0)
4776 goto error;
4777 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4778 if (status < 0)
4779 goto error;
4780 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4781 if (status < 0)
4782 goto error;
4783 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4793 if (status < 0)
4794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004795
4796
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004797 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004799 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4800 if (status < 0)
4801 goto error;
4802 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4815 if (status < 0)
4816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004818 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4819 if (status < 0)
4820 goto error;
4821 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4825 if (status < 0)
4826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004827
4828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004829 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004831 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4835 if (status < 0)
4836 goto error;
4837 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4838 if (status < 0)
4839 goto error;
4840 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4841 if (status < 0)
4842 goto error;
4843 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4844 if (status < 0)
4845 goto error;
4846 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4847 if (status < 0)
4848 goto error;
4849 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4850error:
4851 if (status < 0)
4852 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004853
Oliver Endrissebc7de22011-07-03 13:49:44 -03004854 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004855}
4856
4857/*============================================================================*/
4858
4859/**
4860* \brief QAM128 specific setup
4861* \param demod: instance of demod.
4862* \return DRXStatus_t.
4863*/
4864static int SetQAM128(struct drxk_state *state)
4865{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004866 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004867
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004868 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004869 /* QAM Equalizer Setup */
4870 /* Equalizer */
4871 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4881 if (status < 0)
4882 goto error;
4883 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4884 if (status < 0)
4885 goto error;
4886 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4887 if (status < 0)
4888 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004890 /* Decision Feedback Equalizer */
4891 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4892 if (status < 0)
4893 goto error;
4894 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4895 if (status < 0)
4896 goto error;
4897 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4898 if (status < 0)
4899 goto error;
4900 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4907 if (status < 0)
4908 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004910 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4911 if (status < 0)
4912 goto error;
4913 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4914 if (status < 0)
4915 goto error;
4916 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4917 if (status < 0)
4918 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
4920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004921 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004922
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004923 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4924 if (status < 0)
4925 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004926
4927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004928 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004929
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004930 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4934 if (status < 0)
4935 goto error;
4936 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4937 if (status < 0)
4938 goto error;
4939 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4940 if (status < 0)
4941 goto error;
4942 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4952 if (status < 0)
4953 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004955 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4959 if (status < 0)
4960 goto error;
4961 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4962 if (status < 0)
4963 goto error;
4964 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4965 if (status < 0)
4966 goto error;
4967 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4974 if (status < 0)
4975 goto error;
4976 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4989 if (status < 0)
4990 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004991
4992
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004993 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004994
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004995 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4996 if (status < 0)
4997 goto error;
4998 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5005 if (status < 0)
5006 goto error;
5007 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5008 if (status < 0)
5009 goto error;
5010 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5011 if (status < 0)
5012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005014 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5015 if (status < 0)
5016 goto error;
5017 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5018 if (status < 0)
5019 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005020
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005021 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5022 if (status < 0)
5023 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005024
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005025 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005026
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005027 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5031 if (status < 0)
5032 goto error;
5033 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5034 if (status < 0)
5035 goto error;
5036 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5037 if (status < 0)
5038 goto error;
5039 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5040 if (status < 0)
5041 goto error;
5042 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5043 if (status < 0)
5044 goto error;
5045 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5046error:
5047 if (status < 0)
5048 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005049
Oliver Endrissebc7de22011-07-03 13:49:44 -03005050 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005051}
5052
5053/*============================================================================*/
5054
5055/**
5056* \brief QAM256 specific setup
5057* \param demod: instance of demod.
5058* \return DRXStatus_t.
5059*/
5060static int SetQAM256(struct drxk_state *state)
5061{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005062 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005063
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005064 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005065 /* QAM Equalizer Setup */
5066 /* Equalizer */
5067 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5074 if (status < 0)
5075 goto error;
5076 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5077 if (status < 0)
5078 goto error;
5079 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5080 if (status < 0)
5081 goto error;
5082 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5083 if (status < 0)
5084 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005085
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005086 /* Decision Feedback Equalizer */
5087 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5088 if (status < 0)
5089 goto error;
5090 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5091 if (status < 0)
5092 goto error;
5093 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5094 if (status < 0)
5095 goto error;
5096 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5097 if (status < 0)
5098 goto error;
5099 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5100 if (status < 0)
5101 goto error;
5102 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5103 if (status < 0)
5104 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005106 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5107 if (status < 0)
5108 goto error;
5109 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5110 if (status < 0)
5111 goto error;
5112 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5113 if (status < 0)
5114 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005116 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005118 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5119 if (status < 0)
5120 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005121
5122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005123 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005125 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5126 if (status < 0)
5127 goto error;
5128 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5129 if (status < 0)
5130 goto error;
5131 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5132 if (status < 0)
5133 goto error;
5134 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5135 if (status < 0)
5136 goto error;
5137 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5147 if (status < 0)
5148 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005150 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5151 if (status < 0)
5152 goto error;
5153 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5154 if (status < 0)
5155 goto error;
5156 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5157 if (status < 0)
5158 goto error;
5159 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5160 if (status < 0)
5161 goto error;
5162 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5163 if (status < 0)
5164 goto error;
5165 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5166 if (status < 0)
5167 goto error;
5168 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5169 if (status < 0)
5170 goto error;
5171 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5172 if (status < 0)
5173 goto error;
5174 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5175 if (status < 0)
5176 goto error;
5177 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5184 if (status < 0)
5185 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005186
5187
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005188 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005189
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005190 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5191 if (status < 0)
5192 goto error;
5193 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5194 if (status < 0)
5195 goto error;
5196 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5197 if (status < 0)
5198 goto error;
5199 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5200 if (status < 0)
5201 goto error;
5202 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5206 if (status < 0)
5207 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005208
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005209 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5210 if (status < 0)
5211 goto error;
5212 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5213 if (status < 0)
5214 goto error;
5215 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5216 if (status < 0)
5217 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005218
5219
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005220 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005222 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5223 if (status < 0)
5224 goto error;
5225 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5226 if (status < 0)
5227 goto error;
5228 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5229 if (status < 0)
5230 goto error;
5231 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5232 if (status < 0)
5233 goto error;
5234 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5235 if (status < 0)
5236 goto error;
5237 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5238 if (status < 0)
5239 goto error;
5240 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5241error:
5242 if (status < 0)
5243 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005244 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245}
5246
5247
5248/*============================================================================*/
5249/**
5250* \brief Reset QAM block.
5251* \param demod: instance of demod.
5252* \param channel: pointer to channel data.
5253* \return DRXStatus_t.
5254*/
5255static int QAMResetQAM(struct drxk_state *state)
5256{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257 int status;
5258 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005259
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005260 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005261 /* Stop QAM comstate->m_exec */
5262 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5263 if (status < 0)
5264 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005265
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005266 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5267error:
5268 if (status < 0)
5269 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005270 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005271}
5272
5273/*============================================================================*/
5274
5275/**
5276* \brief Set QAM symbolrate.
5277* \param demod: instance of demod.
5278* \param channel: pointer to channel data.
5279* \return DRXStatus_t.
5280*/
5281static int QAMSetSymbolrate(struct drxk_state *state)
5282{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005283 u32 adcFrequency = 0;
5284 u32 symbFreq = 0;
5285 u32 iqmRcRate = 0;
5286 u16 ratesel = 0;
5287 u32 lcSymbRate = 0;
5288 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005289
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005290 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005291 /* Select & calculate correct IQM rate */
5292 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5293 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005294 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5295 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005296 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005297 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005298 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005299 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005300 ratesel = 1;
5301 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5302 if (status < 0)
5303 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005304
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005305 /*
5306 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5307 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005308 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005309 if (symbFreq == 0) {
5310 /* Divide by zero */
5311 status = -EINVAL;
5312 goto error;
5313 }
5314 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5315 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5316 (1 << 23);
5317 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5318 if (status < 0)
5319 goto error;
5320 state->m_iqmRcRate = iqmRcRate;
5321 /*
5322 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5323 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005324 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005325 if (adcFrequency == 0) {
5326 /* Divide by zero */
5327 status = -EINVAL;
5328 goto error;
5329 }
5330 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5331 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5332 16);
5333 if (lcSymbRate > 511)
5334 lcSymbRate = 511;
5335 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005336
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005337error:
5338 if (status < 0)
5339 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005340 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005341}
5342
5343/*============================================================================*/
5344
5345/**
5346* \brief Get QAM lock status.
5347* \param demod: instance of demod.
5348* \param channel: pointer to channel data.
5349* \return DRXStatus_t.
5350*/
5351
5352static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5353{
5354 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005355 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005356
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005357 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005358 *pLockStatus = NOT_LOCKED;
5359 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005360 SCU_RAM_COMMAND_STANDARD_QAM |
5361 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5362 Result);
5363 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005364 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005365
5366 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005367 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005368 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005369 /* 0x4000 DEMOD LOCKED */
5370 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005371 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005372 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5373 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005374 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005375 /* 0xC000 NEVER LOCKED */
5376 /* (system will never be able to lock to the signal) */
5377 /* TODO: check this, intermediate & standard specific lock states are not
5378 taken into account here */
5379 *pLockStatus = NEVER_LOCK;
5380 }
5381 return status;
5382}
5383
5384#define QAM_MIRROR__M 0x03
5385#define QAM_MIRROR_NORMAL 0x00
5386#define QAM_MIRRORED 0x01
5387#define QAM_MIRROR_AUTO_ON 0x02
5388#define QAM_LOCKRANGE__M 0x10
5389#define QAM_LOCKRANGE_NORMAL 0x10
5390
Oliver Endrissebc7de22011-07-03 13:49:44 -03005391static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5392 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005393{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005394 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005395 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5396 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005397
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005398 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005399 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005400 * STEP 1: reset demodulator
5401 * resets FEC DI and FEC RS
5402 * resets QAM block
5403 * resets SCU variables
5404 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005405 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005406 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005407 goto error;
5408 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5409 if (status < 0)
5410 goto error;
5411 status = QAMResetQAM(state);
5412 if (status < 0)
5413 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005414
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005415 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005416 * STEP 2: configure demodulator
5417 * -set params; resets IQM,QAM,FEC HW; initializes some
5418 * SCU variables
5419 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005420 status = QAMSetSymbolrate(state);
5421 if (status < 0)
5422 goto error;
5423
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005424 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005425 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005426 case QAM_256:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5428 break;
5429 case QAM_AUTO:
5430 case QAM_64:
5431 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5432 break;
5433 case QAM_16:
5434 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5435 break;
5436 case QAM_32:
5437 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5438 break;
5439 case QAM_128:
5440 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5441 break;
5442 default:
5443 status = -EINVAL;
5444 break;
5445 }
5446 if (status < 0)
5447 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005448 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005449 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005450 if (state->m_OperationMode == OM_QAM_ITU_C)
5451 setParamParameters[2] = QAM_TOP_ANNEX_C;
5452 else
5453 setParamParameters[2] = QAM_TOP_ANNEX_A;
5454 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5455 /* Env parameters */
5456 /* check for LOCKRANGE Extented */
5457 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005458
5459 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 -03005460 if (status < 0) {
5461 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005462 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005463 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005464 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005465 setParamParameters[0] = QAM_TOP_ANNEX_A;
5466 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5467 if (status < 0)
5468 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005469
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005470 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005471 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005472 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5473 }
5474 if (status < 0)
5475 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005476
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005477 /*
5478 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005479 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005480 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005481#if 0
5482 status = SetFrequency(channel, tunerFreqOffset));
5483 if (status < 0)
5484 goto error;
5485#endif
5486 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5487 if (status < 0)
5488 goto error;
5489
5490 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005491 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005492 if (status < 0)
5493 goto error;
5494
5495 /* Reset default values */
5496 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5497 if (status < 0)
5498 goto error;
5499 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5500 if (status < 0)
5501 goto error;
5502
5503 /* Reset default LC values */
5504 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5505 if (status < 0)
5506 goto error;
5507 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_MODE__A, 7);
5514 if (status < 0)
5515 goto error;
5516
5517 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5518 if (status < 0)
5519 goto error;
5520 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5521 if (status < 0)
5522 goto error;
5523 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5527 if (status < 0)
5528 goto error;
5529 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5530 if (status < 0)
5531 goto error;
5532 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5533 if (status < 0)
5534 goto error;
5535 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5536 if (status < 0)
5537 goto error;
5538 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5539 if (status < 0)
5540 goto error;
5541 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5554 if (status < 0)
5555 goto error;
5556 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5557 if (status < 0)
5558 goto error;
5559 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5560 if (status < 0)
5561 goto error;
5562
5563 /* Mirroring, QAM-block starting point not inverted */
5564 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5565 if (status < 0)
5566 goto error;
5567
5568 /* Halt SCU to enable safe non-atomic accesses */
5569 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5570 if (status < 0)
5571 goto error;
5572
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005573 /* STEP 4: modulation specific setup */
5574 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005575 case QAM_16:
5576 status = SetQAM16(state);
5577 break;
5578 case QAM_32:
5579 status = SetQAM32(state);
5580 break;
5581 case QAM_AUTO:
5582 case QAM_64:
5583 status = SetQAM64(state);
5584 break;
5585 case QAM_128:
5586 status = SetQAM128(state);
5587 break;
5588 case QAM_256:
5589 status = SetQAM256(state);
5590 break;
5591 default:
5592 status = -EINVAL;
5593 break;
5594 }
5595 if (status < 0)
5596 goto error;
5597
5598 /* Activate SCU to enable SCU commands */
5599 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5600 if (status < 0)
5601 goto error;
5602
5603 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005604 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005605 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5606 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5607 if (status < 0)
5608 goto error;
5609
5610 /* Start processes */
5611 status = MPEGTSStart(state);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5618 if (status < 0)
5619 goto error;
5620 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5621 if (status < 0)
5622 goto error;
5623
5624 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5625 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5626 if (status < 0)
5627 goto error;
5628
5629 /* update global DRXK data container */
5630/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5631
5632error:
5633 if (status < 0)
5634 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005635 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005636}
5637
Oliver Endrissebc7de22011-07-03 13:49:44 -03005638static int SetQAMStandard(struct drxk_state *state,
5639 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005641 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005642#ifdef DRXK_QAM_TAPS
5643#define DRXK_QAMA_TAPS_SELECT
5644#include "drxk_filters.h"
5645#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005646#endif
5647
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005648 dprintk(1, "\n");
5649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005650 /* added antenna switch */
5651 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005652
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005653 /* Ensure correct power-up mode */
5654 status = PowerUpQAM(state);
5655 if (status < 0)
5656 goto error;
5657 /* Reset QAM block */
5658 status = QAMResetQAM(state);
5659 if (status < 0)
5660 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005661
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005662 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005663
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005664 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5665 if (status < 0)
5666 goto error;
5667 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5668 if (status < 0)
5669 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005670
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005671 /* Upload IQM Channel Filter settings by
5672 boot loader from ROM table */
5673 switch (oMode) {
5674 case OM_QAM_ITU_A:
5675 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5676 break;
5677 case OM_QAM_ITU_C:
5678 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 -03005679 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005680 goto error;
5681 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5682 break;
5683 default:
5684 status = -EINVAL;
5685 }
5686 if (status < 0)
5687 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005689 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5696 if (status < 0)
5697 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005698
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005699 status = write16(state, IQM_RC_STRETCH__A, 21);
5700 if (status < 0)
5701 goto error;
5702 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5703 if (status < 0)
5704 goto error;
5705 status = write16(state, IQM_AF_CLP_TH__A, 448);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5716 if (status < 0)
5717 goto error;
5718 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5719 if (status < 0)
5720 goto error;
5721 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5722 if (status < 0)
5723 goto error;
5724 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5725 if (status < 0)
5726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005728 /* IQM Impulse Noise Processing Unit */
5729 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_CF_DATATH__A, 1000);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_DET_LCT__A, 0);
5739 if (status < 0)
5740 goto error;
5741 status = write16(state, IQM_CF_WND_LEN__A, 1);
5742 if (status < 0)
5743 goto error;
5744 status = write16(state, IQM_CF_PKDTH__A, 1);
5745 if (status < 0)
5746 goto error;
5747 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5748 if (status < 0)
5749 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005750
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 /* turn on IQMAF. Must be done before setAgc**() */
5752 status = SetIqmAf(state, true);
5753 if (status < 0)
5754 goto error;
5755 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5756 if (status < 0)
5757 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005759 /* IQM will not be reset from here, sync ADC and update/init AGC */
5760 status = ADCSynchronization(state);
5761 if (status < 0)
5762 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005764 /* Set the FSM step period */
5765 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5766 if (status < 0)
5767 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005769 /* Halt SCU to enable safe non-atomic accesses */
5770 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5771 if (status < 0)
5772 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005773
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005774 /* No more resets of the IQM, current standard correctly set =>
5775 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005777 status = InitAGC(state, true);
5778 if (status < 0)
5779 goto error;
5780 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5781 if (status < 0)
5782 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005784 /* Configure AGC's */
5785 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5786 if (status < 0)
5787 goto error;
5788 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5789 if (status < 0)
5790 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005792 /* Activate SCU to enable SCU commands */
5793 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5794error:
5795 if (status < 0)
5796 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005797 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005798}
5799
5800static int WriteGPIO(struct drxk_state *state)
5801{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005802 int status;
5803 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005804
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005805 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005806 /* stop lock indicator process */
5807 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5808 if (status < 0)
5809 goto error;
5810
5811 /* Write magic word to enable pdr reg write */
5812 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5813 if (status < 0)
5814 goto error;
5815
5816 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005817 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5818 /* write to io pad configuration register - output mode */
5819 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5820 if (status < 0)
5821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005822
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005823 /* use corresponding bit in io data output registar */
5824 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5825 if (status < 0)
5826 goto error;
5827 if ((state->m_GPIO & 0x0001) == 0)
5828 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5829 else
5830 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5831 /* write back to io data output register */
5832 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5833 if (status < 0)
5834 goto error;
5835 }
5836 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5837 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005838 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005839 if (status < 0)
5840 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005841
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005842 /* use corresponding bit in io data output registar */
5843 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5844 if (status < 0)
5845 goto error;
5846 if ((state->m_GPIO & 0x0002) == 0)
5847 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5848 else
5849 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5850 /* write back to io data output register */
5851 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5852 if (status < 0)
5853 goto error;
5854 }
5855 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5856 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005857 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005858 if (status < 0)
5859 goto error;
5860
5861 /* use corresponding bit in io data output registar */
5862 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5863 if (status < 0)
5864 goto error;
5865 if ((state->m_GPIO & 0x0004) == 0)
5866 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5867 else
5868 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5869 /* write back to io data output register */
5870 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5871 if (status < 0)
5872 goto error;
5873 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005874 }
5875 /* Write magic word to disable pdr reg write */
5876 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5877error:
5878 if (status < 0)
5879 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005880 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881}
5882
5883static int SwitchAntennaToQAM(struct drxk_state *state)
5884{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005885 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005886 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005887
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005888 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005889
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005890 if (!state->antenna_gpio)
5891 return 0;
5892
5893 gpio_state = state->m_GPIO & state->antenna_gpio;
5894
5895 if (state->antenna_dvbt ^ gpio_state) {
5896 /* Antenna is on DVB-T mode. Switch */
5897 if (state->antenna_dvbt)
5898 state->m_GPIO &= ~state->antenna_gpio;
5899 else
5900 state->m_GPIO |= state->antenna_gpio;
5901 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005902 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005903 if (status < 0)
5904 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005905 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005906}
5907
5908static int SwitchAntennaToDVBT(struct drxk_state *state)
5909{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005910 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005911 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005912
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005913 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005914
5915 if (!state->antenna_gpio)
5916 return 0;
5917
5918 gpio_state = state->m_GPIO & state->antenna_gpio;
5919
5920 if (!(state->antenna_dvbt ^ gpio_state)) {
5921 /* Antenna is on DVB-C mode. Switch */
5922 if (state->antenna_dvbt)
5923 state->m_GPIO |= state->antenna_gpio;
5924 else
5925 state->m_GPIO &= ~state->antenna_gpio;
5926 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005928 if (status < 0)
5929 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005930 return status;
5931}
5932
5933
5934static int PowerDownDevice(struct drxk_state *state)
5935{
5936 /* Power down to requested mode */
5937 /* Backup some register settings */
5938 /* Set pins with possible pull-ups connected to them in input mode */
5939 /* Analog power down */
5940 /* ADC power down */
5941 /* Power down device */
5942 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005943
5944 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005945 if (state->m_bPDownOpenBridge) {
5946 /* Open I2C bridge before power down of DRXK */
5947 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005948 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005949 goto error;
5950 }
5951 /* driver 0.9.0 */
5952 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005953 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005954 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005956 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5957 if (status < 0)
5958 goto error;
5959 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5960 if (status < 0)
5961 goto error;
5962 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5963 status = HI_CfgCommand(state);
5964error:
5965 if (status < 0)
5966 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5967
5968 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005969}
5970
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971static int init_drxk(struct drxk_state *state)
5972{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03005973 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005974 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 u16 driverVersion;
5976
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005977 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005978 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005979 status = PowerUpDevice(state);
5980 if (status < 0)
5981 goto error;
5982 status = DRXX_Open(state);
5983 if (status < 0)
5984 goto error;
5985 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5986 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5987 if (status < 0)
5988 goto error;
5989 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5990 if (status < 0)
5991 goto error;
5992 /* TODO is this needed, if yes how much delay in worst case scenario */
5993 msleep(1);
5994 state->m_DRXK_A3_PATCH_CODE = true;
5995 status = GetDeviceCapabilities(state);
5996 if (status < 0)
5997 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005998
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005999 /* Bridge delay, uses oscilator clock */
6000 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6001 /* SDA brdige delay */
6002 state->m_HICfgBridgeDelay =
6003 (u16) ((state->m_oscClockFreq / 1000) *
6004 HI_I2C_BRIDGE_DELAY) / 1000;
6005 /* Clipping */
6006 if (state->m_HICfgBridgeDelay >
6007 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006008 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006009 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6010 }
6011 /* SCL bridge delay, same as SDA for now */
6012 state->m_HICfgBridgeDelay +=
6013 state->m_HICfgBridgeDelay <<
6014 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 status = InitHI(state);
6017 if (status < 0)
6018 goto error;
6019 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006020#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006021 if (!(state->m_DRXK_A1_ROM_CODE)
6022 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006024 {
6025 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6026 if (status < 0)
6027 goto error;
6028 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006029
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 /* disable MPEG port */
6031 status = MPEGTSDisable(state);
6032 if (status < 0)
6033 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 /* Stop AUD and SCU */
6036 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6037 if (status < 0)
6038 goto error;
6039 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6040 if (status < 0)
6041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006043 /* enable token-ring bus through OFDM block for possible ucode upload */
6044 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6045 if (status < 0)
6046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006048 /* include boot loader section */
6049 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6050 if (status < 0)
6051 goto error;
6052 status = BLChainCmd(state, 0, 6, 100);
6053 if (status < 0)
6054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006055
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006056 if (state->fw) {
6057 status = DownloadMicrocode(state, state->fw->data,
6058 state->fw->size);
6059 if (status < 0)
6060 goto error;
6061 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 /* disable token-ring bus through OFDM block for possible ucode upload */
6064 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6065 if (status < 0)
6066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006068 /* Run SCU for a little while to initialize microcode version numbers */
6069 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6070 if (status < 0)
6071 goto error;
6072 status = DRXX_Open(state);
6073 if (status < 0)
6074 goto error;
6075 /* added for test */
6076 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006077
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006078 powerMode = DRXK_POWER_DOWN_OFDM;
6079 status = CtrlPowerMode(state, &powerMode);
6080 if (status < 0)
6081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006083 /* Stamp driver version number in SCU data RAM in BCD code
6084 Done to enable field application engineers to retreive drxdriver version
6085 via I2C from SCU RAM.
6086 Not using SCU command interface for SCU register access since no
6087 microcode may be present.
6088 */
6089 driverVersion =
6090 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6091 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6092 ((DRXK_VERSION_MAJOR % 10) << 4) +
6093 (DRXK_VERSION_MINOR % 10);
6094 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6095 if (status < 0)
6096 goto error;
6097 driverVersion =
6098 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6099 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6100 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6101 (DRXK_VERSION_PATCH % 10);
6102 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6103 if (status < 0)
6104 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006106 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6107 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6108 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006109
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006110 /* Dirty fix of default values for ROM/PATCH microcode
6111 Dirty because this fix makes it impossible to setup suitable values
6112 before calling DRX_Open. This solution requires changes to RF AGC speed
6113 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006115 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006117 /* Reset driver debug flags to 0 */
6118 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6119 if (status < 0)
6120 goto error;
6121 /* driver 0.9.0 */
6122 /* Setup FEC OC:
6123 NOTE: No more full FEC resets allowed afterwards!! */
6124 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6125 if (status < 0)
6126 goto error;
6127 /* MPEGTS functions are still the same */
6128 status = MPEGTSDtoInit(state);
6129 if (status < 0)
6130 goto error;
6131 status = MPEGTSStop(state);
6132 if (status < 0)
6133 goto error;
6134 status = MPEGTSConfigurePolarity(state);
6135 if (status < 0)
6136 goto error;
6137 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6138 if (status < 0)
6139 goto error;
6140 /* added: configure GPIO */
6141 status = WriteGPIO(state);
6142 if (status < 0)
6143 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006145 state->m_DrxkState = DRXK_STOPPED;
6146
6147 if (state->m_bPowerDown) {
6148 status = PowerDownDevice(state);
6149 if (status < 0)
6150 goto error;
6151 state->m_DrxkState = DRXK_POWERED_DOWN;
6152 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006153 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006154
6155 /* Initialize the supported delivery systems */
6156 n = 0;
6157 if (state->m_hasDVBC) {
6158 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6159 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6160 strlcat(state->frontend.ops.info.name, " DVB-C",
6161 sizeof(state->frontend.ops.info.name));
6162 }
6163 if (state->m_hasDVBT) {
6164 state->frontend.ops.delsys[n++] = SYS_DVBT;
6165 strlcat(state->frontend.ops.info.name, " DVB-T",
6166 sizeof(state->frontend.ops.info.name));
6167 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006169error:
6170 if (status < 0)
6171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006173 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174}
6175
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006176static void load_firmware_cb(const struct firmware *fw,
6177 void *context)
6178{
6179 struct drxk_state *state = context;
6180
6181 if (!fw) {
6182 printk(KERN_ERR
6183 "drxk: Could not load firmware file %s.\n",
6184 state->microcode_name);
6185 printk(KERN_INFO
6186 "drxk: Copy %s to your hotplug directory!\n",
6187 state->microcode_name);
6188 state->microcode_name = NULL;
6189
6190 /*
6191 * As firmware is now load asynchronous, it is not possible
6192 * anymore to fail at frontend attach. We might silently
6193 * return here, and hope that the driver won't crash.
6194 * We might also change all DVB callbacks to return -ENODEV
6195 * if the device is not initialized.
6196 * As the DRX-K devices have their own internal firmware,
6197 * let's just hope that it will match a firmware revision
6198 * compatible with this driver and proceed.
6199 */
6200 }
6201 state->fw = fw;
6202
6203 init_drxk(state);
6204}
6205
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006206static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006207{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006208 struct drxk_state *state = fe->demodulator_priv;
6209
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006210 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006211 if (state->fw)
6212 release_firmware(state->fw);
6213
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 kfree(state);
6215}
6216
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006217static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006218{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006219 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006220
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006221 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006223 return 0;
6224}
6225
Oliver Endrissebc7de22011-07-03 13:49:44 -03006226static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227{
6228 struct drxk_state *state = fe->demodulator_priv;
6229
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006230 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 return ConfigureI2CBridge(state, enable ? true : false);
6232}
6233
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006234static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006235{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006236 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006237 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006238 struct drxk_state *state = fe->demodulator_priv;
6239 u32 IF;
6240
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006241 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006242
6243 if (!fe->ops.tuner_ops.get_if_frequency) {
6244 printk(KERN_ERR
6245 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6246 return -EINVAL;
6247 }
6248
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006249 if (fe->ops.i2c_gate_ctrl)
6250 fe->ops.i2c_gate_ctrl(fe, 1);
6251 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006252 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253 if (fe->ops.i2c_gate_ctrl)
6254 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006255
6256 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006257 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006258
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006259 if (old_delsys != delsys) {
6260 ShutDown(state);
6261 switch (delsys) {
6262 case SYS_DVBC_ANNEX_A:
6263 case SYS_DVBC_ANNEX_C:
6264 if (!state->m_hasDVBC)
6265 return -EINVAL;
6266 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6267 if (state->m_itut_annex_c)
6268 SetOperationMode(state, OM_QAM_ITU_C);
6269 else
6270 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006271 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006272 case SYS_DVBT:
6273 if (!state->m_hasDVBT)
6274 return -EINVAL;
6275 SetOperationMode(state, OM_DVBT);
6276 break;
6277 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006278 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006279 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006280 }
6281
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006282 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283 Start(state, 0, IF);
6284
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006285 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006286
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006287 return 0;
6288}
6289
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006290static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6291{
6292 struct drxk_state *state = fe->demodulator_priv;
6293 u32 stat;
6294
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006295 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006296 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006297 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006298 if (stat == MPEG_LOCK)
6299 *status |= 0x1f;
6300 if (stat == FEC_LOCK)
6301 *status |= 0x0f;
6302 if (stat == DEMOD_LOCK)
6303 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006304 return 0;
6305}
6306
6307static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6308{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006309 dprintk(1, "\n");
6310
Oliver Endrissebc7de22011-07-03 13:49:44 -03006311 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006312 return 0;
6313}
6314
Oliver Endrissebc7de22011-07-03 13:49:44 -03006315static int drxk_read_signal_strength(struct dvb_frontend *fe,
6316 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006317{
6318 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006319 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006320
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006321 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006322 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006323 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006324 return 0;
6325}
6326
6327static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6328{
6329 struct drxk_state *state = fe->demodulator_priv;
6330 s32 snr2;
6331
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006332 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006333 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006334 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006335 return 0;
6336}
6337
6338static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6339{
6340 struct drxk_state *state = fe->demodulator_priv;
6341 u16 err;
6342
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006343 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006344 DVBTQAMGetAccPktErr(state, &err);
6345 *ucblocks = (u32) err;
6346 return 0;
6347}
6348
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006349static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006350 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006351{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006352 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006353
6354 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006355 switch (p->delivery_system) {
6356 case SYS_DVBC_ANNEX_A:
6357 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006358 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006359 sets->min_delay_ms = 3000;
6360 sets->max_drift = 0;
6361 sets->step_size = 0;
6362 return 0;
6363 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006364 return -EINVAL;
6365 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006366}
6367
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006368static struct dvb_frontend_ops drxk_ops = {
6369 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006370 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006371 .name = "DRXK",
6372 .frequency_min = 47000000,
6373 .frequency_max = 865000000,
6374 /* For DVB-C */
6375 .symbol_rate_min = 870000,
6376 .symbol_rate_max = 11700000,
6377 /* For DVB-T */
6378 .frequency_stepsize = 166667,
6379
6380 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6381 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6382 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6383 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6384 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6385 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6386 },
6387
6388 .release = drxk_release,
6389 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006390 .i2c_gate_ctrl = drxk_gate_ctrl,
6391
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006392 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006393 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006394
6395 .read_status = drxk_read_status,
6396 .read_ber = drxk_read_ber,
6397 .read_signal_strength = drxk_read_signal_strength,
6398 .read_snr = drxk_read_snr,
6399 .read_ucblocks = drxk_read_ucblocks,
6400};
6401
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006402struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006403 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006404{
6405 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006406 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006407 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006408
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006409 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006410 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006411 if (!state)
6412 return NULL;
6413
Oliver Endrissebc7de22011-07-03 13:49:44 -03006414 state->i2c = i2c;
6415 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006416 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006417 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006418 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006419 state->antenna_gpio = config->antenna_gpio;
6420 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006421 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006422 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006423
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006424 if (config->dynamic_clk) {
6425 state->m_DVBTStaticCLK = 0;
6426 state->m_DVBCStaticCLK = 0;
6427 } else {
6428 state->m_DVBTStaticCLK = 1;
6429 state->m_DVBCStaticCLK = 1;
6430 }
6431
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006432
6433 if (config->mpeg_out_clk_strength)
6434 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6435 else
6436 state->m_TSClockkStrength = 0x06;
6437
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006438 if (config->parallel_ts)
6439 state->m_enableParallel = true;
6440 else
6441 state->m_enableParallel = false;
6442
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006443 /* NOTE: as more UIO bits will be used, add them to the mask */
6444 state->UIO_mask = config->antenna_gpio;
6445
6446 /* Default gpio to DVB-C */
6447 if (!state->antenna_dvbt && state->antenna_gpio)
6448 state->m_GPIO |= state->antenna_gpio;
6449 else
6450 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006451
6452 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006453
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006454 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6455 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006456
6457 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006458
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006459 /* Load firmware and initialize DRX-K */
6460 if (state->microcode_name) {
6461 status = request_firmware_nowait(THIS_MODULE, 1,
6462 state->microcode_name,
6463 state->i2c->dev.parent,
6464 GFP_KERNEL,
6465 state, load_firmware_cb);
6466 if (status < 0) {
6467 printk(KERN_ERR
6468 "drxk: failed to request a firmware\n");
6469 return NULL;
6470 }
6471 } else if (init_drxk(state) < 0)
6472 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006473
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006474 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006475 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006476
6477error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006478 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006479 kfree(state);
6480 return NULL;
6481}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006482EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006483
6484MODULE_DESCRIPTION("DRX-K driver");
6485MODULE_AUTHOR("Ralph Metzler");
6486MODULE_LICENSE("GPL");