blob: ec24d71e153dc9ae3caa3c70cebe3f3edcf9418b [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>
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -030031#include <linux/hardirq.h>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030032#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030040static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030045 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030046static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030048static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030049static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030051static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030064 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030066}
67
Ralph Metzler43dd07f2011-07-03 13:42:18 -030068#define NOA1ROM 0
69
Ralph Metzler43dd07f2011-07-03 13:42:18 -030070#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
71#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
72
73#define DEFAULT_MER_83 165
74#define DEFAULT_MER_93 250
75
76#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
77#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
78#endif
79
80#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
81#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
82#endif
83
Ralph Metzler43dd07f2011-07-03 13:42:18 -030084#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
85#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
86
87#ifndef DRXK_KI_RAGC_ATV
88#define DRXK_KI_RAGC_ATV 4
89#endif
90#ifndef DRXK_KI_IAGC_ATV
91#define DRXK_KI_IAGC_ATV 6
92#endif
93#ifndef DRXK_KI_DAGC_ATV
94#define DRXK_KI_DAGC_ATV 7
95#endif
96
97#ifndef DRXK_KI_RAGC_QAM
98#define DRXK_KI_RAGC_QAM 3
99#endif
100#ifndef DRXK_KI_IAGC_QAM
101#define DRXK_KI_IAGC_QAM 4
102#endif
103#ifndef DRXK_KI_DAGC_QAM
104#define DRXK_KI_DAGC_QAM 7
105#endif
106#ifndef DRXK_KI_RAGC_DVBT
107#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
108#endif
109#ifndef DRXK_KI_IAGC_DVBT
110#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
111#endif
112#ifndef DRXK_KI_DAGC_DVBT
113#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
114#endif
115
116#ifndef DRXK_AGC_DAC_OFFSET
117#define DRXK_AGC_DAC_OFFSET (0x800)
118#endif
119
120#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
121#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
122#endif
123
124#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
125#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
126#endif
127
128#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
129#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
130#endif
131
132#ifndef DRXK_QAM_SYMBOLRATE_MAX
133#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
134#endif
135
136#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
137#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
138#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
139#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
140#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
141#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
142#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
143#define DRXK_BL_ROM_OFFSET_UCODE 0
144
145#define DRXK_BLC_TIMEOUT 100
146
147#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
148#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
149
150#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
151
152#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
153#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
154#endif
155
156#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
157#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
158#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
159#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
160#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
161
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300162static unsigned int debug;
163module_param(debug, int, 0644);
164MODULE_PARM_DESC(debug, "enable debug messages");
165
166#define dprintk(level, fmt, arg...) do { \
167if (debug >= level) \
168 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
169} while (0)
170
171
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300172static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300173{
174 u64 tmp64;
175
Oliver Endrissebc7de22011-07-03 13:49:44 -0300176 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300177 do_div(tmp64, c);
178
179 return (u32) tmp64;
180}
181
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200182static inline u32 Frac28a(u32 a, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300183{
184 int i = 0;
185 u32 Q1 = 0;
186 u32 R0 = 0;
187
Oliver Endrissebc7de22011-07-03 13:49:44 -0300188 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
189 Q1 = a / c; /* integer part, only the 4 least significant bits
190 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300191
192 /* division using radix 16, 7 nibbles in the result */
193 for (i = 0; i < 7; i++) {
194 Q1 = (Q1 << 4) | (R0 / c);
195 R0 = (R0 % c) << 4;
196 }
197 /* rounding */
198 if ((R0 >> 3) >= c)
199 Q1++;
200
201 return Q1;
202}
203
204static u32 Log10Times100(u32 x)
205{
206 static const u8 scale = 15;
207 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300208 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300209 u32 y = 0;
210 u32 d = 0;
211 u32 k = 0;
212 u32 r = 0;
213 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300214 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
215 0 <= n < ((1<<INDEXWIDTH)+1)
216 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300217
218 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300219 0, /* 0.000000 */
220 290941, /* 290941.300628 */
221 573196, /* 573196.476418 */
222 847269, /* 847269.179851 */
223 1113620, /* 1113620.489452 */
224 1372674, /* 1372673.576986 */
225 1624818, /* 1624817.752104 */
226 1870412, /* 1870411.981536 */
227 2109788, /* 2109787.962654 */
228 2343253, /* 2343252.817465 */
229 2571091, /* 2571091.461923 */
230 2793569, /* 2793568.696416 */
231 3010931, /* 3010931.055901 */
232 3223408, /* 3223408.452106 */
233 3431216, /* 3431215.635215 */
234 3634553, /* 3634553.498355 */
235 3833610, /* 3833610.244726 */
236 4028562, /* 4028562.434393 */
237 4219576, /* 4219575.925308 */
238 4406807, /* 4406806.721144 */
239 4590402, /* 4590401.736809 */
240 4770499, /* 4770499.491025 */
241 4947231, /* 4947230.734179 */
242 5120719, /* 5120719.018555 */
243 5291081, /* 5291081.217197 */
244 5458428, /* 5458427.996830 */
245 5622864, /* 5622864.249668 */
246 5784489, /* 5784489.488298 */
247 5943398, /* 5943398.207380 */
248 6099680, /* 6099680.215452 */
249 6253421, /* 6253420.939751 */
250 6404702, /* 6404701.706649 */
251 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300252 };
253
254
255 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300256 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300257
258 /* Scale x (normalize) */
259 /* computing y in log(x/y) = log(x) - log(y) */
260 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
261 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300262 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300263 break;
264 x <<= 1;
265 }
266 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300267 for (k = scale; k < 31; k++) {
268 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300269 break;
270 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300271 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300272 }
273 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300274 Now x has binary point between bit[scale] and bit[scale-1]
275 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300276
277 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300278 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300279
280 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300282 /* get index */
283 i = (u8) (x >> (scale - indexWidth));
284 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286 /* compute log, multiplication (d* (..)) must be within range ! */
287 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300289 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300290 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300291 r = (y >> 1);
292 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300293 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300294 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296}
297
298/****************************************************************************/
299/* I2C **********************************************************************/
300/****************************************************************************/
301
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300302static int drxk_i2c_lock(struct drxk_state *state)
303{
304 i2c_lock_adapter(state->i2c);
305 state->drxk_i2c_exclusive_lock = true;
306
307 return 0;
308}
309
310static void drxk_i2c_unlock(struct drxk_state *state)
311{
312 if (!state->drxk_i2c_exclusive_lock)
313 return;
314
315 i2c_unlock_adapter(state->i2c);
316 state->drxk_i2c_exclusive_lock = false;
317}
318
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300319static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
320 unsigned len)
321{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300322 if (state->drxk_i2c_exclusive_lock)
323 return __i2c_transfer(state->i2c, msgs, len);
324 else
325 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300326}
327
328static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300329{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300330 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
331 .buf = val, .len = 1}
332 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300333
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300334 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300335}
336
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300337static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300339 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300340 struct i2c_msg msg = {
341 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300342
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300343 dprintk(3, ":");
344 if (debug > 2) {
345 int i;
346 for (i = 0; i < len; i++)
347 printk(KERN_CONT " %02x", data[i]);
348 printk(KERN_CONT "\n");
349 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300350 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300351 if (status >= 0 && status != 1)
352 status = -EIO;
353
354 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300355 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300356
357 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300358}
359
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300360static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300361 u8 adr, u8 *msg, int len, u8 *answ, int alen)
362{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300363 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300364 struct i2c_msg msgs[2] = {
365 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300366 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300367 {.addr = adr, .flags = I2C_M_RD,
368 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300369 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300370
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300371 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300372 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300373 if (debug > 2)
374 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300375 if (status >= 0)
376 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300377
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300378 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300379 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300380 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300381 if (debug > 2) {
382 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300383 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300384 for (i = 0; i < len; i++)
385 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300386 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300387 for (i = 0; i < alen; i++)
388 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300389 printk(KERN_CONT "\n");
390 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300391 return 0;
392}
393
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300394static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300395{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300396 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300397 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300398
399 if (state->single_master)
400 flags |= 0xC0;
401
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300402 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
403 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
404 mm1[1] = ((reg >> 16) & 0xFF);
405 mm1[2] = ((reg >> 24) & 0xFF) | flags;
406 mm1[3] = ((reg >> 7) & 0xFF);
407 len = 4;
408 } else {
409 mm1[0] = ((reg << 1) & 0xFF);
410 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
411 len = 2;
412 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300413 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300414 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300415 if (status < 0)
416 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300417 if (data)
418 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300419
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300420 return 0;
421}
422
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300423static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300424{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300425 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300426}
427
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300428static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300429{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300430 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300431 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300432
433 if (state->single_master)
434 flags |= 0xC0;
435
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300436 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
437 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
438 mm1[1] = ((reg >> 16) & 0xFF);
439 mm1[2] = ((reg >> 24) & 0xFF) | flags;
440 mm1[3] = ((reg >> 7) & 0xFF);
441 len = 4;
442 } else {
443 mm1[0] = ((reg << 1) & 0xFF);
444 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
445 len = 2;
446 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300447 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300448 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300449 if (status < 0)
450 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300451 if (data)
452 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300453 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300454
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300455 return 0;
456}
457
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300458static int read32(struct drxk_state *state, u32 reg, u32 *data)
459{
460 return read32_flags(state, reg, data, 0);
461}
462
463static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300464{
465 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300466
467 if (state->single_master)
468 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300469 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
470 mm[0] = (((reg << 1) & 0xFF) | 0x01);
471 mm[1] = ((reg >> 16) & 0xFF);
472 mm[2] = ((reg >> 24) & 0xFF) | flags;
473 mm[3] = ((reg >> 7) & 0xFF);
474 len = 4;
475 } else {
476 mm[0] = ((reg << 1) & 0xFF);
477 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
478 len = 2;
479 }
480 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300481 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300482
483 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300484 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300485}
486
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300487static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300488{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300489 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300490}
491
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300492static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300493{
494 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300495
496 if (state->single_master)
497 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300498 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
499 mm[0] = (((reg << 1) & 0xFF) | 0x01);
500 mm[1] = ((reg >> 16) & 0xFF);
501 mm[2] = ((reg >> 24) & 0xFF) | flags;
502 mm[3] = ((reg >> 7) & 0xFF);
503 len = 4;
504 } else {
505 mm[0] = ((reg << 1) & 0xFF);
506 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
507 len = 2;
508 }
509 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300510 mm[len + 1] = (data >> 8) & 0xff;
511 mm[len + 2] = (data >> 16) & 0xff;
512 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300513 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300514
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300515 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516}
517
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300518static int write32(struct drxk_state *state, u32 reg, u32 data)
519{
520 return write32_flags(state, reg, data, 0);
521}
522
523static int write_block(struct drxk_state *state, u32 Address,
524 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300525{
526 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300527 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300528
529 if (state->single_master)
530 Flags |= 0xC0;
531
Oliver Endrissebc7de22011-07-03 13:49:44 -0300532 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300533 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300534 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300535 u8 *AdrBuf = &state->Chunk[0];
536 u32 AdrLength = 0;
537
Oliver Endrissebc7de22011-07-03 13:49:44 -0300538 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
539 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
540 AdrBuf[1] = ((Address >> 16) & 0xFF);
541 AdrBuf[2] = ((Address >> 24) & 0xFF);
542 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300543 AdrBuf[2] |= Flags;
544 AdrLength = 4;
545 if (Chunk == state->m_ChunkSize)
546 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300547 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300548 AdrBuf[0] = ((Address << 1) & 0xFF);
549 AdrBuf[1] = (((Address >> 16) & 0x0F) |
550 ((Address >> 18) & 0xF0));
551 AdrLength = 2;
552 }
553 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300554 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
555 if (debug > 1) {
556 int i;
557 if (pBlock)
558 for (i = 0; i < Chunk; i++)
559 printk(KERN_CONT " %02x", pBlock[i]);
560 printk(KERN_CONT "\n");
561 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300562 status = i2c_write(state, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300563 &state->Chunk[0], Chunk + AdrLength);
564 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300565 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
566 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300567 break;
568 }
569 pBlock += Chunk;
570 Address += (Chunk >> 1);
571 BlkSize -= Chunk;
572 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300573 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300574}
575
576#ifndef DRXK_MAX_RETRIES_POWERUP
577#define DRXK_MAX_RETRIES_POWERUP 20
578#endif
579
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200580static int PowerUpDevice(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300581{
582 int status;
583 u8 data = 0;
584 u16 retryCount = 0;
585
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300586 dprintk(1, "\n");
587
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300588 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300589 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300590 do {
591 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300592 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300593 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300594 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300595 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300596 if (status < 0)
597 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300598 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300599 &data);
600 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300601 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300602 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
603 goto error;
604 }
605
606 /* Make sure all clk domains are active */
607 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
608 if (status < 0)
609 goto error;
610 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
611 if (status < 0)
612 goto error;
613 /* Enable pll lock tests */
614 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
615 if (status < 0)
616 goto error;
617
618 state->m_currentPowerMode = DRX_POWER_UP;
619
620error:
621 if (status < 0)
622 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
623
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300624 return status;
625}
626
627
628static int init_state(struct drxk_state *state)
629{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300630 /*
631 * FIXME: most (all?) of the values bellow should be moved into
632 * struct drxk_config, as they are probably board-specific
633 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300634 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
635 u32 ulVSBIfAgcOutputLevel = 0;
636 u32 ulVSBIfAgcMinLevel = 0;
637 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
638 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300639
Oliver Endrissebc7de22011-07-03 13:49:44 -0300640 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
641 u32 ulVSBRfAgcOutputLevel = 0;
642 u32 ulVSBRfAgcMinLevel = 0;
643 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
644 u32 ulVSBRfAgcSpeed = 3;
645 u32 ulVSBRfAgcTop = 9500;
646 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300647
Oliver Endrissebc7de22011-07-03 13:49:44 -0300648 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
649 u32 ulATVIfAgcOutputLevel = 0;
650 u32 ulATVIfAgcMinLevel = 0;
651 u32 ulATVIfAgcMaxLevel = 0;
652 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300653
Oliver Endrissebc7de22011-07-03 13:49:44 -0300654 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
655 u32 ulATVRfAgcOutputLevel = 0;
656 u32 ulATVRfAgcMinLevel = 0;
657 u32 ulATVRfAgcMaxLevel = 0;
658 u32 ulATVRfAgcTop = 9500;
659 u32 ulATVRfAgcCutOffCurrent = 4000;
660 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300661
662 u32 ulQual83 = DEFAULT_MER_83;
663 u32 ulQual93 = DEFAULT_MER_93;
664
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300665 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
666 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
667
668 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
669 /* io_pad_cfg_mode output mode is drive always */
670 /* io_pad_cfg_drive is set to power 2 (23 mA) */
671 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300672 u32 ulInvertTSClock = 0;
673 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300674 u32 ulDVBTBitrate = 50000000;
675 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
676
677 u32 ulInsertRSByte = 0;
678
679 u32 ulRfMirror = 1;
680 u32 ulPowerDown = 0;
681
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300682 dprintk(1, "\n");
683
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300684 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300685 state->m_hasDVBT = false;
686 state->m_hasDVBC = false;
687 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300688 state->m_hasOOB = false;
689 state->m_hasAudio = false;
690
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300691 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200692 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300693
694 state->m_oscClockFreq = 0;
695 state->m_smartAntInverted = false;
696 state->m_bPDownOpenBridge = false;
697
698 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300699 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300700 /* Timing div, 250ns/Psys */
701 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
702 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
703 HI_I2C_DELAY) / 1000;
704 /* Clipping */
705 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
706 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
707 state->m_HICfgWakeUpKey = (state->demod_address << 1);
708 /* port/bridge/power down ctrl */
709 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
710
711 state->m_bPowerDown = (ulPowerDown != 0);
712
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300713 state->m_DRXK_A3_PATCH_CODE = false;
714
715 /* Init AGC and PGA parameters */
716 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300717 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
718 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
719 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
720 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
721 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300722 state->m_vsbPgaCfg = 140;
723
724 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300725 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
726 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
727 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
728 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
729 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
730 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
731 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
732 state->m_vsbPreSawCfg.reference = 0x07;
733 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300734
735 state->m_Quality83percent = DEFAULT_MER_83;
736 state->m_Quality93percent = DEFAULT_MER_93;
737 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
738 state->m_Quality83percent = ulQual83;
739 state->m_Quality93percent = ulQual93;
740 }
741
742 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300743 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
744 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
745 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
746 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
747 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300748
749 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300750 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
751 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
752 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
753 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
754 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
755 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
756 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
757 state->m_atvPreSawCfg.reference = 0x04;
758 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300759
760
761 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300762 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
763 state->m_dvbtRfAgcCfg.outputLevel = 0;
764 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
765 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
766 state->m_dvbtRfAgcCfg.top = 0x2100;
767 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
768 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300769
770
771 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300772 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
773 state->m_dvbtIfAgcCfg.outputLevel = 0;
774 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
775 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
776 state->m_dvbtIfAgcCfg.top = 13424;
777 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
778 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300779 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300780 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
781 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
Oliver Endrissebc7de22011-07-03 13:49:44 -0300783 state->m_dvbtPreSawCfg.reference = 4;
784 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300785
786 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300787 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
788 state->m_qamRfAgcCfg.outputLevel = 0;
789 state->m_qamRfAgcCfg.minOutputLevel = 6023;
790 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
791 state->m_qamRfAgcCfg.top = 0x2380;
792 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
793 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300794
795 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300796 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
797 state->m_qamIfAgcCfg.outputLevel = 0;
798 state->m_qamIfAgcCfg.minOutputLevel = 0;
799 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
800 state->m_qamIfAgcCfg.top = 0x0511;
801 state->m_qamIfAgcCfg.cutOffCurrent = 0;
802 state->m_qamIfAgcCfg.speed = 3;
803 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300804 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
805
Oliver Endrissebc7de22011-07-03 13:49:44 -0300806 state->m_qamPgaCfg = 140;
807 state->m_qamPreSawCfg.reference = 4;
808 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300809
810 state->m_OperationMode = OM_NONE;
811 state->m_DrxkState = DRXK_UNINITIALIZED;
812
813 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300814 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
815 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300816 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
817 state->m_invertERR = false; /* If TRUE; invert ERR signal */
818 state->m_invertSTR = false; /* If TRUE; invert STR signals */
819 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
820 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300821
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300822 /* If TRUE; static MPEG clockrate will be used;
823 otherwise clockrate will adapt to the bitrate of the TS */
824
825 state->m_DVBTBitrate = ulDVBTBitrate;
826 state->m_DVBCBitrate = ulDVBCBitrate;
827
828 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300829
830 /* Maximum bitrate in b/s in case static clockrate is selected */
831 state->m_mpegTsStaticBitrate = 19392658;
832 state->m_disableTEIhandling = false;
833
834 if (ulInsertRSByte)
835 state->m_insertRSByte = true;
836
837 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
838 if (ulMpegLockTimeOut < 10000)
839 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
840 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
841 if (ulDemodLockTimeOut < 10000)
842 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
843
Oliver Endrissebc7de22011-07-03 13:49:44 -0300844 /* QAM defaults */
845 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300846 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300847 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
848 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300849
850 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
851 state->m_agcFastClipCtrlDelay = 0;
852
853 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300854
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300855 state->m_bPowerDown = false;
856 state->m_currentPowerMode = DRX_POWER_DOWN;
857
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300858 state->m_rfmirror = (ulRfMirror == 0);
859 state->m_IfAgcPol = false;
860 return 0;
861}
862
863static int DRXX_Open(struct drxk_state *state)
864{
865 int status = 0;
866 u32 jtag = 0;
867 u16 bid = 0;
868 u16 key = 0;
869
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300870 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300871 /* stop lock indicator process */
872 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
873 if (status < 0)
874 goto error;
875 /* Check device id */
876 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
877 if (status < 0)
878 goto error;
879 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
880 if (status < 0)
881 goto error;
882 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
883 if (status < 0)
884 goto error;
885 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
886 if (status < 0)
887 goto error;
888 status = write16(state, SIO_TOP_COMM_KEY__A, key);
889error:
890 if (status < 0)
891 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300892 return status;
893}
894
895static int GetDeviceCapabilities(struct drxk_state *state)
896{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300897 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300898 u32 sioTopJtagidLo = 0;
899 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300900 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300901
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300902 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300903
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300904 /* driver 0.9.0 */
905 /* stop lock indicator process */
906 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
907 if (status < 0)
908 goto error;
Martin Blumenstingl84183662012-10-04 14:22:55 -0300909 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300910 if (status < 0)
911 goto error;
912 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
913 if (status < 0)
914 goto error;
915 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
916 if (status < 0)
917 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300919 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
920 case 0:
921 /* ignore (bypass ?) */
922 break;
923 case 1:
924 /* 27 MHz */
925 state->m_oscClockFreq = 27000;
926 break;
927 case 2:
928 /* 20.25 MHz */
929 state->m_oscClockFreq = 20250;
930 break;
931 case 3:
932 /* 4 MHz */
933 state->m_oscClockFreq = 20250;
934 break;
935 default:
Masanari Iida9c768202012-11-30 14:10:25 +0900936 printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300937 return -EINVAL;
938 }
939 /*
940 Determine device capabilities
941 Based on pinning v14
942 */
943 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
944 if (status < 0)
945 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300946
Martin Blumenstingl257ee972012-07-04 17:38:23 -0300947 printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300948
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300949 /* driver 0.9.0 */
950 switch ((sioTopJtagidLo >> 29) & 0xF) {
951 case 0:
952 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300953 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300954 break;
955 case 2:
956 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300957 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300958 break;
959 case 3:
960 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300961 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300962 break;
963 default:
964 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
965 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300966 printk(KERN_ERR "drxk: Spin %d unknown\n",
967 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300968 goto error2;
969 }
970 switch ((sioTopJtagidLo >> 12) & 0xFF) {
971 case 0x13:
972 /* typeId = DRX3913K_TYPE_ID */
973 state->m_hasLNA = false;
974 state->m_hasOOB = false;
975 state->m_hasATV = false;
976 state->m_hasAudio = false;
977 state->m_hasDVBT = true;
978 state->m_hasDVBC = true;
979 state->m_hasSAWSW = true;
980 state->m_hasGPIO2 = false;
981 state->m_hasGPIO1 = false;
982 state->m_hasIRQN = false;
983 break;
984 case 0x15:
985 /* typeId = DRX3915K_TYPE_ID */
986 state->m_hasLNA = false;
987 state->m_hasOOB = false;
988 state->m_hasATV = true;
989 state->m_hasAudio = false;
990 state->m_hasDVBT = true;
991 state->m_hasDVBC = false;
992 state->m_hasSAWSW = true;
993 state->m_hasGPIO2 = true;
994 state->m_hasGPIO1 = true;
995 state->m_hasIRQN = false;
996 break;
997 case 0x16:
998 /* typeId = DRX3916K_TYPE_ID */
999 state->m_hasLNA = false;
1000 state->m_hasOOB = false;
1001 state->m_hasATV = true;
1002 state->m_hasAudio = false;
1003 state->m_hasDVBT = true;
1004 state->m_hasDVBC = false;
1005 state->m_hasSAWSW = true;
1006 state->m_hasGPIO2 = true;
1007 state->m_hasGPIO1 = true;
1008 state->m_hasIRQN = false;
1009 break;
1010 case 0x18:
1011 /* typeId = DRX3918K_TYPE_ID */
1012 state->m_hasLNA = false;
1013 state->m_hasOOB = false;
1014 state->m_hasATV = true;
1015 state->m_hasAudio = true;
1016 state->m_hasDVBT = true;
1017 state->m_hasDVBC = false;
1018 state->m_hasSAWSW = true;
1019 state->m_hasGPIO2 = true;
1020 state->m_hasGPIO1 = true;
1021 state->m_hasIRQN = false;
1022 break;
1023 case 0x21:
1024 /* typeId = DRX3921K_TYPE_ID */
1025 state->m_hasLNA = false;
1026 state->m_hasOOB = false;
1027 state->m_hasATV = true;
1028 state->m_hasAudio = true;
1029 state->m_hasDVBT = true;
1030 state->m_hasDVBC = true;
1031 state->m_hasSAWSW = true;
1032 state->m_hasGPIO2 = true;
1033 state->m_hasGPIO1 = true;
1034 state->m_hasIRQN = false;
1035 break;
1036 case 0x23:
1037 /* typeId = DRX3923K_TYPE_ID */
1038 state->m_hasLNA = false;
1039 state->m_hasOOB = false;
1040 state->m_hasATV = true;
1041 state->m_hasAudio = true;
1042 state->m_hasDVBT = true;
1043 state->m_hasDVBC = true;
1044 state->m_hasSAWSW = true;
1045 state->m_hasGPIO2 = true;
1046 state->m_hasGPIO1 = true;
1047 state->m_hasIRQN = false;
1048 break;
1049 case 0x25:
1050 /* typeId = DRX3925K_TYPE_ID */
1051 state->m_hasLNA = false;
1052 state->m_hasOOB = false;
1053 state->m_hasATV = true;
1054 state->m_hasAudio = true;
1055 state->m_hasDVBT = true;
1056 state->m_hasDVBC = true;
1057 state->m_hasSAWSW = true;
1058 state->m_hasGPIO2 = true;
1059 state->m_hasGPIO1 = true;
1060 state->m_hasIRQN = false;
1061 break;
1062 case 0x26:
1063 /* typeId = DRX3926K_TYPE_ID */
1064 state->m_hasLNA = false;
1065 state->m_hasOOB = false;
1066 state->m_hasATV = true;
1067 state->m_hasAudio = false;
1068 state->m_hasDVBT = true;
1069 state->m_hasDVBC = true;
1070 state->m_hasSAWSW = true;
1071 state->m_hasGPIO2 = true;
1072 state->m_hasGPIO1 = true;
1073 state->m_hasIRQN = false;
1074 break;
1075 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001076 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001077 ((sioTopJtagidLo >> 12) & 0xFF));
1078 status = -EINVAL;
1079 goto error2;
1080 }
1081
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001082 printk(KERN_INFO
1083 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1084 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1085 state->m_oscClockFreq / 1000,
1086 state->m_oscClockFreq % 1000);
1087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001088error:
1089 if (status < 0)
1090 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1091
1092error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093 return status;
1094}
1095
1096static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1097{
1098 int status;
1099 bool powerdown_cmd;
1100
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001101 dprintk(1, "\n");
1102
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001104 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001105 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001106 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001107 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1108 msleep(1);
1109
1110 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001111 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1112 ((state->m_HICfgCtrl) &
1113 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1114 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001115 if (powerdown_cmd == false) {
1116 /* Wait until command rdy */
1117 u32 retryCount = 0;
1118 u16 waitCmd;
1119
1120 do {
1121 msleep(1);
1122 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001123 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1124 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001125 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1126 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001127 if (status < 0)
1128 goto error;
1129 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001130 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001131error:
1132 if (status < 0)
1133 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1134
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001135 return status;
1136}
1137
1138static int HI_CfgCommand(struct drxk_state *state)
1139{
1140 int status;
1141
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001142 dprintk(1, "\n");
1143
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001144 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001146 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1156 if (status < 0)
1157 goto error;
1158 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1159 if (status < 0)
1160 goto error;
1161 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1162 if (status < 0)
1163 goto error;
1164 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1165 if (status < 0)
1166 goto error;
1167
1168 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1169error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001170 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001171 if (status < 0)
1172 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001173 return status;
1174}
1175
1176static int InitHI(struct drxk_state *state)
1177{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001178 dprintk(1, "\n");
1179
Oliver Endrissebc7de22011-07-03 13:49:44 -03001180 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001181 state->m_HICfgTimeout = 0x96FF;
1182 /* port/bridge/power down ctrl */
1183 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001184
Oliver Endrissebc7de22011-07-03 13:49:44 -03001185 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001186}
1187
1188static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1189{
1190 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001191 u16 sioPdrMclkCfg = 0;
1192 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001193 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001194
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001195 dprintk(1, ": mpeg %s, %s mode\n",
1196 mpegEnable ? "enable" : "disable",
1197 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001198
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001199 /* stop lock indicator process */
1200 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1201 if (status < 0)
1202 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001203
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001204 /* MPEG TS pad configuration */
Martin Blumenstingl84183662012-10-04 14:22:55 -03001205 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001206 if (status < 0)
1207 goto error;
1208
1209 if (mpegEnable == false) {
1210 /* Set MPEG TS pads to inputmode */
1211 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1239 if (status < 0)
1240 goto error;
1241 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1242 if (status < 0)
1243 goto error;
1244 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1245 if (status < 0)
1246 goto error;
1247 } else {
1248 /* Enable MPEG output */
1249 sioPdrMdxCfg =
1250 ((state->m_TSDataStrength <<
1251 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1252 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1253 SIO_PDR_MCLK_CFG_DRIVE__B) |
1254 0x0003);
1255
1256 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1257 if (status < 0)
1258 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001259
1260 if (state->enable_merr_cfg)
1261 err_cfg = sioPdrMdxCfg;
1262
1263 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001264 if (status < 0)
1265 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001266 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001267 if (status < 0)
1268 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001269
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001270 if (state->m_enableParallel == true) {
1271 /* paralel -> enable MD1 to MD7 */
1272 status = write16(state, SIO_PDR_MD1_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_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001276 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001277 goto error;
1278 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001279 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001280 goto error;
1281 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001282 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001283 goto error;
1284 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001285 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001286 goto error;
1287 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1288 if (status < 0)
1289 goto error;
1290 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1291 if (status < 0)
1292 goto error;
1293 } else {
1294 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1295 SIO_PDR_MD0_CFG_DRIVE__B)
1296 | 0x0003);
1297 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001298 status = write16(state, SIO_PDR_MD1_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_MD2_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_MD3_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;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001307 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001308 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001309 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001310 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001311 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001312 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001313 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001314 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001315 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001316 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001317 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001318 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001319 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001320 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001321 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001322 goto error;
1323 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001324 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001325 goto error;
1326 }
1327 /* Enable MB output over MPEG pads and ctl input */
1328 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1329 if (status < 0)
1330 goto error;
1331 /* Write nomagic word to enable pdr reg write */
1332 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1333error:
1334 if (status < 0)
1335 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001336 return status;
1337}
1338
1339static int MPEGTSDisable(struct drxk_state *state)
1340{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001341 dprintk(1, "\n");
1342
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001343 return MPEGTSConfigurePins(state, false);
1344}
1345
1346static int BLChainCmd(struct drxk_state *state,
1347 u16 romOffset, u16 nrOfElements, u32 timeOut)
1348{
1349 u16 blStatus = 0;
1350 int status;
1351 unsigned long end;
1352
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001353 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001354 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001355 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1356 if (status < 0)
1357 goto error;
1358 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1359 if (status < 0)
1360 goto error;
1361 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1362 if (status < 0)
1363 goto error;
1364 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1365 if (status < 0)
1366 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001367
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001368 end = jiffies + msecs_to_jiffies(timeOut);
1369 do {
1370 msleep(1);
1371 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1372 if (status < 0)
1373 goto error;
1374 } while ((blStatus == 0x1) &&
1375 ((time_is_after_jiffies(end))));
1376
1377 if (blStatus == 0x1) {
1378 printk(KERN_ERR "drxk: SIO not ready\n");
1379 status = -EINVAL;
1380 goto error2;
1381 }
1382error:
1383 if (status < 0)
1384 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1385error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001386 mutex_unlock(&state->mutex);
1387 return status;
1388}
1389
1390
1391static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001392 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001393{
1394 const u8 *pSrc = pMCImage;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395 u32 Address;
1396 u16 nBlocks;
1397 u16 BlockSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001398 u32 offset = 0;
1399 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001400 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001401
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001402 dprintk(1, "\n");
1403
Hans Verkuil5becbc52012-05-14 10:22:58 -03001404 /* down the drain (we don't care about MAGIC_WORD) */
1405#if 0
1406 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001407 Drain = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001408#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001409 pSrc += sizeof(u16);
1410 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001411 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001412 pSrc += sizeof(u16);
1413 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001414
1415 for (i = 0; i < nBlocks; i += 1) {
1416 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 (pSrc[2] << 8) | pSrc[3];
1418 pSrc += sizeof(u32);
1419 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001420
1421 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001422 pSrc += sizeof(u16);
1423 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424
Hans Verkuil5becbc52012-05-14 10:22:58 -03001425#if 0
1426 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001427 Flags = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001428#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001429 pSrc += sizeof(u16);
1430 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001431
Hans Verkuil5becbc52012-05-14 10:22:58 -03001432#if 0
1433 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001434 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001435#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001436 pSrc += sizeof(u16);
1437 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001438
1439 if (offset + BlockSize > Length) {
1440 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1441 return -EINVAL;
1442 }
1443
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001444 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001445 if (status < 0) {
1446 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001447 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001448 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 pSrc += BlockSize;
1450 offset += BlockSize;
1451 }
1452 return status;
1453}
1454
1455static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1456{
1457 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001458 u16 data = 0;
1459 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1461 unsigned long end;
1462
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001463 dprintk(1, "\n");
1464
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001466 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001467 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1468 }
1469
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001470 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1471 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001472 /* tokenring already has correct status */
1473 return status;
1474 }
1475 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001476 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001477
Oliver Endrissebc7de22011-07-03 13:49:44 -03001478 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001479 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001480 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001481 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001482 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001483 msleep(1);
1484 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001485 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001486 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001487 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001488 }
1489 return status;
1490}
1491
1492static int MPEGTSStop(struct drxk_state *state)
1493{
1494 int status = 0;
1495 u16 fecOcSncMode = 0;
1496 u16 fecOcIprMode = 0;
1497
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001498 dprintk(1, "\n");
1499
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001500 /* Gracefull shutdown (byte boundaries) */
1501 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1502 if (status < 0)
1503 goto error;
1504 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1505 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1506 if (status < 0)
1507 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001509 /* Suppress MCLK during absence of data */
1510 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1511 if (status < 0)
1512 goto error;
1513 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1514 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1515
1516error:
1517 if (status < 0)
1518 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1519
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520 return status;
1521}
1522
1523static int scu_command(struct drxk_state *state,
1524 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001525 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001526{
1527#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1528#error DRXK register mapping no longer compatible with this routine!
1529#endif
1530 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001531 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001532 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001533 u8 buffer[34];
1534 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001535 const char *p;
1536 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001537
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001538 dprintk(1, "\n");
1539
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001540 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001541 ((resultLen > 0) && (result == NULL))) {
1542 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1543 return status;
1544 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001545
1546 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001547
1548 /* assume that the command register is ready
1549 since it is checked afterwards */
1550 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1551 buffer[cnt++] = (parameter[ii] & 0xFF);
1552 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1553 }
1554 buffer[cnt++] = (cmd & 0xFF);
1555 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1556
1557 write_block(state, SCU_RAM_PARAM_0__A -
1558 (parameterLen - 1), cnt, buffer);
1559 /* Wait until SCU has processed command */
1560 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001561 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001562 msleep(1);
1563 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1564 if (status < 0)
1565 goto error;
1566 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1567 if (curCmd != DRX_SCU_READY) {
1568 printk(KERN_ERR "drxk: SCU not ready\n");
1569 status = -EIO;
1570 goto error2;
1571 }
1572 /* read results */
1573 if ((resultLen > 0) && (result != NULL)) {
1574 s16 err;
1575 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001577 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1578 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001579 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001580 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001581 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001582
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001583 /* Check if an error was reported by SCU */
1584 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001585 if (err >= 0)
1586 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001587
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001588 /* check for the known error codes */
1589 switch (err) {
1590 case SCU_RESULT_UNKCMD:
1591 p = "SCU_RESULT_UNKCMD";
1592 break;
1593 case SCU_RESULT_UNKSTD:
1594 p = "SCU_RESULT_UNKSTD";
1595 break;
1596 case SCU_RESULT_SIZE:
1597 p = "SCU_RESULT_SIZE";
1598 break;
1599 case SCU_RESULT_INVPAR:
1600 p = "SCU_RESULT_INVPAR";
1601 break;
1602 default: /* Other negative values are errors */
1603 sprintf(errname, "ERROR: %d\n", err);
1604 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001605 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001606 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1607 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1608 status = -EINVAL;
1609 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001610 }
1611
1612error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001613 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001614 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001615error2:
1616 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001617 return status;
1618}
1619
1620static int SetIqmAf(struct drxk_state *state, bool active)
1621{
1622 u16 data = 0;
1623 int status;
1624
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001625 dprintk(1, "\n");
1626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001627 /* Configure IQM */
1628 status = read16(state, IQM_AF_STDBY__A, &data);
1629 if (status < 0)
1630 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001631
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001632 if (!active) {
1633 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1634 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1635 | IQM_AF_STDBY_STDBY_PD_STANDBY
1636 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1637 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1638 } else {
1639 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1640 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1641 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1642 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1643 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1644 );
1645 }
1646 status = write16(state, IQM_AF_STDBY__A, data);
1647
1648error:
1649 if (status < 0)
1650 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001651 return status;
1652}
1653
Oliver Endrissebc7de22011-07-03 13:49:44 -03001654static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001655{
1656 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001657 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001658
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001659 dprintk(1, "\n");
1660
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001661 /* Check arguments */
1662 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001663 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001664
1665 switch (*mode) {
1666 case DRX_POWER_UP:
1667 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1668 break;
1669 case DRXK_POWER_DOWN_OFDM:
1670 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1671 break;
1672 case DRXK_POWER_DOWN_CORE:
1673 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1674 break;
1675 case DRXK_POWER_DOWN_PLL:
1676 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1677 break;
1678 case DRX_POWER_DOWN:
1679 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1680 break;
1681 default:
1682 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001683 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001684 }
1685
1686 /* If already in requested power mode, do nothing */
1687 if (state->m_currentPowerMode == *mode)
1688 return 0;
1689
1690 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001691 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001692 status = PowerUpDevice(state);
1693 if (status < 0)
1694 goto error;
1695 status = DVBTEnableOFDMTokenRing(state, true);
1696 if (status < 0)
1697 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001698 }
1699
1700 if (*mode == DRX_POWER_UP) {
1701 /* Restore analog & pin configuartion */
1702 } else {
1703 /* Power down to requested mode */
1704 /* Backup some register settings */
1705 /* Set pins with possible pull-ups connected
1706 to them in input mode */
1707 /* Analog power down */
1708 /* ADC power down */
1709 /* Power down device */
1710 /* stop all comm_exec */
1711 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001712 switch (state->m_OperationMode) {
1713 case OM_DVBT:
1714 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001715 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001716 goto error;
1717 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001718 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001719 goto error;
1720 break;
1721 case OM_QAM_ITU_A:
1722 case OM_QAM_ITU_C:
1723 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001724 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001725 goto error;
1726 status = PowerDownQAM(state);
1727 if (status < 0)
1728 goto error;
1729 break;
1730 default:
1731 break;
1732 }
1733 status = DVBTEnableOFDMTokenRing(state, false);
1734 if (status < 0)
1735 goto error;
1736 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1737 if (status < 0)
1738 goto error;
1739 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1740 if (status < 0)
1741 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001742
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001743 if (*mode != DRXK_POWER_DOWN_OFDM) {
1744 state->m_HICfgCtrl |=
1745 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1746 status = HI_CfgCommand(state);
1747 if (status < 0)
1748 goto error;
1749 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001750 }
1751 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001752
1753error:
1754 if (status < 0)
1755 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1756
Oliver Endrissebc7de22011-07-03 13:49:44 -03001757 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001758}
1759
1760static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1761{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001762 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001763 u16 cmdResult = 0;
1764 u16 data = 0;
1765 int status;
1766
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001767 dprintk(1, "\n");
1768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001769 status = read16(state, SCU_COMM_EXEC__A, &data);
1770 if (status < 0)
1771 goto error;
1772 if (data == SCU_COMM_EXEC_ACTIVE) {
1773 /* Send OFDM stop command */
1774 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 -03001775 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001776 goto error;
1777 /* Send OFDM reset command */
1778 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1779 if (status < 0)
1780 goto error;
1781 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001783 /* Reset datapath for OFDM, processors first */
1784 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1785 if (status < 0)
1786 goto error;
1787 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1788 if (status < 0)
1789 goto error;
1790 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1791 if (status < 0)
1792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001794 /* powerdown AFE */
1795 status = SetIqmAf(state, false);
1796 if (status < 0)
1797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001799 /* powerdown to OFDM mode */
1800 if (setPowerMode) {
1801 status = CtrlPowerMode(state, &powerMode);
1802 if (status < 0)
1803 goto error;
1804 }
1805error:
1806 if (status < 0)
1807 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001808 return status;
1809}
1810
Oliver Endrissebc7de22011-07-03 13:49:44 -03001811static int SetOperationMode(struct drxk_state *state,
1812 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001813{
1814 int status = 0;
1815
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001816 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001817 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001818 Stop and power down previous standard
1819 TODO investigate total power down instead of partial
1820 power down depending on "previous" standard.
1821 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001823 /* disable HW lock indicator */
1824 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1825 if (status < 0)
1826 goto error;
1827
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001828 /* Device is already at the required mode */
1829 if (state->m_OperationMode == oMode)
1830 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001831
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001832 switch (state->m_OperationMode) {
1833 /* OM_NONE was added for start up */
1834 case OM_NONE:
1835 break;
1836 case OM_DVBT:
1837 status = MPEGTSStop(state);
1838 if (status < 0)
1839 goto error;
1840 status = PowerDownDVBT(state, true);
1841 if (status < 0)
1842 goto error;
1843 state->m_OperationMode = OM_NONE;
1844 break;
1845 case OM_QAM_ITU_A: /* fallthrough */
1846 case OM_QAM_ITU_C:
1847 status = MPEGTSStop(state);
1848 if (status < 0)
1849 goto error;
1850 status = PowerDownQAM(state);
1851 if (status < 0)
1852 goto error;
1853 state->m_OperationMode = OM_NONE;
1854 break;
1855 case OM_QAM_ITU_B:
1856 default:
1857 status = -EINVAL;
1858 goto error;
1859 }
1860
1861 /*
1862 Power up new standard
1863 */
1864 switch (oMode) {
1865 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001866 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001867 state->m_OperationMode = oMode;
1868 status = SetDVBTStandard(state, oMode);
1869 if (status < 0)
1870 goto error;
1871 break;
1872 case OM_QAM_ITU_A: /* fallthrough */
1873 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001874 dprintk(1, ": DVB-C Annex %c\n",
1875 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001876 state->m_OperationMode = oMode;
1877 status = SetQAMStandard(state, oMode);
1878 if (status < 0)
1879 goto error;
1880 break;
1881 case OM_QAM_ITU_B:
1882 default:
1883 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001884 }
1885error:
1886 if (status < 0)
1887 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1888 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889}
1890
1891static int Start(struct drxk_state *state, s32 offsetFreq,
1892 s32 IntermediateFrequency)
1893{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001894 int status = -EINVAL;
1895
1896 u16 IFreqkHz;
1897 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001898
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001899 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001900 if (state->m_DrxkState != DRXK_STOPPED &&
1901 state->m_DrxkState != DRXK_DTV_STARTED)
1902 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001903
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001904 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001905
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001906 if (IntermediateFrequency < 0) {
1907 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1908 IntermediateFrequency = -IntermediateFrequency;
1909 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001911 switch (state->m_OperationMode) {
1912 case OM_QAM_ITU_A:
1913 case OM_QAM_ITU_C:
1914 IFreqkHz = (IntermediateFrequency / 1000);
1915 status = SetQAM(state, IFreqkHz, OffsetkHz);
1916 if (status < 0)
1917 goto error;
1918 state->m_DrxkState = DRXK_DTV_STARTED;
1919 break;
1920 case OM_DVBT:
1921 IFreqkHz = (IntermediateFrequency / 1000);
1922 status = MPEGTSStop(state);
1923 if (status < 0)
1924 goto error;
1925 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1926 if (status < 0)
1927 goto error;
1928 status = DVBTStart(state);
1929 if (status < 0)
1930 goto error;
1931 state->m_DrxkState = DRXK_DTV_STARTED;
1932 break;
1933 default:
1934 break;
1935 }
1936error:
1937 if (status < 0)
1938 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001939 return status;
1940}
1941
1942static int ShutDown(struct drxk_state *state)
1943{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001944 dprintk(1, "\n");
1945
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001946 MPEGTSStop(state);
1947 return 0;
1948}
1949
Jean Delvarea3ad56d2013-03-20 12:43:21 +00001950static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001951{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001952 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001953
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001954 dprintk(1, "\n");
1955
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001956 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001957 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001958
1959 *pLockStatus = NOT_LOCKED;
1960
1961 /* define the SCU command code */
1962 switch (state->m_OperationMode) {
1963 case OM_QAM_ITU_A:
1964 case OM_QAM_ITU_B:
1965 case OM_QAM_ITU_C:
1966 status = GetQAMLockStatus(state, pLockStatus);
1967 break;
1968 case OM_DVBT:
1969 status = GetDVBTLockStatus(state, pLockStatus);
1970 break;
1971 default:
1972 break;
1973 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001974error:
1975 if (status < 0)
1976 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001977 return status;
1978}
1979
1980static int MPEGTSStart(struct drxk_state *state)
1981{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001982 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001983
1984 u16 fecOcSncMode = 0;
1985
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001986 /* Allow OC to sync again */
1987 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1988 if (status < 0)
1989 goto error;
1990 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1991 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1992 if (status < 0)
1993 goto error;
1994 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1995error:
1996 if (status < 0)
1997 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001998 return status;
1999}
2000
2001static int MPEGTSDtoInit(struct drxk_state *state)
2002{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002003 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002004
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002005 dprintk(1, "\n");
2006
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002007 /* Rate integration settings */
2008 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
2009 if (status < 0)
2010 goto error;
2011 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
2012 if (status < 0)
2013 goto error;
2014 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2015 if (status < 0)
2016 goto error;
2017 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2018 if (status < 0)
2019 goto error;
2020 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2021 if (status < 0)
2022 goto error;
2023 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2024 if (status < 0)
2025 goto error;
2026 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2027 if (status < 0)
2028 goto error;
2029 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2030 if (status < 0)
2031 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002032
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002033 /* Additional configuration */
2034 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2035 if (status < 0)
2036 goto error;
2037 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2038 if (status < 0)
2039 goto error;
2040 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2041error:
2042 if (status < 0)
2043 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2044
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002045 return status;
2046}
2047
Oliver Endrissebc7de22011-07-03 13:49:44 -03002048static int MPEGTSDtoSetup(struct drxk_state *state,
2049 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002050{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002051 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002052
Oliver Endrissebc7de22011-07-03 13:49:44 -03002053 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2054 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2055 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2056 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2057 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2058 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2059 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002060 u16 fecOcTmdMode = 0;
2061 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002062 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002063 bool staticCLK = false;
2064
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002065 dprintk(1, "\n");
2066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002067 /* Check insertion of the Reed-Solomon parity bytes */
2068 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2069 if (status < 0)
2070 goto error;
2071 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2072 if (status < 0)
2073 goto error;
2074 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2075 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2076 if (state->m_insertRSByte == true) {
2077 /* enable parity symbol forward */
2078 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2079 /* MVAL disable during parity bytes */
2080 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2081 /* TS burst length to 204 */
2082 fecOcDtoBurstLen = 204;
2083 }
2084
2085 /* Check serial or parrallel output */
2086 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2087 if (state->m_enableParallel == false) {
2088 /* MPEG data output is serial -> set ipr_mode[0] */
2089 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2090 }
2091
2092 switch (oMode) {
2093 case OM_DVBT:
2094 maxBitRate = state->m_DVBTBitrate;
2095 fecOcTmdMode = 3;
2096 fecOcRcnCtlRate = 0xC00000;
2097 staticCLK = state->m_DVBTStaticCLK;
2098 break;
2099 case OM_QAM_ITU_A: /* fallthrough */
2100 case OM_QAM_ITU_C:
2101 fecOcTmdMode = 0x0004;
2102 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2103 maxBitRate = state->m_DVBCBitrate;
2104 staticCLK = state->m_DVBCStaticCLK;
2105 break;
2106 default:
2107 status = -EINVAL;
2108 } /* switch (standard) */
2109 if (status < 0)
2110 goto error;
2111
2112 /* Configure DTO's */
2113 if (staticCLK) {
2114 u32 bitRate = 0;
2115
2116 /* Rational DTO for MCLK source (static MCLK rate),
2117 Dynamic DTO for optimal grouping
2118 (avoid intra-packet gaps),
2119 DTO offset enable to sync TS burst with MSTRT */
2120 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2121 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2122 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2123 FEC_OC_FCT_MODE_VIRT_ENA__M);
2124
2125 /* Check user defined bitrate */
2126 bitRate = maxBitRate;
2127 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2128 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002129 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002130 /* Rational DTO period:
2131 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002132
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002133 Result should be floored,
2134 to make sure >= requested bitrate
2135 */
2136 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2137 * 1000) / bitRate);
2138 if (fecOcDtoPeriod <= 2)
2139 fecOcDtoPeriod = 0;
2140 else
2141 fecOcDtoPeriod -= 2;
2142 fecOcTmdIntUpdRate = 8;
2143 } else {
2144 /* (commonAttr->staticCLK == false) => dynamic mode */
2145 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2146 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2147 fecOcTmdIntUpdRate = 5;
2148 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002150 /* Write appropriate registers with requested configuration */
2151 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2152 if (status < 0)
2153 goto error;
2154 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2155 if (status < 0)
2156 goto error;
2157 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2158 if (status < 0)
2159 goto error;
2160 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2161 if (status < 0)
2162 goto error;
2163 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2164 if (status < 0)
2165 goto error;
2166 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2167 if (status < 0)
2168 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002169
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002170 /* Rate integration settings */
2171 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2172 if (status < 0)
2173 goto error;
2174 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2175 if (status < 0)
2176 goto error;
2177 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2178error:
2179 if (status < 0)
2180 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181 return status;
2182}
2183
2184static int MPEGTSConfigurePolarity(struct drxk_state *state)
2185{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002186 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002187
2188 /* Data mask for the output data byte */
2189 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002190 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2191 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2192 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2193 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002194
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002195 dprintk(1, "\n");
2196
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197 /* Control selective inversion of output bits */
2198 fecOcRegIprInvert &= (~(InvertDataMask));
2199 if (state->m_invertDATA == true)
2200 fecOcRegIprInvert |= InvertDataMask;
2201 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2202 if (state->m_invertERR == true)
2203 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2204 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2205 if (state->m_invertSTR == true)
2206 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2207 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2208 if (state->m_invertVAL == true)
2209 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2210 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2211 if (state->m_invertCLK == true)
2212 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002213
2214 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215}
2216
2217#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2218
2219static int SetAgcRf(struct drxk_state *state,
2220 struct SCfgAgc *pAgcCfg, bool isDTV)
2221{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002222 int status = -EINVAL;
2223 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002224 struct SCfgAgc *pIfAgcSettings;
2225
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002226 dprintk(1, "\n");
2227
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002228 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002229 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002230
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002231 switch (pAgcCfg->ctrlMode) {
2232 case DRXK_AGC_CTRL_AUTO:
2233 /* Enable RF AGC DAC */
2234 status = read16(state, IQM_AF_STDBY__A, &data);
2235 if (status < 0)
2236 goto error;
2237 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2238 status = write16(state, IQM_AF_STDBY__A, data);
2239 if (status < 0)
2240 goto error;
2241 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2242 if (status < 0)
2243 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002244
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002245 /* Enable SCU RF AGC loop */
2246 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002247
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002248 /* Polarity */
2249 if (state->m_RfAgcPol)
2250 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2251 else
2252 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2253 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2254 if (status < 0)
2255 goto error;
2256
2257 /* Set speed (using complementary reduction value) */
2258 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2259 if (status < 0)
2260 goto error;
2261
2262 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2263 data |= (~(pAgcCfg->speed <<
2264 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2265 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2266
2267 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2268 if (status < 0)
2269 goto error;
2270
2271 if (IsDVBT(state))
2272 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2273 else if (IsQAM(state))
2274 pIfAgcSettings = &state->m_qamIfAgcCfg;
2275 else
2276 pIfAgcSettings = &state->m_atvIfAgcCfg;
2277 if (pIfAgcSettings == NULL) {
2278 status = -EINVAL;
2279 goto error;
2280 }
2281
2282 /* Set TOP, only if IF-AGC is in AUTO mode */
2283 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2284 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002285 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002286 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002287
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002288 /* Cut-Off current */
2289 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2290 if (status < 0)
2291 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002292
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002293 /* Max. output level */
2294 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2295 if (status < 0)
2296 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002297
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002298 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002299
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002300 case DRXK_AGC_CTRL_USER:
2301 /* Enable RF AGC DAC */
2302 status = read16(state, IQM_AF_STDBY__A, &data);
2303 if (status < 0)
2304 goto error;
2305 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2306 status = write16(state, IQM_AF_STDBY__A, data);
2307 if (status < 0)
2308 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002310 /* Disable SCU RF AGC loop */
2311 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2312 if (status < 0)
2313 goto error;
2314 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2315 if (state->m_RfAgcPol)
2316 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2317 else
2318 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2319 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2320 if (status < 0)
2321 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002323 /* SCU c.o.c. to 0, enabling full control range */
2324 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2325 if (status < 0)
2326 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002327
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002328 /* Write value to output pin */
2329 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2330 if (status < 0)
2331 goto error;
2332 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002334 case DRXK_AGC_CTRL_OFF:
2335 /* Disable RF AGC DAC */
2336 status = read16(state, IQM_AF_STDBY__A, &data);
2337 if (status < 0)
2338 goto error;
2339 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2340 status = write16(state, IQM_AF_STDBY__A, data);
2341 if (status < 0)
2342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002344 /* Disable SCU RF AGC loop */
2345 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2346 if (status < 0)
2347 goto error;
2348 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2349 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2350 if (status < 0)
2351 goto error;
2352 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002354 default:
2355 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002356
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002357 }
2358error:
2359 if (status < 0)
2360 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002361 return status;
2362}
2363
2364#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2365
Oliver Endrissebc7de22011-07-03 13:49:44 -03002366static int SetAgcIf(struct drxk_state *state,
2367 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002368{
2369 u16 data = 0;
2370 int status = 0;
2371 struct SCfgAgc *pRfAgcSettings;
2372
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002373 dprintk(1, "\n");
2374
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002375 switch (pAgcCfg->ctrlMode) {
2376 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002377
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002378 /* Enable IF AGC DAC */
2379 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002380 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002381 goto error;
2382 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2383 status = write16(state, IQM_AF_STDBY__A, data);
2384 if (status < 0)
2385 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002386
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002387 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2388 if (status < 0)
2389 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002390
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002391 /* Enable SCU IF AGC loop */
2392 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2393
2394 /* Polarity */
2395 if (state->m_IfAgcPol)
2396 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2397 else
2398 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2399 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2400 if (status < 0)
2401 goto error;
2402
2403 /* Set speed (using complementary reduction value) */
2404 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2405 if (status < 0)
2406 goto error;
2407 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2408 data |= (~(pAgcCfg->speed <<
2409 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2410 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2411
2412 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2413 if (status < 0)
2414 goto error;
2415
2416 if (IsQAM(state))
2417 pRfAgcSettings = &state->m_qamRfAgcCfg;
2418 else
2419 pRfAgcSettings = &state->m_atvRfAgcCfg;
2420 if (pRfAgcSettings == NULL)
2421 return -1;
2422 /* Restore TOP */
2423 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2424 if (status < 0)
2425 goto error;
2426 break;
2427
2428 case DRXK_AGC_CTRL_USER:
2429
2430 /* Enable IF AGC DAC */
2431 status = read16(state, IQM_AF_STDBY__A, &data);
2432 if (status < 0)
2433 goto error;
2434 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2435 status = write16(state, IQM_AF_STDBY__A, data);
2436 if (status < 0)
2437 goto error;
2438
2439 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2440 if (status < 0)
2441 goto error;
2442
2443 /* Disable SCU IF AGC loop */
2444 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2445
2446 /* Polarity */
2447 if (state->m_IfAgcPol)
2448 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2449 else
2450 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2451 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2452 if (status < 0)
2453 goto error;
2454
2455 /* Write value to output pin */
2456 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2457 if (status < 0)
2458 goto error;
2459 break;
2460
2461 case DRXK_AGC_CTRL_OFF:
2462
2463 /* Disable If AGC DAC */
2464 status = read16(state, IQM_AF_STDBY__A, &data);
2465 if (status < 0)
2466 goto error;
2467 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2468 status = write16(state, IQM_AF_STDBY__A, data);
2469 if (status < 0)
2470 goto error;
2471
2472 /* Disable SCU IF AGC loop */
2473 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2474 if (status < 0)
2475 goto error;
2476 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2477 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2478 if (status < 0)
2479 goto error;
2480 break;
2481 } /* switch (agcSettingsIf->ctrlMode) */
2482
2483 /* always set the top to support
2484 configurations without if-loop */
2485 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2486error:
2487 if (status < 0)
2488 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002489 return status;
2490}
2491
Oliver Endrissebc7de22011-07-03 13:49:44 -03002492static int GetQAMSignalToNoise(struct drxk_state *state,
2493 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002494{
2495 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002496 u16 qamSlErrPower = 0; /* accum. error between
2497 raw and sliced symbols */
2498 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002499 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002500 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002501
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002502 dprintk(1, "\n");
2503
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002504 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002505
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002506 /* get the register value needed for MER */
2507 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2508 if (status < 0) {
2509 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2510 return -EINVAL;
2511 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002512
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002513 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002514 case QAM_16:
2515 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2516 break;
2517 case QAM_32:
2518 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2519 break;
2520 case QAM_64:
2521 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2522 break;
2523 case QAM_128:
2524 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2525 break;
2526 default:
2527 case QAM_256:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2529 break;
2530 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002531
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002532 if (qamSlErrPower > 0) {
2533 qamSlMer = Log10Times100(qamSlSigPower) -
2534 Log10Times100((u32) qamSlErrPower);
2535 }
2536 *pSignalToNoise = qamSlMer;
2537
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002538 return status;
2539}
2540
Oliver Endrissebc7de22011-07-03 13:49:44 -03002541static int GetDVBTSignalToNoise(struct drxk_state *state,
2542 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002544 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002545 u16 regData = 0;
2546 u32 EqRegTdSqrErrI = 0;
2547 u32 EqRegTdSqrErrQ = 0;
2548 u16 EqRegTdSqrErrExp = 0;
2549 u16 EqRegTdTpsPwrOfs = 0;
2550 u16 EqRegTdReqSmbCnt = 0;
2551 u32 tpsCnt = 0;
2552 u32 SqrErrIQ = 0;
2553 u32 a = 0;
2554 u32 b = 0;
2555 u32 c = 0;
2556 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002557 u16 transmissionParams = 0;
2558
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002559 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002560
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002561 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2562 if (status < 0)
2563 goto error;
2564 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2565 if (status < 0)
2566 goto error;
2567 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2568 if (status < 0)
2569 goto error;
2570 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2571 if (status < 0)
2572 goto error;
2573 /* Extend SQR_ERR_I operational range */
2574 EqRegTdSqrErrI = (u32) regData;
2575 if ((EqRegTdSqrErrExp > 11) &&
2576 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2577 EqRegTdSqrErrI += 0x00010000UL;
2578 }
2579 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2580 if (status < 0)
2581 goto error;
2582 /* Extend SQR_ERR_Q operational range */
2583 EqRegTdSqrErrQ = (u32) regData;
2584 if ((EqRegTdSqrErrExp > 11) &&
2585 (EqRegTdSqrErrQ < 0x00000FFFUL))
2586 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002587
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002588 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2589 if (status < 0)
2590 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002591
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002592 /* Check input data for MER */
2593
2594 /* MER calculation (in 0.1 dB) without math.h */
2595 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2596 iMER = 0;
2597 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2598 /* No error at all, this must be the HW reset value
2599 * Apparently no first measurement yet
2600 * Set MER to 0.0 */
2601 iMER = 0;
2602 } else {
2603 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2604 EqRegTdSqrErrExp;
2605 if ((transmissionParams &
2606 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2607 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2608 tpsCnt = 17;
2609 else
2610 tpsCnt = 68;
2611
2612 /* IMER = 100 * log10 (x)
2613 where x = (EqRegTdTpsPwrOfs^2 *
2614 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2615
2616 => IMER = a + b -c
2617 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2618 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2619 c = 100 * log10 (SqrErrIQ)
2620 */
2621
2622 /* log(x) x = 9bits * 9bits->18 bits */
2623 a = Log10Times100(EqRegTdTpsPwrOfs *
2624 EqRegTdTpsPwrOfs);
2625 /* log(x) x = 16bits * 7bits->23 bits */
2626 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2627 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2628 c = Log10Times100(SqrErrIQ);
2629
Mauro Carvalho Chehab48f72a12013-03-22 06:37:32 -03002630 iMER = a + b - c;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002631 }
2632 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002633
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002634error:
2635 if (status < 0)
2636 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002637 return status;
2638}
2639
2640static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2641{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002642 dprintk(1, "\n");
2643
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002644 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002645 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646 case OM_DVBT:
2647 return GetDVBTSignalToNoise(state, pSignalToNoise);
2648 case OM_QAM_ITU_A:
2649 case OM_QAM_ITU_C:
2650 return GetQAMSignalToNoise(state, pSignalToNoise);
2651 default:
2652 break;
2653 }
2654 return 0;
2655}
2656
2657#if 0
2658static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2659{
2660 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2661 int status = 0;
2662
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002663 dprintk(1, "\n");
2664
Oliver Endrissebc7de22011-07-03 13:49:44 -03002665 static s32 QE_SN[] = {
2666 51, /* QPSK 1/2 */
2667 69, /* QPSK 2/3 */
2668 79, /* QPSK 3/4 */
2669 89, /* QPSK 5/6 */
2670 97, /* QPSK 7/8 */
2671 108, /* 16-QAM 1/2 */
2672 131, /* 16-QAM 2/3 */
2673 146, /* 16-QAM 3/4 */
2674 156, /* 16-QAM 5/6 */
2675 160, /* 16-QAM 7/8 */
2676 165, /* 64-QAM 1/2 */
2677 187, /* 64-QAM 2/3 */
2678 202, /* 64-QAM 3/4 */
2679 216, /* 64-QAM 5/6 */
2680 225, /* 64-QAM 7/8 */
2681 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002682
2683 *pQuality = 0;
2684
2685 do {
2686 s32 SignalToNoise = 0;
2687 u16 Constellation = 0;
2688 u16 CodeRate = 0;
2689 u32 SignalToNoiseRel;
2690 u32 BERQuality;
2691
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002692 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2693 if (status < 0)
2694 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002695 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002696 if (status < 0)
2697 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002698 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2699
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002700 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002701 if (status < 0)
2702 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002703 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2704
2705 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2706 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2707 break;
2708 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002709 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002710 BERQuality = 100;
2711
Oliver Endrissebc7de22011-07-03 13:49:44 -03002712 if (SignalToNoiseRel < -70)
2713 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714 else if (SignalToNoiseRel < 30)
2715 *pQuality = ((SignalToNoiseRel + 70) *
2716 BERQuality) / 100;
2717 else
2718 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002719 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720 return 0;
2721};
2722
Oliver Endrissebc7de22011-07-03 13:49:44 -03002723static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002724{
2725 int status = 0;
2726 *pQuality = 0;
2727
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002728 dprintk(1, "\n");
2729
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 do {
2731 u32 SignalToNoise = 0;
2732 u32 BERQuality = 100;
2733 u32 SignalToNoiseRel = 0;
2734
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002735 status = GetQAMSignalToNoise(state, &SignalToNoise);
2736 if (status < 0)
2737 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002738
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002739 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002740 case QAM_16:
2741 SignalToNoiseRel = SignalToNoise - 200;
2742 break;
2743 case QAM_32:
2744 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002745 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746 case QAM_64:
2747 SignalToNoiseRel = SignalToNoise - 260;
2748 break;
2749 case QAM_128:
2750 SignalToNoiseRel = SignalToNoise - 290;
2751 break;
2752 default:
2753 case QAM_256:
2754 SignalToNoiseRel = SignalToNoise - 320;
2755 break;
2756 }
2757
2758 if (SignalToNoiseRel < -70)
2759 *pQuality = 0;
2760 else if (SignalToNoiseRel < 30)
2761 *pQuality = ((SignalToNoiseRel + 70) *
2762 BERQuality) / 100;
2763 else
2764 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002765 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002766
2767 return status;
2768}
2769
2770static int GetQuality(struct drxk_state *state, s32 *pQuality)
2771{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002772 dprintk(1, "\n");
2773
Oliver Endrissebc7de22011-07-03 13:49:44 -03002774 switch (state->m_OperationMode) {
2775 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002777 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002778 return GetDVBCQuality(state, pQuality);
2779 default:
2780 break;
2781 }
2782
2783 return 0;
2784}
2785#endif
2786
2787/* Free data ram in SIO HI */
2788#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2789#define SIO_HI_RA_RAM_USR_END__A 0x420060
2790
2791#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2792#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2793#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2794#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2795
2796#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2797#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2798#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2799
2800static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2801{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002802 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002803
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002804 dprintk(1, "\n");
2805
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002806 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002807 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002808 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002809 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002810
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002811 if (state->no_i2c_bridge)
2812 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002814 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2815 if (status < 0)
2816 goto error;
2817 if (bEnableBridge) {
2818 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 -03002819 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002820 goto error;
2821 } else {
2822 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2823 if (status < 0)
2824 goto error;
2825 }
2826
2827 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2828
2829error:
2830 if (status < 0)
2831 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002832 return status;
2833}
2834
Oliver Endrissebc7de22011-07-03 13:49:44 -03002835static int SetPreSaw(struct drxk_state *state,
2836 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002837{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002838 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002839
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002840 dprintk(1, "\n");
2841
Oliver Endrissebc7de22011-07-03 13:49:44 -03002842 if ((pPreSawCfg == NULL)
2843 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002844 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002846 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002847error:
2848 if (status < 0)
2849 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002850 return status;
2851}
2852
2853static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002854 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002856 u16 blStatus = 0;
2857 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2858 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2859 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860 unsigned long end;
2861
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002862 dprintk(1, "\n");
2863
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002865 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2866 if (status < 0)
2867 goto error;
2868 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2869 if (status < 0)
2870 goto error;
2871 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2872 if (status < 0)
2873 goto error;
2874 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2875 if (status < 0)
2876 goto error;
2877 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2878 if (status < 0)
2879 goto error;
2880 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2881 if (status < 0)
2882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002883
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002884 end = jiffies + msecs_to_jiffies(timeOut);
2885 do {
2886 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2887 if (status < 0)
2888 goto error;
2889 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2890 if (blStatus == 0x1) {
2891 printk(KERN_ERR "drxk: SIO not ready\n");
2892 status = -EINVAL;
2893 goto error2;
2894 }
2895error:
2896 if (status < 0)
2897 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2898error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002899 mutex_unlock(&state->mutex);
2900 return status;
2901
2902}
2903
Oliver Endrissebc7de22011-07-03 13:49:44 -03002904static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002905{
2906 u16 data = 0;
2907 int status;
2908
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002909 dprintk(1, "\n");
2910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002911 /* Start measurement */
2912 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2913 if (status < 0)
2914 goto error;
2915 status = write16(state, IQM_AF_START_LOCK__A, 1);
2916 if (status < 0)
2917 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002919 *count = 0;
2920 status = read16(state, IQM_AF_PHASE0__A, &data);
2921 if (status < 0)
2922 goto error;
2923 if (data == 127)
2924 *count = *count + 1;
2925 status = read16(state, IQM_AF_PHASE1__A, &data);
2926 if (status < 0)
2927 goto error;
2928 if (data == 127)
2929 *count = *count + 1;
2930 status = read16(state, IQM_AF_PHASE2__A, &data);
2931 if (status < 0)
2932 goto error;
2933 if (data == 127)
2934 *count = *count + 1;
2935
2936error:
2937 if (status < 0)
2938 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002939 return status;
2940}
2941
2942static int ADCSynchronization(struct drxk_state *state)
2943{
2944 u16 count = 0;
2945 int status;
2946
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002947 dprintk(1, "\n");
2948
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002949 status = ADCSyncMeasurement(state, &count);
2950 if (status < 0)
2951 goto error;
2952
2953 if (count == 1) {
2954 /* Try sampling on a diffrent edge */
2955 u16 clkNeg = 0;
2956
2957 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2958 if (status < 0)
2959 goto error;
Dan Carpenter22a09b42012-06-26 04:40:38 -03002960 if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002961 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2962 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2963 clkNeg |=
2964 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2965 } else {
2966 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2967 clkNeg |=
2968 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2969 }
2970 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2971 if (status < 0)
2972 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002973 status = ADCSyncMeasurement(state, &count);
2974 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002975 goto error;
2976 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002977
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002978 if (count < 2)
2979 status = -EINVAL;
2980error:
2981 if (status < 0)
2982 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002983 return status;
2984}
2985
2986static int SetFrequencyShifter(struct drxk_state *state,
2987 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002988 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989{
2990 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002991 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002992 u32 fmFrequencyShift = 0;
2993 bool tunerMirror = !state->m_bMirrorFreqSpect;
2994 u32 adcFreq;
2995 bool adcFlip;
2996 int status;
2997 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002998 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999 u32 frequencyShift;
3000 bool imageToSelect;
3001
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003002 dprintk(1, "\n");
3003
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003005 Program frequency shifter
3006 No need to account for mirroring on RF
3007 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003008 if (isDTV) {
3009 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3010 (state->m_OperationMode == OM_QAM_ITU_C) ||
3011 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003012 selectPosImage = true;
3013 else
3014 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 }
3016 if (tunerMirror)
3017 /* tuner doesn't mirror */
3018 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003019 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003020 else
3021 /* tuner mirrors */
3022 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003023 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 if (ifFreqActual > samplingFrequency / 2) {
3025 /* adc mirrors */
3026 adcFreq = samplingFrequency - ifFreqActual;
3027 adcFlip = true;
3028 } else {
3029 /* adc doesn't mirror */
3030 adcFreq = ifFreqActual;
3031 adcFlip = false;
3032 }
3033
3034 frequencyShift = adcFreq;
3035 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003036 adcFlip ^ selectPosImage;
3037 state->m_IqmFsRateOfs =
3038 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003039
3040 if (imageToSelect)
3041 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3042
3043 /* Program frequency shifter with tuner offset compensation */
3044 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003045 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3046 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003047 if (status < 0)
3048 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003049 return status;
3050}
3051
3052static int InitAGC(struct drxk_state *state, bool isDTV)
3053{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003054 u16 ingainTgt = 0;
3055 u16 ingainTgtMin = 0;
3056 u16 ingainTgtMax = 0;
3057 u16 clpCyclen = 0;
3058 u16 clpSumMin = 0;
3059 u16 clpDirTo = 0;
3060 u16 snsSumMin = 0;
3061 u16 snsSumMax = 0;
3062 u16 clpSumMax = 0;
3063 u16 snsDirTo = 0;
3064 u16 kiInnergainMin = 0;
3065 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066 u16 ifIaccuHiTgtMin = 0;
3067 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003068 u16 data = 0;
3069 u16 fastClpCtrlDelay = 0;
3070 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003071 int status = 0;
3072
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003073 dprintk(1, "\n");
3074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003075 /* Common settings */
3076 snsSumMax = 1023;
3077 ifIaccuHiTgtMin = 2047;
3078 clpCyclen = 500;
3079 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003080
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003081 /* AGCInit() not available for DVBT; init done in microcode */
3082 if (!IsQAM(state)) {
3083 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3084 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003085 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003086
3087 /* FIXME: Analog TV AGC require different settings */
3088
3089 /* Standard specific settings */
3090 clpSumMin = 8;
3091 clpDirTo = (u16) -9;
3092 clpCtrlMode = 0;
3093 snsSumMin = 8;
3094 snsDirTo = (u16) -9;
3095 kiInnergainMin = (u16) -1030;
3096 ifIaccuHiTgtMax = 0x2380;
3097 ifIaccuHiTgt = 0x2380;
3098 ingainTgtMin = 0x0511;
3099 ingainTgt = 0x0511;
3100 ingainTgtMax = 5119;
3101 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003103 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3104 if (status < 0)
3105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003107 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3108 if (status < 0)
3109 goto error;
3110 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3111 if (status < 0)
3112 goto error;
3113 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3114 if (status < 0)
3115 goto error;
3116 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3117 if (status < 0)
3118 goto error;
3119 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3141 if (status < 0)
3142 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003143
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003144 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3145 if (status < 0)
3146 goto error;
3147 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3148 if (status < 0)
3149 goto error;
3150 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3151 if (status < 0)
3152 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003154 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
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_MAXMINGAIN_TH__A, 20);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3168 if (status < 0)
3169 goto error;
3170 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3171 if (status < 0)
3172 goto error;
3173 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3174 if (status < 0)
3175 goto error;
3176 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3219 if (status < 0)
3220 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003222 /* Initialize inner-loop KI gain factors */
3223 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3224 if (status < 0)
3225 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003226
3227 data = 0x0657;
3228 data &= ~SCU_RAM_AGC_KI_RF__M;
3229 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3230 data &= ~SCU_RAM_AGC_KI_IF__M;
3231 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3232
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003233 status = write16(state, SCU_RAM_AGC_KI__A, data);
3234error:
3235 if (status < 0)
3236 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237 return status;
3238}
3239
Oliver Endrissebc7de22011-07-03 13:49:44 -03003240static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241{
3242 int status;
3243
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003244 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003245 if (packetErr == NULL)
3246 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3247 else
3248 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3249 if (status < 0)
3250 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 return status;
3252}
3253
3254static int DVBTScCommand(struct drxk_state *state,
3255 u16 cmd, u16 subcmd,
3256 u16 param0, u16 param1, u16 param2,
3257 u16 param3, u16 param4)
3258{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003259 u16 curCmd = 0;
3260 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003261 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003262 u16 scExec = 0;
3263 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003264
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003265 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003266 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 if (scExec != 1) {
3268 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003269 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003270 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003271 if (status < 0)
3272 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273
3274 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003275 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003276 do {
3277 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003278 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 retryCnt++;
3280 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003281 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3282 goto error;
3283
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 /* Write sub-command */
3285 switch (cmd) {
3286 /* All commands using sub-cmd */
3287 case OFDM_SC_RA_RAM_CMD_PROC_START:
3288 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3289 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003290 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3291 if (status < 0)
3292 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 break;
3294 default:
3295 /* Do nothing */
3296 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003297 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003298
3299 /* Write needed parameters and the command */
3300 switch (cmd) {
3301 /* All commands using 5 parameters */
3302 /* All commands using 4 parameters */
3303 /* All commands using 3 parameters */
3304 /* All commands using 2 parameters */
3305 case OFDM_SC_RA_RAM_CMD_PROC_START:
3306 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3307 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003308 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003309 /* All commands using 1 parameters */
3310 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3311 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003312 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003313 /* All commands using 0 parameters */
3314 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3315 case OFDM_SC_RA_RAM_CMD_NULL:
3316 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003317 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003318 break;
3319 default:
3320 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003321 status = -EINVAL;
3322 }
3323 if (status < 0)
3324 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325
3326 /* Wait until sc is ready processing command */
3327 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003328 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003329 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003330 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003332 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003333 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3334 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335
3336 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003337 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003338 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003340 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003342 if (status < 0)
3343 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344
3345 /* Retreive results parameters from SC */
3346 switch (cmd) {
3347 /* All commands yielding 5 results */
3348 /* All commands yielding 4 results */
3349 /* All commands yielding 3 results */
3350 /* All commands yielding 2 results */
3351 /* All commands yielding 1 result */
3352 case OFDM_SC_RA_RAM_CMD_USER_IO:
3353 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003354 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003355 /* All commands yielding 0 results */
3356 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3357 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3358 case OFDM_SC_RA_RAM_CMD_PROC_START:
3359 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3360 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3361 case OFDM_SC_RA_RAM_CMD_NULL:
3362 break;
3363 default:
3364 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003365 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003367 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003368error:
3369 if (status < 0)
3370 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371 return status;
3372}
3373
Oliver Endrissebc7de22011-07-03 13:49:44 -03003374static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003375{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003376 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003377 int status;
3378
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003379 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380 status = CtrlPowerMode(state, &powerMode);
3381 if (status < 0)
3382 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 return status;
3384}
3385
Oliver Endrissebc7de22011-07-03 13:49:44 -03003386static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003390 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003391 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003392 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003393 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003394 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003395 if (status < 0)
3396 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003397 return status;
3398}
3399
3400#define DEFAULT_FR_THRES_8K 4000
3401static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3402{
3403
3404 int status;
3405
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003406 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 if (*enabled == true) {
3408 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003409 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003410 DEFAULT_FR_THRES_8K);
3411 } else {
3412 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003413 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 }
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
3418 return status;
3419}
3420
3421static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3422 struct DRXKCfgDvbtEchoThres_t *echoThres)
3423{
3424 u16 data = 0;
3425 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003426
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003427 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003428 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3429 if (status < 0)
3430 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003431
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003432 switch (echoThres->fftMode) {
3433 case DRX_FFTMODE_2K:
3434 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3435 data |= ((echoThres->threshold <<
3436 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3437 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003438 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003439 case DRX_FFTMODE_8K:
3440 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3441 data |= ((echoThres->threshold <<
3442 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3443 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003444 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003445 default:
3446 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003447 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003449 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3450error:
3451 if (status < 0)
3452 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003453 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003454}
3455
3456static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003457 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003458{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003460
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003461 dprintk(1, "\n");
3462
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003463 switch (*speed) {
3464 case DRXK_DVBT_SQI_SPEED_FAST:
3465 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3466 case DRXK_DVBT_SQI_SPEED_SLOW:
3467 break;
3468 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003469 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003470 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003471 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003472 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003473error:
3474 if (status < 0)
3475 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476 return status;
3477}
3478
3479/*============================================================================*/
3480
3481/**
3482* \brief Activate DVBT specific presets
3483* \param demod instance of demodulator.
3484* \return DRXStatus_t.
3485*
3486* Called in DVBTSetStandard
3487*
3488*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003491 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003492 bool setincenable = false;
3493 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494
Oliver Endrissebc7de22011-07-03 13:49:44 -03003495 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3496 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003497
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003498 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003499 status = DVBTCtrlSetIncEnable(state, &setincenable);
3500 if (status < 0)
3501 goto error;
3502 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3503 if (status < 0)
3504 goto error;
3505 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3506 if (status < 0)
3507 goto error;
3508 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3509 if (status < 0)
3510 goto error;
3511 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3512error:
3513 if (status < 0)
3514 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003515 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003516}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003517
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003518/*============================================================================*/
3519
3520/**
3521* \brief Initialize channelswitch-independent settings for DVBT.
3522* \param demod instance of demodulator.
3523* \return DRXStatus_t.
3524*
3525* For ROM code channel filter taps are loaded from the bootloader. For microcode
3526* the DVB-T taps from the drxk_filters.h are used.
3527*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003528static int SetDVBTStandard(struct drxk_state *state,
3529 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003530{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003531 u16 cmdResult = 0;
3532 u16 data = 0;
3533 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003535 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003536
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003537 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003538 /* added antenna switch */
3539 SwitchAntennaToDVBT(state);
3540 /* send OFDM reset command */
3541 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 -03003542 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003543 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003544
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003545 /* send OFDM setenv command */
3546 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3547 if (status < 0)
3548 goto error;
3549
3550 /* reset datapath for OFDM, processors first */
3551 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3552 if (status < 0)
3553 goto error;
3554 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3555 if (status < 0)
3556 goto error;
3557 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3558 if (status < 0)
3559 goto error;
3560
3561 /* IQM setup */
3562 /* synchronize on ofdstate->m_festart */
3563 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3564 if (status < 0)
3565 goto error;
3566 /* window size for clipping ADC detection */
3567 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3568 if (status < 0)
3569 goto error;
3570 /* window size for for sense pre-SAW detection */
3571 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3572 if (status < 0)
3573 goto error;
3574 /* sense threshold for sense pre-SAW detection */
3575 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3576 if (status < 0)
3577 goto error;
3578 status = SetIqmAf(state, true);
3579 if (status < 0)
3580 goto error;
3581
3582 status = write16(state, IQM_AF_AGC_RF__A, 0);
3583 if (status < 0)
3584 goto error;
3585
3586 /* Impulse noise cruncher setup */
3587 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3588 if (status < 0)
3589 goto error;
3590 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3591 if (status < 0)
3592 goto error;
3593 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3594 if (status < 0)
3595 goto error;
3596
3597 status = write16(state, IQM_RC_STRETCH__A, 16);
3598 if (status < 0)
3599 goto error;
3600 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3601 if (status < 0)
3602 goto error;
3603 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3604 if (status < 0)
3605 goto error;
3606 status = write16(state, IQM_CF_SCALE__A, 1600);
3607 if (status < 0)
3608 goto error;
3609 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3610 if (status < 0)
3611 goto error;
3612
3613 /* virtual clipping threshold for clipping ADC detection */
3614 status = write16(state, IQM_AF_CLP_TH__A, 448);
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3618 if (status < 0)
3619 goto error;
3620
3621 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3622 if (status < 0)
3623 goto error;
3624
3625 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3626 if (status < 0)
3627 goto error;
3628 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3629 if (status < 0)
3630 goto error;
3631 /* enable power measurement interrupt */
3632 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3636 if (status < 0)
3637 goto error;
3638
3639 /* IQM will not be reset from here, sync ADC and update/init AGC */
3640 status = ADCSynchronization(state);
3641 if (status < 0)
3642 goto error;
3643 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3644 if (status < 0)
3645 goto error;
3646
3647 /* Halt SCU to enable safe non-atomic accesses */
3648 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3649 if (status < 0)
3650 goto error;
3651
3652 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3653 if (status < 0)
3654 goto error;
3655 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3656 if (status < 0)
3657 goto error;
3658
3659 /* Set Noise Estimation notch width and enable DC fix */
3660 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3661 if (status < 0)
3662 goto error;
3663 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3664 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3665 if (status < 0)
3666 goto error;
3667
3668 /* Activate SCU to enable SCU commands */
3669 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3670 if (status < 0)
3671 goto error;
3672
3673 if (!state->m_DRXK_A3_ROM_CODE) {
3674 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3675 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3676 if (status < 0)
3677 goto error;
3678 }
3679
3680 /* OFDM_SC setup */
3681#ifdef COMPILE_FOR_NONRT
3682 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3683 if (status < 0)
3684 goto error;
3685 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3686 if (status < 0)
3687 goto error;
3688#endif
3689
3690 /* FEC setup */
3691 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3692 if (status < 0)
3693 goto error;
3694
3695
3696#ifdef COMPILE_FOR_NONRT
3697 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3698 if (status < 0)
3699 goto error;
3700#else
3701 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3702 if (status < 0)
3703 goto error;
3704#endif
3705 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3706 if (status < 0)
3707 goto error;
3708
3709 /* Setup MPEG bus */
3710 status = MPEGTSDtoSetup(state, OM_DVBT);
3711 if (status < 0)
3712 goto error;
3713 /* Set DVBT Presets */
3714 status = DVBTActivatePresets(state);
3715 if (status < 0)
3716 goto error;
3717
3718error:
3719 if (status < 0)
3720 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003721 return status;
3722}
3723
3724/*============================================================================*/
3725/**
3726* \brief Start dvbt demodulating for channel.
3727* \param demod instance of demodulator.
3728* \return DRXStatus_t.
3729*/
3730static int DVBTStart(struct drxk_state *state)
3731{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003732 u16 param1;
3733 int status;
3734 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003735
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003736 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003737 /* Start correct processes to get in lock */
3738 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003739 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3740 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3741 if (status < 0)
3742 goto error;
3743 /* Start FEC OC */
3744 status = MPEGTSStart(state);
3745 if (status < 0)
3746 goto error;
3747 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3748 if (status < 0)
3749 goto error;
3750error:
3751 if (status < 0)
3752 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003753 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003754}
3755
3756
3757/*============================================================================*/
3758
3759/**
3760* \brief Set up dvbt demodulator for channel.
3761* \param demod instance of demodulator.
3762* \return DRXStatus_t.
3763* // original DVBTSetChannel()
3764*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003765static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3766 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003767{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003768 u16 cmdResult = 0;
3769 u16 transmissionParams = 0;
3770 u16 operationMode = 0;
3771 u32 iqmRcRateOfs = 0;
3772 u32 bandwidth = 0;
3773 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003774 int status;
3775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003776 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003778 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3779 if (status < 0)
3780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003782 /* Halt SCU to enable safe non-atomic accesses */
3783 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3784 if (status < 0)
3785 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003787 /* Stop processors */
3788 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3789 if (status < 0)
3790 goto error;
3791 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3792 if (status < 0)
3793 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003795 /* Mandatory fix, always stop CP, required to set spl offset back to
3796 hardware default (is set to 0 by ucode during pilot detection */
3797 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3798 if (status < 0)
3799 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003800
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003801 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003803 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003804 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003805 case TRANSMISSION_MODE_AUTO:
3806 default:
3807 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3808 /* fall through , try first guess DRX_FFTMODE_8K */
3809 case TRANSMISSION_MODE_8K:
3810 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003811 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003812 case TRANSMISSION_MODE_2K:
3813 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003814 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003816
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003817 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003818 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 default:
3820 case GUARD_INTERVAL_AUTO:
3821 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3822 /* fall through , try first guess DRX_GUARD_1DIV4 */
3823 case GUARD_INTERVAL_1_4:
3824 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003825 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003826 case GUARD_INTERVAL_1_32:
3827 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003828 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 case GUARD_INTERVAL_1_16:
3830 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003831 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 case GUARD_INTERVAL_1_8:
3833 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003834 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 }
3836
3837 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003838 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003839 case HIERARCHY_AUTO:
3840 case HIERARCHY_NONE:
3841 default:
3842 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3843 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3844 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3845 /* break; */
3846 case HIERARCHY_1:
3847 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3848 break;
3849 case HIERARCHY_2:
3850 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3851 break;
3852 case HIERARCHY_4:
3853 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3854 break;
3855 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003856
3857
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003858 /* modulation */
3859 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003860 case QAM_AUTO:
3861 default:
3862 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3863 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3864 case QAM_64:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3866 break;
3867 case QPSK:
3868 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3869 break;
3870 case QAM_16:
3871 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3872 break;
3873 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003874#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003875 /* No hierachical channels support in BDA */
3876 /* Priority (only for hierarchical channels) */
3877 switch (channel->priority) {
3878 case DRX_PRIORITY_LOW:
3879 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3880 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3881 OFDM_EC_SB_PRIOR_LO);
3882 break;
3883 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003884 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003885 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3886 OFDM_EC_SB_PRIOR_HI));
3887 break;
3888 case DRX_PRIORITY_UNKNOWN: /* fall through */
3889 default:
3890 status = -EINVAL;
3891 goto error;
3892 }
3893#else
3894 /* Set Priorty high */
3895 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3896 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3897 if (status < 0)
3898 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003899#endif
3900
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003901 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003902 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003903 case FEC_AUTO:
3904 default:
3905 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3906 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3907 case FEC_2_3:
3908 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3909 break;
3910 case FEC_1_2:
3911 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3912 break;
3913 case FEC_3_4:
3914 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3915 break;
3916 case FEC_5_6:
3917 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3918 break;
3919 case FEC_7_8:
3920 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3921 break;
3922 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003923
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003924 /* SAW filter selection: normaly not necesarry, but if wanted
3925 the application can select a SAW filter via the driver by using UIOs */
3926 /* First determine real bandwidth (Hz) */
3927 /* Also set delay for impulse noise cruncher */
3928 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3929 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3930 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003931 switch (state->props.bandwidth_hz) {
3932 case 0:
3933 state->props.bandwidth_hz = 8000000;
3934 /* fall though */
3935 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003936 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3937 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003938 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003939 goto error;
3940 /* cochannel protection for PAL 8 MHz */
3941 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3942 if (status < 0)
3943 goto error;
3944 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3945 if (status < 0)
3946 goto error;
3947 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3948 if (status < 0)
3949 goto error;
3950 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3951 if (status < 0)
3952 goto error;
3953 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003954 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003955 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3956 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3957 if (status < 0)
3958 goto error;
3959 /* cochannel protection for PAL 7 MHz */
3960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3961 if (status < 0)
3962 goto error;
3963 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3964 if (status < 0)
3965 goto error;
3966 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3967 if (status < 0)
3968 goto error;
3969 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3970 if (status < 0)
3971 goto error;
3972 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003973 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003974 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3975 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3976 if (status < 0)
3977 goto error;
3978 /* cochannel protection for NTSC 6 MHz */
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3980 if (status < 0)
3981 goto error;
3982 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3983 if (status < 0)
3984 goto error;
3985 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3986 if (status < 0)
3987 goto error;
3988 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3989 if (status < 0)
3990 goto error;
3991 break;
3992 default:
3993 status = -EINVAL;
3994 goto error;
3995 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003996
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003997 if (iqmRcRateOfs == 0) {
3998 /* Now compute IQM_RC_RATE_OFS
3999 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4000 =>
4001 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4002 */
4003 /* (SysFreq / BandWidth) * (2^28) */
4004 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4005 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4006 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4007 iqmRcRateOfs = Frac28a((u32)
4008 ((state->m_sysClockFreq *
4009 1000) / 3), bandwidth);
4010 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4011 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4012 iqmRcRateOfs += 0x80L;
4013 iqmRcRateOfs = iqmRcRateOfs >> 7;
4014 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4015 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4016 }
4017
4018 iqmRcRateOfs &=
4019 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4020 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4021 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4022 if (status < 0)
4023 goto error;
4024
4025 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004026
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004027#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004028 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4029 if (status < 0)
4030 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004031#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004032 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4033 if (status < 0)
4034 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004035
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004036 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004038 /* Activate SCU to enable SCU commands */
4039 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4040 if (status < 0)
4041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004043 /* Enable SC after setting all other parameters */
4044 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4045 if (status < 0)
4046 goto error;
4047 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4048 if (status < 0)
4049 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050
4051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004052 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4053 if (status < 0)
4054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004056 /* Write SC parameter registers, set all AUTO flags in operation mode */
4057 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4058 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4059 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4060 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4061 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4062 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4063 0, transmissionParams, param1, 0, 0, 0);
4064 if (status < 0)
4065 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004067 if (!state->m_DRXK_A3_ROM_CODE)
4068 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4069error:
4070 if (status < 0)
4071 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004072
4073 return status;
4074}
4075
4076
4077/*============================================================================*/
4078
4079/**
4080* \brief Retreive lock status .
4081* \param demod Pointer to demodulator instance.
4082* \param lockStat Pointer to lock status structure.
4083* \return DRXStatus_t.
4084*
4085*/
4086static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4087{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004088 int status;
4089 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4090 OFDM_SC_RA_RAM_LOCK_FEC__M);
4091 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4092 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004093
Oliver Endrissebc7de22011-07-03 13:49:44 -03004094 u16 ScRaRamLock = 0;
4095 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004096
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004097 dprintk(1, "\n");
4098
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004099 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004100 /* driver 0.9.0 */
4101 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004102 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004103 if (status < 0)
4104 goto end;
4105 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4106 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004107
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004108 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004109 if (status < 0)
4110 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Oliver Endrissebc7de22011-07-03 13:49:44 -03004112 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4113 *pLockStatus = MPEG_LOCK;
4114 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4115 *pLockStatus = FEC_LOCK;
4116 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4117 *pLockStatus = DEMOD_LOCK;
4118 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4119 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004120end:
4121 if (status < 0)
4122 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Oliver Endrissebc7de22011-07-03 13:49:44 -03004124 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125}
4126
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004129 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004130 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004131
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004132 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004133 status = CtrlPowerMode(state, &powerMode);
4134 if (status < 0)
4135 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004136
Oliver Endrissebc7de22011-07-03 13:49:44 -03004137 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138}
4139
4140
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142static int PowerDownQAM(struct drxk_state *state)
4143{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144 u16 data = 0;
4145 u16 cmdResult;
4146 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004147
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004148 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004149 status = read16(state, SCU_COMM_EXEC__A, &data);
4150 if (status < 0)
4151 goto error;
4152 if (data == SCU_COMM_EXEC_ACTIVE) {
4153 /*
4154 STOP demodulator
4155 QAM and HW blocks
4156 */
4157 /* stop all comstate->m_exec */
4158 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004159 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004160 goto error;
4161 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 -03004162 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004163 goto error;
4164 }
4165 /* powerdown AFE */
4166 status = SetIqmAf(state, false);
4167
4168error:
4169 if (status < 0)
4170 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004171
Oliver Endrissebc7de22011-07-03 13:49:44 -03004172 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004173}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004174
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004175/*============================================================================*/
4176
4177/**
4178* \brief Setup of the QAM Measurement intervals for signal quality
4179* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004180* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004181* \return DRXStatus_t.
4182*
4183* NOTE:
4184* Take into account that for certain settings the errorcounters can overflow.
4185* The implementation does not check this.
4186*
4187*/
4188static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004189 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004190 u32 symbolRate)
4191{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004192 u32 fecBitsDesired = 0; /* BER accounting period */
4193 u32 fecRsPeriodTotal = 0; /* Total period */
4194 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4195 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004196 int status = 0;
4197
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004198 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004199
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004200 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004201 /* fecBitsDesired = symbolRate [kHz] *
4202 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004203 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004204 SyncLoss (== 1) *
4205 ViterbiLoss (==1)
4206 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004207 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004208 case DRX_CONSTELLATION_QAM16:
4209 fecBitsDesired = 4 * symbolRate;
4210 break;
4211 case DRX_CONSTELLATION_QAM32:
4212 fecBitsDesired = 5 * symbolRate;
4213 break;
4214 case DRX_CONSTELLATION_QAM64:
4215 fecBitsDesired = 6 * symbolRate;
4216 break;
4217 case DRX_CONSTELLATION_QAM128:
4218 fecBitsDesired = 7 * symbolRate;
4219 break;
4220 case DRX_CONSTELLATION_QAM256:
4221 fecBitsDesired = 8 * symbolRate;
4222 break;
4223 default:
4224 status = -EINVAL;
4225 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004226 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004227 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004229 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4230 fecBitsDesired *= 500; /* meas. period [ms] */
4231
4232 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4233 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4234 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4235
4236 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4237 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4238 if (fecRsPrescale == 0) {
4239 /* Divide by zero (though impossible) */
4240 status = -EINVAL;
4241 if (status < 0)
4242 goto error;
4243 }
4244 fecRsPeriod =
4245 ((u16) fecRsPeriodTotal +
4246 (fecRsPrescale >> 1)) / fecRsPrescale;
4247
4248 /* write corresponding registers */
4249 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4250 if (status < 0)
4251 goto error;
4252 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4253 if (status < 0)
4254 goto error;
4255 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4256error:
4257 if (status < 0)
4258 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004259 return status;
4260}
4261
Oliver Endrissebc7de22011-07-03 13:49:44 -03004262static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004263{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004264 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004265
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004266 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004267 /* QAM Equalizer Setup */
4268 /* Equalizer */
4269 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4270 if (status < 0)
4271 goto error;
4272 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4273 if (status < 0)
4274 goto error;
4275 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4276 if (status < 0)
4277 goto error;
4278 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4279 if (status < 0)
4280 goto error;
4281 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4285 if (status < 0)
4286 goto error;
4287 /* Decision Feedback Equalizer */
4288 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4295 if (status < 0)
4296 goto error;
4297 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4298 if (status < 0)
4299 goto error;
4300 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4301 if (status < 0)
4302 goto error;
4303 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4304 if (status < 0)
4305 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004306
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004307 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4314 if (status < 0)
4315 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004317 /* QAM Slicer Settings */
4318 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4319 if (status < 0)
4320 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004321
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004322 /* QAM Loop Controller Coeficients */
4323 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4324 if (status < 0)
4325 goto error;
4326 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4327 if (status < 0)
4328 goto error;
4329 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4330 if (status < 0)
4331 goto error;
4332 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4333 if (status < 0)
4334 goto error;
4335 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4345 if (status < 0)
4346 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004347
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004348 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4352 if (status < 0)
4353 goto error;
4354 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4355 if (status < 0)
4356 goto error;
4357 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4358 if (status < 0)
4359 goto error;
4360 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4361 if (status < 0)
4362 goto error;
4363 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4364 if (status < 0)
4365 goto error;
4366 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4367 if (status < 0)
4368 goto error;
4369 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4370 if (status < 0)
4371 goto error;
4372 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4373 if (status < 0)
4374 goto error;
4375 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4382 if (status < 0)
4383 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004384
4385
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004386 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004387
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004388 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4392 if (status < 0)
4393 goto error;
4394 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4395 if (status < 0)
4396 goto error;
4397 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4398 if (status < 0)
4399 goto error;
4400 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4401 if (status < 0)
4402 goto error;
4403 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4404 if (status < 0)
4405 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004406
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004407 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4414 if (status < 0)
4415 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004416
4417
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004418 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004419
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004420 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4424 if (status < 0)
4425 goto error;
4426 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4427 if (status < 0)
4428 goto error;
4429 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4430 if (status < 0)
4431 goto error;
4432 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4433 if (status < 0)
4434 goto error;
4435 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4436 if (status < 0)
4437 goto error;
4438 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4439 if (status < 0)
4440 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004441
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004442error:
4443 if (status < 0)
4444 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004445 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004446}
4447
4448/*============================================================================*/
4449
4450/**
4451* \brief QAM32 specific setup
4452* \param demod instance of demod.
4453* \return DRXStatus_t.
4454*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004455static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004456{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004457 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004458
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004459 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004460
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004461 /* QAM Equalizer Setup */
4462 /* Equalizer */
4463 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4464 if (status < 0)
4465 goto error;
4466 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4467 if (status < 0)
4468 goto error;
4469 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4470 if (status < 0)
4471 goto error;
4472 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4473 if (status < 0)
4474 goto error;
4475 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4476 if (status < 0)
4477 goto error;
4478 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4479 if (status < 0)
4480 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004481
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004482 /* Decision Feedback Equalizer */
4483 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4487 if (status < 0)
4488 goto error;
4489 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4490 if (status < 0)
4491 goto error;
4492 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4493 if (status < 0)
4494 goto error;
4495 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4496 if (status < 0)
4497 goto error;
4498 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4499 if (status < 0)
4500 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004501
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004502 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4509 if (status < 0)
4510 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004511
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004512 /* QAM Slicer Settings */
4513
4514 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4515 if (status < 0)
4516 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004517
4518
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004519 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004520
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004521 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4522 if (status < 0)
4523 goto error;
4524 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4525 if (status < 0)
4526 goto error;
4527 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4528 if (status < 0)
4529 goto error;
4530 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4543 if (status < 0)
4544 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004546 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4553 if (status < 0)
4554 goto error;
4555 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4556 if (status < 0)
4557 goto error;
4558 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4559 if (status < 0)
4560 goto error;
4561 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4562 if (status < 0)
4563 goto error;
4564 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4580 if (status < 0)
4581 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004582
4583
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004584 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004585
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004586 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4590 if (status < 0)
4591 goto error;
4592 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4593 if (status < 0)
4594 goto error;
4595 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4596 if (status < 0)
4597 goto error;
4598 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4602 if (status < 0)
4603 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004604
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004605 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4612 if (status < 0)
4613 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004614
4615
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004616 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004618 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4622 if (status < 0)
4623 goto error;
4624 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4625 if (status < 0)
4626 goto error;
4627 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4628 if (status < 0)
4629 goto error;
4630 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4637error:
4638 if (status < 0)
4639 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004640 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004641}
4642
4643/*============================================================================*/
4644
4645/**
4646* \brief QAM64 specific setup
4647* \param demod instance of demod.
4648* \return DRXStatus_t.
4649*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004650static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004651{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004652 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004653
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004654 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004655 /* QAM Equalizer Setup */
4656 /* Equalizer */
4657 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4658 if (status < 0)
4659 goto error;
4660 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4661 if (status < 0)
4662 goto error;
4663 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4664 if (status < 0)
4665 goto error;
4666 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4667 if (status < 0)
4668 goto error;
4669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4673 if (status < 0)
4674 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004675
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004676 /* Decision Feedback Equalizer */
4677 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4678 if (status < 0)
4679 goto error;
4680 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4681 if (status < 0)
4682 goto error;
4683 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4684 if (status < 0)
4685 goto error;
4686 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4687 if (status < 0)
4688 goto error;
4689 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4693 if (status < 0)
4694 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004695
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004696 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4700 if (status < 0)
4701 goto error;
4702 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4703 if (status < 0)
4704 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004705
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004706 /* QAM Slicer Settings */
4707 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4708 if (status < 0)
4709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004710
4711
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004712 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004713
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004714 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4715 if (status < 0)
4716 goto error;
4717 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4718 if (status < 0)
4719 goto error;
4720 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4721 if (status < 0)
4722 goto error;
4723 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4724 if (status < 0)
4725 goto error;
4726 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4736 if (status < 0)
4737 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004738
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004739 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4746 if (status < 0)
4747 goto error;
4748 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4749 if (status < 0)
4750 goto error;
4751 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4752 if (status < 0)
4753 goto error;
4754 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4755 if (status < 0)
4756 goto error;
4757 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4758 if (status < 0)
4759 goto error;
4760 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4761 if (status < 0)
4762 goto error;
4763 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4773 if (status < 0)
4774 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004775
4776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004777 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004778
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004779 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4783 if (status < 0)
4784 goto error;
4785 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4786 if (status < 0)
4787 goto error;
4788 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4789 if (status < 0)
4790 goto error;
4791 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4792 if (status < 0)
4793 goto error;
4794 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4795 if (status < 0)
4796 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004798 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4805 if (status < 0)
4806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
4808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004809 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004811 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4815 if (status < 0)
4816 goto error;
4817 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4818 if (status < 0)
4819 goto error;
4820 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4821 if (status < 0)
4822 goto error;
4823 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4824 if (status < 0)
4825 goto error;
4826 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4830error:
4831 if (status < 0)
4832 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004833
Oliver Endrissebc7de22011-07-03 13:49:44 -03004834 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004835}
4836
4837/*============================================================================*/
4838
4839/**
4840* \brief QAM128 specific setup
4841* \param demod: instance of demod.
4842* \return DRXStatus_t.
4843*/
4844static int SetQAM128(struct drxk_state *state)
4845{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004846 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004848 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004849 /* QAM Equalizer Setup */
4850 /* Equalizer */
4851 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4852 if (status < 0)
4853 goto error;
4854 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4855 if (status < 0)
4856 goto error;
4857 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4858 if (status < 0)
4859 goto error;
4860 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4861 if (status < 0)
4862 goto error;
4863 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4864 if (status < 0)
4865 goto error;
4866 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4867 if (status < 0)
4868 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004869
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004870 /* Decision Feedback Equalizer */
4871 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4881 if (status < 0)
4882 goto error;
4883 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4884 if (status < 0)
4885 goto error;
4886 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4887 if (status < 0)
4888 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004890 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4897 if (status < 0)
4898 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004899
4900
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004901 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004902
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004903 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4904 if (status < 0)
4905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004906
4907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004908 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004910 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4911 if (status < 0)
4912 goto error;
4913 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4914 if (status < 0)
4915 goto error;
4916 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4917 if (status < 0)
4918 goto error;
4919 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4920 if (status < 0)
4921 goto error;
4922 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4932 if (status < 0)
4933 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004935 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4939 if (status < 0)
4940 goto error;
4941 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4942 if (status < 0)
4943 goto error;
4944 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4945 if (status < 0)
4946 goto error;
4947 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4948 if (status < 0)
4949 goto error;
4950 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4951 if (status < 0)
4952 goto error;
4953 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4954 if (status < 0)
4955 goto error;
4956 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4957 if (status < 0)
4958 goto error;
4959 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4969 if (status < 0)
4970 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004971
4972
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004973 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004974
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004975 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4979 if (status < 0)
4980 goto error;
4981 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4982 if (status < 0)
4983 goto error;
4984 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4985 if (status < 0)
4986 goto error;
4987 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4988 if (status < 0)
4989 goto error;
4990 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4991 if (status < 0)
4992 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004993
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004994 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4998 if (status < 0)
4999 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005000
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005001 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5002 if (status < 0)
5003 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005005 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005006
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005007 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5008 if (status < 0)
5009 goto error;
5010 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5011 if (status < 0)
5012 goto error;
5013 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5014 if (status < 0)
5015 goto error;
5016 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5017 if (status < 0)
5018 goto error;
5019 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5020 if (status < 0)
5021 goto error;
5022 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5023 if (status < 0)
5024 goto error;
5025 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5026error:
5027 if (status < 0)
5028 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005029
Oliver Endrissebc7de22011-07-03 13:49:44 -03005030 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005031}
5032
5033/*============================================================================*/
5034
5035/**
5036* \brief QAM256 specific setup
5037* \param demod: instance of demod.
5038* \return DRXStatus_t.
5039*/
5040static int SetQAM256(struct drxk_state *state)
5041{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005042 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005043
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005044 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005045 /* QAM Equalizer Setup */
5046 /* Equalizer */
5047 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5048 if (status < 0)
5049 goto error;
5050 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5051 if (status < 0)
5052 goto error;
5053 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5054 if (status < 0)
5055 goto error;
5056 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5057 if (status < 0)
5058 goto error;
5059 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5060 if (status < 0)
5061 goto error;
5062 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5063 if (status < 0)
5064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005066 /* Decision Feedback Equalizer */
5067 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5074 if (status < 0)
5075 goto error;
5076 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5077 if (status < 0)
5078 goto error;
5079 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5080 if (status < 0)
5081 goto error;
5082 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5083 if (status < 0)
5084 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005085
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005086 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5093 if (status < 0)
5094 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005095
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005096 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005097
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005098 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5099 if (status < 0)
5100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005101
5102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005103 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005104
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005105 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5106 if (status < 0)
5107 goto error;
5108 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5109 if (status < 0)
5110 goto error;
5111 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5112 if (status < 0)
5113 goto error;
5114 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5115 if (status < 0)
5116 goto error;
5117 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5127 if (status < 0)
5128 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005130 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5137 if (status < 0)
5138 goto error;
5139 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5140 if (status < 0)
5141 goto error;
5142 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5143 if (status < 0)
5144 goto error;
5145 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5146 if (status < 0)
5147 goto error;
5148 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5164 if (status < 0)
5165 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005166
5167
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005168 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005169
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005170 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5174 if (status < 0)
5175 goto error;
5176 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5177 if (status < 0)
5178 goto error;
5179 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5180 if (status < 0)
5181 goto error;
5182 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5183 if (status < 0)
5184 goto error;
5185 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5186 if (status < 0)
5187 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005188
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005189 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5196 if (status < 0)
5197 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005198
5199
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005200 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005201
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005202 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5206 if (status < 0)
5207 goto error;
5208 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5209 if (status < 0)
5210 goto error;
5211 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5212 if (status < 0)
5213 goto error;
5214 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5215 if (status < 0)
5216 goto error;
5217 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5221error:
5222 if (status < 0)
5223 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005224 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005225}
5226
5227
5228/*============================================================================*/
5229/**
5230* \brief Reset QAM block.
5231* \param demod: instance of demod.
5232* \param channel: pointer to channel data.
5233* \return DRXStatus_t.
5234*/
5235static int QAMResetQAM(struct drxk_state *state)
5236{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005237 int status;
5238 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005239
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005240 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005241 /* Stop QAM comstate->m_exec */
5242 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5243 if (status < 0)
5244 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005246 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5247error:
5248 if (status < 0)
5249 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005250 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251}
5252
5253/*============================================================================*/
5254
5255/**
5256* \brief Set QAM symbolrate.
5257* \param demod: instance of demod.
5258* \param channel: pointer to channel data.
5259* \return DRXStatus_t.
5260*/
5261static int QAMSetSymbolrate(struct drxk_state *state)
5262{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005263 u32 adcFrequency = 0;
5264 u32 symbFreq = 0;
5265 u32 iqmRcRate = 0;
5266 u16 ratesel = 0;
5267 u32 lcSymbRate = 0;
5268 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005269
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005270 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005271 /* Select & calculate correct IQM rate */
5272 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5273 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005274 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5275 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005276 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005277 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005278 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005279 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005280 ratesel = 1;
5281 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5282 if (status < 0)
5283 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005284
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005285 /*
5286 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5287 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005288 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005289 if (symbFreq == 0) {
5290 /* Divide by zero */
5291 status = -EINVAL;
5292 goto error;
5293 }
5294 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5295 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5296 (1 << 23);
5297 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5298 if (status < 0)
5299 goto error;
5300 state->m_iqmRcRate = iqmRcRate;
5301 /*
5302 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5303 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005304 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005305 if (adcFrequency == 0) {
5306 /* Divide by zero */
5307 status = -EINVAL;
5308 goto error;
5309 }
5310 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5311 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5312 16);
5313 if (lcSymbRate > 511)
5314 lcSymbRate = 511;
5315 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005317error:
5318 if (status < 0)
5319 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005320 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005321}
5322
5323/*============================================================================*/
5324
5325/**
5326* \brief Get QAM lock status.
5327* \param demod: instance of demod.
5328* \param channel: pointer to channel data.
5329* \return DRXStatus_t.
5330*/
5331
5332static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5333{
5334 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005335 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005336
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005337 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005338 *pLockStatus = NOT_LOCKED;
5339 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005340 SCU_RAM_COMMAND_STANDARD_QAM |
5341 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5342 Result);
5343 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005344 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005345
5346 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005347 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005348 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005349 /* 0x4000 DEMOD LOCKED */
5350 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005351 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005352 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5353 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005355 /* 0xC000 NEVER LOCKED */
5356 /* (system will never be able to lock to the signal) */
5357 /* TODO: check this, intermediate & standard specific lock states are not
5358 taken into account here */
5359 *pLockStatus = NEVER_LOCK;
5360 }
5361 return status;
5362}
5363
5364#define QAM_MIRROR__M 0x03
5365#define QAM_MIRROR_NORMAL 0x00
5366#define QAM_MIRRORED 0x01
5367#define QAM_MIRROR_AUTO_ON 0x02
5368#define QAM_LOCKRANGE__M 0x10
5369#define QAM_LOCKRANGE_NORMAL 0x10
5370
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005371static int QAMDemodulatorCommand(struct drxk_state *state,
5372 int numberOfParameters)
5373{
5374 int status;
5375 u16 cmdResult;
5376 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5377
5378 setParamParameters[0] = state->m_Constellation; /* modulation */
5379 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5380
5381 if (numberOfParameters == 2) {
5382 u16 setEnvParameters[1] = { 0 };
5383
5384 if (state->m_OperationMode == OM_QAM_ITU_C)
5385 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5386 else
5387 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5388
5389 status = scu_command(state,
5390 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5391 1, setEnvParameters, 1, &cmdResult);
5392 if (status < 0)
5393 goto error;
5394
5395 status = scu_command(state,
5396 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5397 numberOfParameters, setParamParameters,
5398 1, &cmdResult);
5399 } else if (numberOfParameters == 4) {
5400 if (state->m_OperationMode == OM_QAM_ITU_C)
5401 setParamParameters[2] = QAM_TOP_ANNEX_C;
5402 else
5403 setParamParameters[2] = QAM_TOP_ANNEX_A;
5404
5405 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5406 /* Env parameters */
5407 /* check for LOCKRANGE Extented */
5408 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5409
5410 status = scu_command(state,
5411 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5412 numberOfParameters, setParamParameters,
5413 1, &cmdResult);
5414 } else {
5415 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5416 "count %d\n", numberOfParameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005417 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005418 }
5419
5420error:
5421 if (status < 0)
5422 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5423 status, __func__);
5424 return status;
5425}
5426
Oliver Endrissebc7de22011-07-03 13:49:44 -03005427static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5428 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005429{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005430 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005431 u16 cmdResult;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005432 int qamDemodParamCount = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005433
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005434 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005435 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005436 * STEP 1: reset demodulator
5437 * resets FEC DI and FEC RS
5438 * resets QAM block
5439 * resets SCU variables
5440 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005441 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005442 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005443 goto error;
5444 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5445 if (status < 0)
5446 goto error;
5447 status = QAMResetQAM(state);
5448 if (status < 0)
5449 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005450
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005451 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005452 * STEP 2: configure demodulator
5453 * -set params; resets IQM,QAM,FEC HW; initializes some
5454 * SCU variables
5455 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005456 status = QAMSetSymbolrate(state);
5457 if (status < 0)
5458 goto error;
5459
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005460 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005461 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005462 case QAM_256:
5463 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5464 break;
5465 case QAM_AUTO:
5466 case QAM_64:
5467 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5468 break;
5469 case QAM_16:
5470 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5471 break;
5472 case QAM_32:
5473 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5474 break;
5475 case QAM_128:
5476 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5477 break;
5478 default:
5479 status = -EINVAL;
5480 break;
5481 }
5482 if (status < 0)
5483 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005484
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005485 /* Use the 4-parameter if it's requested or we're probing for
5486 * the correct command. */
5487 if (state->qam_demod_parameter_count == 4
5488 || !state->qam_demod_parameter_count) {
5489 qamDemodParamCount = 4;
5490 status = QAMDemodulatorCommand(state, qamDemodParamCount);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005491 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005492
5493 /* Use the 2-parameter command if it was requested or if we're
5494 * probing for the correct command and the 4-parameter command
5495 * failed. */
5496 if (state->qam_demod_parameter_count == 2
5497 || (!state->qam_demod_parameter_count && status < 0)) {
5498 qamDemodParamCount = 2;
5499 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5500 }
5501
5502 if (status < 0) {
5503 dprintk(1, "Could not set demodulator parameters. Make "
5504 "sure qam_demod_parameter_count (%d) is correct for "
5505 "your firmware (%s).\n",
5506 state->qam_demod_parameter_count,
5507 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005508 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005509 } else if (!state->qam_demod_parameter_count) {
5510 dprintk(1, "Auto-probing the correct QAM demodulator command "
5511 "parameters was successful - using %d parameters.\n",
5512 qamDemodParamCount);
5513
Mauro Carvalho Chehab7eaf71882012-07-06 14:53:51 -03005514 /*
5515 * One of our commands was successful. We don't need to
5516 * auto-probe anymore, now that we got the correct command.
5517 */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005518 state->qam_demod_parameter_count = qamDemodParamCount;
5519 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005520
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005521 /*
5522 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005523 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005524 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005525#if 0
5526 status = SetFrequency(channel, tunerFreqOffset));
5527 if (status < 0)
5528 goto error;
5529#endif
5530 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5531 if (status < 0)
5532 goto error;
5533
5534 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005535 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005536 if (status < 0)
5537 goto error;
5538
5539 /* Reset default values */
5540 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5544 if (status < 0)
5545 goto error;
5546
5547 /* Reset default LC values */
5548 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5549 if (status < 0)
5550 goto error;
5551 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5552 if (status < 0)
5553 goto error;
5554 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5555 if (status < 0)
5556 goto error;
5557 status = write16(state, QAM_LC_MODE__A, 7);
5558 if (status < 0)
5559 goto error;
5560
5561 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5562 if (status < 0)
5563 goto error;
5564 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5565 if (status < 0)
5566 goto error;
5567 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5568 if (status < 0)
5569 goto error;
5570 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5571 if (status < 0)
5572 goto error;
5573 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5574 if (status < 0)
5575 goto error;
5576 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5577 if (status < 0)
5578 goto error;
5579 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5580 if (status < 0)
5581 goto error;
5582 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5583 if (status < 0)
5584 goto error;
5585 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5586 if (status < 0)
5587 goto error;
5588 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5589 if (status < 0)
5590 goto error;
5591 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5592 if (status < 0)
5593 goto error;
5594 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5595 if (status < 0)
5596 goto error;
5597 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5598 if (status < 0)
5599 goto error;
5600 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5601 if (status < 0)
5602 goto error;
5603 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5604 if (status < 0)
5605 goto error;
5606
5607 /* Mirroring, QAM-block starting point not inverted */
5608 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5609 if (status < 0)
5610 goto error;
5611
5612 /* Halt SCU to enable safe non-atomic accesses */
5613 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5614 if (status < 0)
5615 goto error;
5616
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005617 /* STEP 4: modulation specific setup */
5618 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005619 case QAM_16:
5620 status = SetQAM16(state);
5621 break;
5622 case QAM_32:
5623 status = SetQAM32(state);
5624 break;
5625 case QAM_AUTO:
5626 case QAM_64:
5627 status = SetQAM64(state);
5628 break;
5629 case QAM_128:
5630 status = SetQAM128(state);
5631 break;
5632 case QAM_256:
5633 status = SetQAM256(state);
5634 break;
5635 default:
5636 status = -EINVAL;
5637 break;
5638 }
5639 if (status < 0)
5640 goto error;
5641
5642 /* Activate SCU to enable SCU commands */
5643 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5644 if (status < 0)
5645 goto error;
5646
5647 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005648 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005649 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5650 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5651 if (status < 0)
5652 goto error;
5653
5654 /* Start processes */
5655 status = MPEGTSStart(state);
5656 if (status < 0)
5657 goto error;
5658 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5659 if (status < 0)
5660 goto error;
5661 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5662 if (status < 0)
5663 goto error;
5664 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5665 if (status < 0)
5666 goto error;
5667
5668 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5669 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5670 if (status < 0)
5671 goto error;
5672
5673 /* update global DRXK data container */
5674/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5675
5676error:
5677 if (status < 0)
5678 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005679 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005680}
5681
Oliver Endrissebc7de22011-07-03 13:49:44 -03005682static int SetQAMStandard(struct drxk_state *state,
5683 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005684{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005685 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005686#ifdef DRXK_QAM_TAPS
5687#define DRXK_QAMA_TAPS_SELECT
5688#include "drxk_filters.h"
5689#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005690#endif
5691
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005692 dprintk(1, "\n");
5693
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005694 /* added antenna switch */
5695 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005696
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005697 /* Ensure correct power-up mode */
5698 status = PowerUpQAM(state);
5699 if (status < 0)
5700 goto error;
5701 /* Reset QAM block */
5702 status = QAMResetQAM(state);
5703 if (status < 0)
5704 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005705
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005706 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005708 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 /* Upload IQM Channel Filter settings by
5716 boot loader from ROM table */
5717 switch (oMode) {
5718 case OM_QAM_ITU_A:
5719 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5720 break;
5721 case OM_QAM_ITU_C:
5722 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 -03005723 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005724 goto error;
5725 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5726 break;
5727 default:
5728 status = -EINVAL;
5729 }
5730 if (status < 0)
5731 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005732
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005733 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5734 if (status < 0)
5735 goto error;
5736 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5737 if (status < 0)
5738 goto error;
5739 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5740 if (status < 0)
5741 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005742
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005743 status = write16(state, IQM_RC_STRETCH__A, 21);
5744 if (status < 0)
5745 goto error;
5746 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5747 if (status < 0)
5748 goto error;
5749 status = write16(state, IQM_AF_CLP_TH__A, 448);
5750 if (status < 0)
5751 goto error;
5752 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5753 if (status < 0)
5754 goto error;
5755 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5756 if (status < 0)
5757 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005759 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5760 if (status < 0)
5761 goto error;
5762 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5763 if (status < 0)
5764 goto error;
5765 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5766 if (status < 0)
5767 goto error;
5768 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5769 if (status < 0)
5770 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005771
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005772 /* IQM Impulse Noise Processing Unit */
5773 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5774 if (status < 0)
5775 goto error;
5776 status = write16(state, IQM_CF_DATATH__A, 1000);
5777 if (status < 0)
5778 goto error;
5779 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5780 if (status < 0)
5781 goto error;
5782 status = write16(state, IQM_CF_DET_LCT__A, 0);
5783 if (status < 0)
5784 goto error;
5785 status = write16(state, IQM_CF_WND_LEN__A, 1);
5786 if (status < 0)
5787 goto error;
5788 status = write16(state, IQM_CF_PKDTH__A, 1);
5789 if (status < 0)
5790 goto error;
5791 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5792 if (status < 0)
5793 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005795 /* turn on IQMAF. Must be done before setAgc**() */
5796 status = SetIqmAf(state, true);
5797 if (status < 0)
5798 goto error;
5799 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5800 if (status < 0)
5801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005803 /* IQM will not be reset from here, sync ADC and update/init AGC */
5804 status = ADCSynchronization(state);
5805 if (status < 0)
5806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005808 /* Set the FSM step period */
5809 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5810 if (status < 0)
5811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005813 /* Halt SCU to enable safe non-atomic accesses */
5814 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5815 if (status < 0)
5816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005818 /* No more resets of the IQM, current standard correctly set =>
5819 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005821 status = InitAGC(state, true);
5822 if (status < 0)
5823 goto error;
5824 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5825 if (status < 0)
5826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005828 /* Configure AGC's */
5829 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5830 if (status < 0)
5831 goto error;
5832 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5833 if (status < 0)
5834 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005835
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005836 /* Activate SCU to enable SCU commands */
5837 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5838error:
5839 if (status < 0)
5840 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005841 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005842}
5843
5844static int WriteGPIO(struct drxk_state *state)
5845{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005846 int status;
5847 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005848
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005849 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005850 /* stop lock indicator process */
5851 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5852 if (status < 0)
5853 goto error;
5854
5855 /* Write magic word to enable pdr reg write */
5856 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5857 if (status < 0)
5858 goto error;
5859
5860 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005861 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5862 /* write to io pad configuration register - output mode */
5863 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5864 if (status < 0)
5865 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005866
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005867 /* use corresponding bit in io data output registar */
5868 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5869 if (status < 0)
5870 goto error;
5871 if ((state->m_GPIO & 0x0001) == 0)
5872 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5873 else
5874 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5875 /* write back to io data output register */
5876 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5877 if (status < 0)
5878 goto error;
5879 }
5880 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5881 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005882 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005883 if (status < 0)
5884 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005885
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005886 /* use corresponding bit in io data output registar */
5887 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5888 if (status < 0)
5889 goto error;
5890 if ((state->m_GPIO & 0x0002) == 0)
5891 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5892 else
5893 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5894 /* write back to io data output register */
5895 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5896 if (status < 0)
5897 goto error;
5898 }
5899 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5900 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005901 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005902 if (status < 0)
5903 goto error;
5904
5905 /* use corresponding bit in io data output registar */
5906 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5907 if (status < 0)
5908 goto error;
5909 if ((state->m_GPIO & 0x0004) == 0)
5910 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5911 else
5912 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5913 /* write back to io data output register */
5914 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5915 if (status < 0)
5916 goto error;
5917 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005918 }
5919 /* Write magic word to disable pdr reg write */
5920 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5921error:
5922 if (status < 0)
5923 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005924 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005925}
5926
5927static int SwitchAntennaToQAM(struct drxk_state *state)
5928{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005929 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005930 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005931
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005932 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005933
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005934 if (!state->antenna_gpio)
5935 return 0;
5936
5937 gpio_state = state->m_GPIO & state->antenna_gpio;
5938
5939 if (state->antenna_dvbt ^ gpio_state) {
5940 /* Antenna is on DVB-T mode. Switch */
5941 if (state->antenna_dvbt)
5942 state->m_GPIO &= ~state->antenna_gpio;
5943 else
5944 state->m_GPIO |= state->antenna_gpio;
5945 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005946 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005947 if (status < 0)
5948 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005949 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005950}
5951
5952static int SwitchAntennaToDVBT(struct drxk_state *state)
5953{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005954 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005955 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005956
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005957 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005958
5959 if (!state->antenna_gpio)
5960 return 0;
5961
5962 gpio_state = state->m_GPIO & state->antenna_gpio;
5963
5964 if (!(state->antenna_dvbt ^ gpio_state)) {
5965 /* Antenna is on DVB-C mode. Switch */
5966 if (state->antenna_dvbt)
5967 state->m_GPIO |= state->antenna_gpio;
5968 else
5969 state->m_GPIO &= ~state->antenna_gpio;
5970 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005971 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005972 if (status < 0)
5973 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005974 return status;
5975}
5976
5977
5978static int PowerDownDevice(struct drxk_state *state)
5979{
5980 /* Power down to requested mode */
5981 /* Backup some register settings */
5982 /* Set pins with possible pull-ups connected to them in input mode */
5983 /* Analog power down */
5984 /* ADC power down */
5985 /* Power down device */
5986 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005987
5988 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005989 if (state->m_bPDownOpenBridge) {
5990 /* Open I2C bridge before power down of DRXK */
5991 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005992 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005993 goto error;
5994 }
5995 /* driver 0.9.0 */
5996 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005997 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005998 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006000 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
6001 if (status < 0)
6002 goto error;
6003 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6004 if (status < 0)
6005 goto error;
6006 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6007 status = HI_CfgCommand(state);
6008error:
6009 if (status < 0)
6010 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6011
6012 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006013}
6014
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006015static int init_drxk(struct drxk_state *state)
6016{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006017 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006018 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006019 u16 driverVersion;
6020
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006021 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006022 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006023 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006024 status = PowerUpDevice(state);
6025 if (status < 0)
6026 goto error;
6027 status = DRXX_Open(state);
6028 if (status < 0)
6029 goto error;
6030 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6031 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);
6032 if (status < 0)
6033 goto error;
6034 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6035 if (status < 0)
6036 goto error;
6037 /* TODO is this needed, if yes how much delay in worst case scenario */
6038 msleep(1);
6039 state->m_DRXK_A3_PATCH_CODE = true;
6040 status = GetDeviceCapabilities(state);
6041 if (status < 0)
6042 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006044 /* Bridge delay, uses oscilator clock */
6045 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6046 /* SDA brdige delay */
6047 state->m_HICfgBridgeDelay =
6048 (u16) ((state->m_oscClockFreq / 1000) *
6049 HI_I2C_BRIDGE_DELAY) / 1000;
6050 /* Clipping */
6051 if (state->m_HICfgBridgeDelay >
6052 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006053 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006054 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6055 }
6056 /* SCL bridge delay, same as SDA for now */
6057 state->m_HICfgBridgeDelay +=
6058 state->m_HICfgBridgeDelay <<
6059 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006061 status = InitHI(state);
6062 if (status < 0)
6063 goto error;
6064 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006065#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006066 if (!(state->m_DRXK_A1_ROM_CODE)
6067 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006068#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006069 {
6070 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6071 if (status < 0)
6072 goto error;
6073 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006075 /* disable MPEG port */
6076 status = MPEGTSDisable(state);
6077 if (status < 0)
6078 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006080 /* Stop AUD and SCU */
6081 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6082 if (status < 0)
6083 goto error;
6084 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6085 if (status < 0)
6086 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006088 /* enable token-ring bus through OFDM block for possible ucode upload */
6089 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6090 if (status < 0)
6091 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 /* include boot loader section */
6094 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6095 if (status < 0)
6096 goto error;
6097 status = BLChainCmd(state, 0, 6, 100);
6098 if (status < 0)
6099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006101 if (state->fw) {
6102 status = DownloadMicrocode(state, state->fw->data,
6103 state->fw->size);
6104 if (status < 0)
6105 goto error;
6106 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006108 /* disable token-ring bus through OFDM block for possible ucode upload */
6109 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6110 if (status < 0)
6111 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006113 /* Run SCU for a little while to initialize microcode version numbers */
6114 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6115 if (status < 0)
6116 goto error;
6117 status = DRXX_Open(state);
6118 if (status < 0)
6119 goto error;
6120 /* added for test */
6121 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006123 powerMode = DRXK_POWER_DOWN_OFDM;
6124 status = CtrlPowerMode(state, &powerMode);
6125 if (status < 0)
6126 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006128 /* Stamp driver version number in SCU data RAM in BCD code
6129 Done to enable field application engineers to retreive drxdriver version
6130 via I2C from SCU RAM.
6131 Not using SCU command interface for SCU register access since no
6132 microcode may be present.
6133 */
6134 driverVersion =
6135 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6136 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6137 ((DRXK_VERSION_MAJOR % 10) << 4) +
6138 (DRXK_VERSION_MINOR % 10);
6139 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6140 if (status < 0)
6141 goto error;
6142 driverVersion =
6143 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6144 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6145 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6146 (DRXK_VERSION_PATCH % 10);
6147 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6148 if (status < 0)
6149 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006150
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006151 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6152 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6153 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006155 /* Dirty fix of default values for ROM/PATCH microcode
6156 Dirty because this fix makes it impossible to setup suitable values
6157 before calling DRX_Open. This solution requires changes to RF AGC speed
6158 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006160 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006161
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006162 /* Reset driver debug flags to 0 */
6163 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6164 if (status < 0)
6165 goto error;
6166 /* driver 0.9.0 */
6167 /* Setup FEC OC:
6168 NOTE: No more full FEC resets allowed afterwards!! */
6169 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6170 if (status < 0)
6171 goto error;
6172 /* MPEGTS functions are still the same */
6173 status = MPEGTSDtoInit(state);
6174 if (status < 0)
6175 goto error;
6176 status = MPEGTSStop(state);
6177 if (status < 0)
6178 goto error;
6179 status = MPEGTSConfigurePolarity(state);
6180 if (status < 0)
6181 goto error;
6182 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6183 if (status < 0)
6184 goto error;
6185 /* added: configure GPIO */
6186 status = WriteGPIO(state);
6187 if (status < 0)
6188 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006190 state->m_DrxkState = DRXK_STOPPED;
6191
6192 if (state->m_bPowerDown) {
6193 status = PowerDownDevice(state);
6194 if (status < 0)
6195 goto error;
6196 state->m_DrxkState = DRXK_POWERED_DOWN;
6197 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006198 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006199
6200 /* Initialize the supported delivery systems */
6201 n = 0;
6202 if (state->m_hasDVBC) {
6203 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6204 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6205 strlcat(state->frontend.ops.info.name, " DVB-C",
6206 sizeof(state->frontend.ops.info.name));
6207 }
6208 if (state->m_hasDVBT) {
6209 state->frontend.ops.delsys[n++] = SYS_DVBT;
6210 strlcat(state->frontend.ops.info.name, " DVB-T",
6211 sizeof(state->frontend.ops.info.name));
6212 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006213 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006215error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006216 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006217 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006218 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006219 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006220 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006221
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006222 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006223}
6224
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006225static void load_firmware_cb(const struct firmware *fw,
6226 void *context)
6227{
6228 struct drxk_state *state = context;
6229
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006230 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006231 if (!fw) {
6232 printk(KERN_ERR
6233 "drxk: Could not load firmware file %s.\n",
6234 state->microcode_name);
6235 printk(KERN_INFO
6236 "drxk: Copy %s to your hotplug directory!\n",
6237 state->microcode_name);
6238 state->microcode_name = NULL;
6239
6240 /*
6241 * As firmware is now load asynchronous, it is not possible
6242 * anymore to fail at frontend attach. We might silently
6243 * return here, and hope that the driver won't crash.
6244 * We might also change all DVB callbacks to return -ENODEV
6245 * if the device is not initialized.
6246 * As the DRX-K devices have their own internal firmware,
6247 * let's just hope that it will match a firmware revision
6248 * compatible with this driver and proceed.
6249 */
6250 }
6251 state->fw = fw;
6252
6253 init_drxk(state);
6254}
6255
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006256static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006257{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006258 struct drxk_state *state = fe->demodulator_priv;
6259
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006260 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006261 if (state->fw)
6262 release_firmware(state->fw);
6263
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006264 kfree(state);
6265}
6266
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006267static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006269 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006271 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006272
6273 if (state->m_DrxkState == DRXK_NO_DEV)
6274 return -ENODEV;
6275 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6276 return 0;
6277
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 return 0;
6280}
6281
Oliver Endrissebc7de22011-07-03 13:49:44 -03006282static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006283{
6284 struct drxk_state *state = fe->demodulator_priv;
6285
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006286 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006287
6288 if (state->m_DrxkState == DRXK_NO_DEV)
6289 return -ENODEV;
6290
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 return ConfigureI2CBridge(state, enable ? true : false);
6292}
6293
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006294static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006295{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006296 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006297 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006298 struct drxk_state *state = fe->demodulator_priv;
6299 u32 IF;
6300
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006301 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006302
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006303 if (state->m_DrxkState == DRXK_NO_DEV)
6304 return -ENODEV;
6305
6306 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6307 return -EAGAIN;
6308
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006309 if (!fe->ops.tuner_ops.get_if_frequency) {
6310 printk(KERN_ERR
6311 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6312 return -EINVAL;
6313 }
6314
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315 if (fe->ops.i2c_gate_ctrl)
6316 fe->ops.i2c_gate_ctrl(fe, 1);
6317 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006318 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006319 if (fe->ops.i2c_gate_ctrl)
6320 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006321
6322 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006323 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006324
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006325 if (old_delsys != delsys) {
6326 ShutDown(state);
6327 switch (delsys) {
6328 case SYS_DVBC_ANNEX_A:
6329 case SYS_DVBC_ANNEX_C:
6330 if (!state->m_hasDVBC)
6331 return -EINVAL;
6332 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6333 if (state->m_itut_annex_c)
6334 SetOperationMode(state, OM_QAM_ITU_C);
6335 else
6336 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006337 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006338 case SYS_DVBT:
6339 if (!state->m_hasDVBT)
6340 return -EINVAL;
6341 SetOperationMode(state, OM_DVBT);
6342 break;
6343 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006344 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006345 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006346 }
6347
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006348 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006349 Start(state, 0, IF);
6350
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006351 /* After set_frontend, stats aren't avaliable */
6352 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6353 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6354 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6355 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6356 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6357 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6358 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6359 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6360
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006361 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006362
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006363 return 0;
6364}
6365
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006366static int get_strength(struct drxk_state *state, u64 *strength)
6367{
6368 int status;
6369 struct SCfgAgc rfAgc, ifAgc;
6370 u32 totalGain = 0;
6371 u32 atten = 0;
6372 u32 agcRange = 0;
6373 u16 scu_lvl = 0;
6374 u16 scu_coc = 0;
6375 /* FIXME: those are part of the tuner presets */
6376 u16 tunerRfGain = 50; /* Default value on az6007 driver */
6377 u16 tunerIfGain = 40; /* Default value on az6007 driver */
6378
6379 *strength = 0;
6380
6381 if (IsDVBT(state)) {
6382 rfAgc = state->m_dvbtRfAgcCfg;
6383 ifAgc = state->m_dvbtIfAgcCfg;
6384 } else if (IsQAM(state)) {
6385 rfAgc = state->m_qamRfAgcCfg;
6386 ifAgc = state->m_qamIfAgcCfg;
6387 } else {
6388 rfAgc = state->m_atvRfAgcCfg;
6389 ifAgc = state->m_atvIfAgcCfg;
6390 }
6391
6392 if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6393 /* SCU outputLevel */
6394 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6395 if (status < 0)
6396 return status;
6397
6398 /* SCU c.o.c. */
6399 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6400 if (status < 0)
6401 return status;
6402
6403 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6404 rfAgc.outputLevel = scu_lvl + scu_coc;
6405 else
6406 rfAgc.outputLevel = 0xffff;
6407
6408 /* Take RF gain into account */
6409 totalGain += tunerRfGain;
6410
6411 /* clip output value */
6412 if (rfAgc.outputLevel < rfAgc.minOutputLevel)
6413 rfAgc.outputLevel = rfAgc.minOutputLevel;
6414 if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
6415 rfAgc.outputLevel = rfAgc.maxOutputLevel;
6416
6417 agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
6418 if (agcRange > 0) {
6419 atten += 100UL *
6420 ((u32)(tunerRfGain)) *
6421 ((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
6422 / agcRange;
6423 }
6424 }
6425
6426 if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6427 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6428 &ifAgc.outputLevel);
6429 if (status < 0)
6430 return status;
6431
6432 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6433 &ifAgc.top);
6434 if (status < 0)
6435 return status;
6436
6437 /* Take IF gain into account */
6438 totalGain += (u32) tunerIfGain;
6439
6440 /* clip output value */
6441 if (ifAgc.outputLevel < ifAgc.minOutputLevel)
6442 ifAgc.outputLevel = ifAgc.minOutputLevel;
6443 if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
6444 ifAgc.outputLevel = ifAgc.maxOutputLevel;
6445
6446 agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
6447 if (agcRange > 0) {
6448 atten += 100UL *
6449 ((u32)(tunerIfGain)) *
6450 ((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
6451 / agcRange;
6452 }
6453 }
6454
6455 /*
6456 * Convert to 0..65535 scale.
6457 * If it can't be measured (AGC is disabled), just show 100%.
6458 */
6459 if (totalGain > 0)
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006460 *strength = (65535UL * atten / totalGain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006461 else
6462 *strength = 65535;
6463
6464 return 0;
6465}
6466
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006467static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006468{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006469 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006470 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006471 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006472 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006473 u16 reg16;
6474 u32 post_bit_count;
6475 u32 post_bit_err_count;
6476 u32 post_bit_error_scale;
6477 u32 pre_bit_err_count;
6478 u32 pre_bit_count;
6479 u32 pkt_count;
6480 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006481 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006482
6483 if (state->m_DrxkState == DRXK_NO_DEV)
6484 return -ENODEV;
6485 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6486 return -EAGAIN;
6487
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006488 /* get status */
6489 state->fe_status = 0;
Jean Delvarea3ad56d2013-03-20 12:43:21 +00006490 GetLockStatus(state, &stat);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006491 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006492 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006493 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006494 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006495 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006496 state->fe_status |= 0x07;
6497
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006498 /*
6499 * Estimate signal strength from AGC
6500 */
6501 get_strength(state, &c->strength.stat[0].uvalue);
6502 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6503
6504
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006505 if (stat >= DEMOD_LOCK) {
6506 GetSignalToNoise(state, &cnr);
6507 c->cnr.stat[0].svalue = cnr * 100;
6508 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6509 } else {
6510 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6511 }
6512
6513 if (stat < FEC_LOCK) {
6514 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6515 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6516 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6517 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6518 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6519 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6520 return 0;
6521 }
6522
6523 /* Get post BER */
6524
6525 /* BER measurement is valid if at least FEC lock is achieved */
6526
6527 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6528 to set nr of symbols or bits over which
6529 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6530
6531 /* Read registers for post/preViterbi BER calculation */
6532 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6533 if (status < 0)
6534 goto error;
6535 pre_bit_err_count = reg16;
6536
6537 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6538 if (status < 0)
6539 goto error;
6540 pre_bit_count = reg16;
6541
6542 /* Number of bit-errors */
6543 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6544 if (status < 0)
6545 goto error;
6546 post_bit_err_count = reg16;
6547
6548 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6549 if (status < 0)
6550 goto error;
6551 post_bit_error_scale = reg16;
6552
6553 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6554 if (status < 0)
6555 goto error;
6556 pkt_count = reg16;
6557
6558 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6559 if (status < 0)
6560 goto error;
6561 pkt_error_count = reg16;
6562 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6563
6564 post_bit_err_count *= post_bit_error_scale;
6565
6566 post_bit_count = pkt_count * 204 * 8;
6567
6568 /* Store the results */
6569 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6570 c->block_error.stat[0].uvalue += pkt_error_count;
6571 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6572 c->block_count.stat[0].uvalue += pkt_count;
6573
6574 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6575 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6576 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6577 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6578
6579 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6580 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6581 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6582 c->post_bit_count.stat[0].uvalue += post_bit_count;
6583
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006584error:
6585 return status;
6586}
6587
6588
6589static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6590{
6591 struct drxk_state *state = fe->demodulator_priv;
6592 int rc;
6593
6594 dprintk(1, "\n");
6595
6596 rc = drxk_get_stats(fe);
6597 if (rc < 0)
6598 return rc;
6599
6600 *status = state->fe_status;
6601
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006602 return 0;
6603}
6604
Oliver Endrissebc7de22011-07-03 13:49:44 -03006605static int drxk_read_signal_strength(struct dvb_frontend *fe,
6606 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006607{
6608 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006609 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006610
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006611 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006612
6613 if (state->m_DrxkState == DRXK_NO_DEV)
6614 return -ENODEV;
6615 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6616 return -EAGAIN;
6617
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006618 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006619 return 0;
6620}
6621
6622static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6623{
6624 struct drxk_state *state = fe->demodulator_priv;
6625 s32 snr2;
6626
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006627 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006628
6629 if (state->m_DrxkState == DRXK_NO_DEV)
6630 return -ENODEV;
6631 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6632 return -EAGAIN;
6633
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006634 GetSignalToNoise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006635
6636 /* No negative SNR, clip to zero */
6637 if (snr2 < 0)
6638 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006639 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006640 return 0;
6641}
6642
6643static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6644{
6645 struct drxk_state *state = fe->demodulator_priv;
6646 u16 err;
6647
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006648 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006649
6650 if (state->m_DrxkState == DRXK_NO_DEV)
6651 return -ENODEV;
6652 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6653 return -EAGAIN;
6654
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006655 DVBTQAMGetAccPktErr(state, &err);
6656 *ucblocks = (u32) err;
6657 return 0;
6658}
6659
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006660static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006661 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006662{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006663 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006664 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006665
6666 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006667
6668 if (state->m_DrxkState == DRXK_NO_DEV)
6669 return -ENODEV;
6670 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6671 return -EAGAIN;
6672
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006673 switch (p->delivery_system) {
6674 case SYS_DVBC_ANNEX_A:
6675 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006676 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006677 sets->min_delay_ms = 3000;
6678 sets->max_drift = 0;
6679 sets->step_size = 0;
6680 return 0;
6681 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006682 return -EINVAL;
6683 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006684}
6685
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006686static struct dvb_frontend_ops drxk_ops = {
6687 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006688 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006689 .name = "DRXK",
6690 .frequency_min = 47000000,
6691 .frequency_max = 865000000,
6692 /* For DVB-C */
6693 .symbol_rate_min = 870000,
6694 .symbol_rate_max = 11700000,
6695 /* For DVB-T */
6696 .frequency_stepsize = 166667,
6697
6698 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6699 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6700 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6701 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6702 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6703 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6704 },
6705
6706 .release = drxk_release,
6707 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006708 .i2c_gate_ctrl = drxk_gate_ctrl,
6709
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006710 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006711 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006712
6713 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006714 .read_signal_strength = drxk_read_signal_strength,
6715 .read_snr = drxk_read_snr,
6716 .read_ucblocks = drxk_read_ucblocks,
6717};
6718
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006719struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006720 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006721{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006722 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006723 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006724 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006725 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006726
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006727 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006728 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006729 if (!state)
6730 return NULL;
6731
Oliver Endrissebc7de22011-07-03 13:49:44 -03006732 state->i2c = i2c;
6733 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006734 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006735 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006736 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006737 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006738 state->antenna_gpio = config->antenna_gpio;
6739 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006740 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006741 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006742
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006743 if (config->dynamic_clk) {
6744 state->m_DVBTStaticCLK = 0;
6745 state->m_DVBCStaticCLK = 0;
6746 } else {
6747 state->m_DVBTStaticCLK = 1;
6748 state->m_DVBCStaticCLK = 1;
6749 }
6750
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006751
6752 if (config->mpeg_out_clk_strength)
6753 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6754 else
6755 state->m_TSClockkStrength = 0x06;
6756
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006757 if (config->parallel_ts)
6758 state->m_enableParallel = true;
6759 else
6760 state->m_enableParallel = false;
6761
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006762 /* NOTE: as more UIO bits will be used, add them to the mask */
6763 state->UIO_mask = config->antenna_gpio;
6764
6765 /* Default gpio to DVB-C */
6766 if (!state->antenna_dvbt && state->antenna_gpio)
6767 state->m_GPIO |= state->antenna_gpio;
6768 else
6769 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006770
6771 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006772
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006773 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6774 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006775
6776 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006777
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006778 /* Load firmware and initialize DRX-K */
6779 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006780 if (config->load_firmware_sync) {
6781 const struct firmware *fw = NULL;
6782
6783 status = request_firmware(&fw, state->microcode_name,
6784 state->i2c->dev.parent);
6785 if (status < 0)
6786 fw = NULL;
6787 load_firmware_cb(fw, state);
6788 } else {
6789 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006790 state->microcode_name,
6791 state->i2c->dev.parent,
6792 GFP_KERNEL,
6793 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006794 if (status < 0) {
6795 printk(KERN_ERR
6796 "drxk: failed to request a firmware\n");
6797 return NULL;
6798 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006799 }
6800 } else if (init_drxk(state) < 0)
6801 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006802
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006803
6804 /* Initialize stats */
6805 p = &state->frontend.dtv_property_cache;
6806 p->strength.len = 1;
6807 p->cnr.len = 1;
6808 p->block_error.len = 1;
6809 p->block_count.len = 1;
6810 p->pre_bit_error.len = 1;
6811 p->pre_bit_count.len = 1;
6812 p->post_bit_error.len = 1;
6813 p->post_bit_count.len = 1;
6814
6815 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6816 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6817 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6818 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6819 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6820 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6821 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6822 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6823
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006824 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006825 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006826
6827error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006828 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006829 kfree(state);
6830 return NULL;
6831}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006832EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006833
6834MODULE_DESCRIPTION("DRX-K driver");
6835MODULE_AUTHOR("Ralph Metzler");
6836MODULE_LICENSE("GPL");