blob: 55a4c22ac2d4323491681d3c6d709a37f741a299 [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
Oliver Endrissebc7de22011-07-03 13:49:44 -03001950static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1951 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001952{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001953 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001954
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001955 dprintk(1, "\n");
1956
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001957 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001958 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001959
1960 *pLockStatus = NOT_LOCKED;
1961
1962 /* define the SCU command code */
1963 switch (state->m_OperationMode) {
1964 case OM_QAM_ITU_A:
1965 case OM_QAM_ITU_B:
1966 case OM_QAM_ITU_C:
1967 status = GetQAMLockStatus(state, pLockStatus);
1968 break;
1969 case OM_DVBT:
1970 status = GetDVBTLockStatus(state, pLockStatus);
1971 break;
1972 default:
1973 break;
1974 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001975error:
1976 if (status < 0)
1977 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001978 return status;
1979}
1980
1981static int MPEGTSStart(struct drxk_state *state)
1982{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001983 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001984
1985 u16 fecOcSncMode = 0;
1986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001987 /* Allow OC to sync again */
1988 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1989 if (status < 0)
1990 goto error;
1991 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1992 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1993 if (status < 0)
1994 goto error;
1995 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1996error:
1997 if (status < 0)
1998 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001999 return status;
2000}
2001
2002static int MPEGTSDtoInit(struct drxk_state *state)
2003{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002004 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002005
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002006 dprintk(1, "\n");
2007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002008 /* Rate integration settings */
2009 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
2010 if (status < 0)
2011 goto error;
2012 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
2013 if (status < 0)
2014 goto error;
2015 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2016 if (status < 0)
2017 goto error;
2018 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2019 if (status < 0)
2020 goto error;
2021 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2022 if (status < 0)
2023 goto error;
2024 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2025 if (status < 0)
2026 goto error;
2027 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2028 if (status < 0)
2029 goto error;
2030 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2031 if (status < 0)
2032 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002033
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002034 /* Additional configuration */
2035 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2036 if (status < 0)
2037 goto error;
2038 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2039 if (status < 0)
2040 goto error;
2041 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2042error:
2043 if (status < 0)
2044 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2045
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002046 return status;
2047}
2048
Oliver Endrissebc7de22011-07-03 13:49:44 -03002049static int MPEGTSDtoSetup(struct drxk_state *state,
2050 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002051{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002052 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002053
Oliver Endrissebc7de22011-07-03 13:49:44 -03002054 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2055 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2056 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2057 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2058 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2059 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2060 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061 u16 fecOcTmdMode = 0;
2062 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002063 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002064 bool staticCLK = false;
2065
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002066 dprintk(1, "\n");
2067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002068 /* Check insertion of the Reed-Solomon parity bytes */
2069 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2070 if (status < 0)
2071 goto error;
2072 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2073 if (status < 0)
2074 goto error;
2075 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2076 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2077 if (state->m_insertRSByte == true) {
2078 /* enable parity symbol forward */
2079 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2080 /* MVAL disable during parity bytes */
2081 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2082 /* TS burst length to 204 */
2083 fecOcDtoBurstLen = 204;
2084 }
2085
2086 /* Check serial or parrallel output */
2087 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2088 if (state->m_enableParallel == false) {
2089 /* MPEG data output is serial -> set ipr_mode[0] */
2090 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2091 }
2092
2093 switch (oMode) {
2094 case OM_DVBT:
2095 maxBitRate = state->m_DVBTBitrate;
2096 fecOcTmdMode = 3;
2097 fecOcRcnCtlRate = 0xC00000;
2098 staticCLK = state->m_DVBTStaticCLK;
2099 break;
2100 case OM_QAM_ITU_A: /* fallthrough */
2101 case OM_QAM_ITU_C:
2102 fecOcTmdMode = 0x0004;
2103 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2104 maxBitRate = state->m_DVBCBitrate;
2105 staticCLK = state->m_DVBCStaticCLK;
2106 break;
2107 default:
2108 status = -EINVAL;
2109 } /* switch (standard) */
2110 if (status < 0)
2111 goto error;
2112
2113 /* Configure DTO's */
2114 if (staticCLK) {
2115 u32 bitRate = 0;
2116
2117 /* Rational DTO for MCLK source (static MCLK rate),
2118 Dynamic DTO for optimal grouping
2119 (avoid intra-packet gaps),
2120 DTO offset enable to sync TS burst with MSTRT */
2121 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2122 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2123 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2124 FEC_OC_FCT_MODE_VIRT_ENA__M);
2125
2126 /* Check user defined bitrate */
2127 bitRate = maxBitRate;
2128 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2129 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002130 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002131 /* Rational DTO period:
2132 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002134 Result should be floored,
2135 to make sure >= requested bitrate
2136 */
2137 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2138 * 1000) / bitRate);
2139 if (fecOcDtoPeriod <= 2)
2140 fecOcDtoPeriod = 0;
2141 else
2142 fecOcDtoPeriod -= 2;
2143 fecOcTmdIntUpdRate = 8;
2144 } else {
2145 /* (commonAttr->staticCLK == false) => dynamic mode */
2146 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2147 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2148 fecOcTmdIntUpdRate = 5;
2149 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002150
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002151 /* Write appropriate registers with requested configuration */
2152 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2153 if (status < 0)
2154 goto error;
2155 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2156 if (status < 0)
2157 goto error;
2158 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2159 if (status < 0)
2160 goto error;
2161 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2162 if (status < 0)
2163 goto error;
2164 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2165 if (status < 0)
2166 goto error;
2167 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2168 if (status < 0)
2169 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002171 /* Rate integration settings */
2172 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2173 if (status < 0)
2174 goto error;
2175 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2176 if (status < 0)
2177 goto error;
2178 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2179error:
2180 if (status < 0)
2181 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002182 return status;
2183}
2184
2185static int MPEGTSConfigurePolarity(struct drxk_state *state)
2186{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002187 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002188
2189 /* Data mask for the output data byte */
2190 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002191 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2192 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2193 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2194 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002195
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002196 dprintk(1, "\n");
2197
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002198 /* Control selective inversion of output bits */
2199 fecOcRegIprInvert &= (~(InvertDataMask));
2200 if (state->m_invertDATA == true)
2201 fecOcRegIprInvert |= InvertDataMask;
2202 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2203 if (state->m_invertERR == true)
2204 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2205 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2206 if (state->m_invertSTR == true)
2207 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2208 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2209 if (state->m_invertVAL == true)
2210 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2211 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2212 if (state->m_invertCLK == true)
2213 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002214
2215 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002216}
2217
2218#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2219
2220static int SetAgcRf(struct drxk_state *state,
2221 struct SCfgAgc *pAgcCfg, bool isDTV)
2222{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002223 int status = -EINVAL;
2224 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002225 struct SCfgAgc *pIfAgcSettings;
2226
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002227 dprintk(1, "\n");
2228
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002230 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002231
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002232 switch (pAgcCfg->ctrlMode) {
2233 case DRXK_AGC_CTRL_AUTO:
2234 /* Enable RF AGC DAC */
2235 status = read16(state, IQM_AF_STDBY__A, &data);
2236 if (status < 0)
2237 goto error;
2238 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2239 status = write16(state, IQM_AF_STDBY__A, data);
2240 if (status < 0)
2241 goto error;
2242 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2243 if (status < 0)
2244 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002246 /* Enable SCU RF AGC loop */
2247 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002249 /* Polarity */
2250 if (state->m_RfAgcPol)
2251 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2252 else
2253 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2254 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2255 if (status < 0)
2256 goto error;
2257
2258 /* Set speed (using complementary reduction value) */
2259 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2260 if (status < 0)
2261 goto error;
2262
2263 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2264 data |= (~(pAgcCfg->speed <<
2265 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2266 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2267
2268 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2269 if (status < 0)
2270 goto error;
2271
2272 if (IsDVBT(state))
2273 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2274 else if (IsQAM(state))
2275 pIfAgcSettings = &state->m_qamIfAgcCfg;
2276 else
2277 pIfAgcSettings = &state->m_atvIfAgcCfg;
2278 if (pIfAgcSettings == NULL) {
2279 status = -EINVAL;
2280 goto error;
2281 }
2282
2283 /* Set TOP, only if IF-AGC is in AUTO mode */
2284 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2285 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002286 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002287 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002288
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002289 /* Cut-Off current */
2290 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2291 if (status < 0)
2292 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002293
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002294 /* Max. output level */
2295 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2296 if (status < 0)
2297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002300
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002301 case DRXK_AGC_CTRL_USER:
2302 /* Enable RF AGC DAC */
2303 status = read16(state, IQM_AF_STDBY__A, &data);
2304 if (status < 0)
2305 goto error;
2306 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2307 status = write16(state, IQM_AF_STDBY__A, data);
2308 if (status < 0)
2309 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002310
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002311 /* Disable SCU RF AGC loop */
2312 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2313 if (status < 0)
2314 goto error;
2315 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2316 if (state->m_RfAgcPol)
2317 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2318 else
2319 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2320 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2321 if (status < 0)
2322 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002323
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002324 /* SCU c.o.c. to 0, enabling full control range */
2325 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2326 if (status < 0)
2327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002328
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002329 /* Write value to output pin */
2330 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2331 if (status < 0)
2332 goto error;
2333 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002335 case DRXK_AGC_CTRL_OFF:
2336 /* Disable RF AGC DAC */
2337 status = read16(state, IQM_AF_STDBY__A, &data);
2338 if (status < 0)
2339 goto error;
2340 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2341 status = write16(state, IQM_AF_STDBY__A, data);
2342 if (status < 0)
2343 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002344
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002345 /* Disable SCU RF AGC loop */
2346 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2347 if (status < 0)
2348 goto error;
2349 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2350 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2351 if (status < 0)
2352 goto error;
2353 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002355 default:
2356 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002357
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002358 }
2359error:
2360 if (status < 0)
2361 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002362 return status;
2363}
2364
2365#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2366
Oliver Endrissebc7de22011-07-03 13:49:44 -03002367static int SetAgcIf(struct drxk_state *state,
2368 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002369{
2370 u16 data = 0;
2371 int status = 0;
2372 struct SCfgAgc *pRfAgcSettings;
2373
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002374 dprintk(1, "\n");
2375
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002376 switch (pAgcCfg->ctrlMode) {
2377 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002378
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002379 /* Enable IF AGC DAC */
2380 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002381 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002382 goto error;
2383 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2384 status = write16(state, IQM_AF_STDBY__A, data);
2385 if (status < 0)
2386 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002387
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002388 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2389 if (status < 0)
2390 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002391
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002392 /* Enable SCU IF AGC loop */
2393 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2394
2395 /* Polarity */
2396 if (state->m_IfAgcPol)
2397 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2398 else
2399 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2400 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2401 if (status < 0)
2402 goto error;
2403
2404 /* Set speed (using complementary reduction value) */
2405 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2406 if (status < 0)
2407 goto error;
2408 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2409 data |= (~(pAgcCfg->speed <<
2410 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2411 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2412
2413 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2414 if (status < 0)
2415 goto error;
2416
2417 if (IsQAM(state))
2418 pRfAgcSettings = &state->m_qamRfAgcCfg;
2419 else
2420 pRfAgcSettings = &state->m_atvRfAgcCfg;
2421 if (pRfAgcSettings == NULL)
2422 return -1;
2423 /* Restore TOP */
2424 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2425 if (status < 0)
2426 goto error;
2427 break;
2428
2429 case DRXK_AGC_CTRL_USER:
2430
2431 /* Enable IF AGC DAC */
2432 status = read16(state, IQM_AF_STDBY__A, &data);
2433 if (status < 0)
2434 goto error;
2435 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2436 status = write16(state, IQM_AF_STDBY__A, data);
2437 if (status < 0)
2438 goto error;
2439
2440 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2441 if (status < 0)
2442 goto error;
2443
2444 /* Disable SCU IF AGC loop */
2445 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2446
2447 /* Polarity */
2448 if (state->m_IfAgcPol)
2449 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2450 else
2451 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2452 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2453 if (status < 0)
2454 goto error;
2455
2456 /* Write value to output pin */
2457 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2458 if (status < 0)
2459 goto error;
2460 break;
2461
2462 case DRXK_AGC_CTRL_OFF:
2463
2464 /* Disable If AGC DAC */
2465 status = read16(state, IQM_AF_STDBY__A, &data);
2466 if (status < 0)
2467 goto error;
2468 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2469 status = write16(state, IQM_AF_STDBY__A, data);
2470 if (status < 0)
2471 goto error;
2472
2473 /* Disable SCU IF AGC loop */
2474 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2475 if (status < 0)
2476 goto error;
2477 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2478 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2479 if (status < 0)
2480 goto error;
2481 break;
2482 } /* switch (agcSettingsIf->ctrlMode) */
2483
2484 /* always set the top to support
2485 configurations without if-loop */
2486 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2487error:
2488 if (status < 0)
2489 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002490 return status;
2491}
2492
Oliver Endrissebc7de22011-07-03 13:49:44 -03002493static int GetQAMSignalToNoise(struct drxk_state *state,
2494 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002495{
2496 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002497 u16 qamSlErrPower = 0; /* accum. error between
2498 raw and sliced symbols */
2499 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002500 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002501 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002502
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002503 dprintk(1, "\n");
2504
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002505 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002506
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002507 /* get the register value needed for MER */
2508 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2509 if (status < 0) {
2510 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2511 return -EINVAL;
2512 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002513
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002514 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002515 case QAM_16:
2516 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2517 break;
2518 case QAM_32:
2519 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2520 break;
2521 case QAM_64:
2522 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2523 break;
2524 case QAM_128:
2525 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2526 break;
2527 default:
2528 case QAM_256:
2529 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2530 break;
2531 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002532
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002533 if (qamSlErrPower > 0) {
2534 qamSlMer = Log10Times100(qamSlSigPower) -
2535 Log10Times100((u32) qamSlErrPower);
2536 }
2537 *pSignalToNoise = qamSlMer;
2538
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002539 return status;
2540}
2541
Oliver Endrissebc7de22011-07-03 13:49:44 -03002542static int GetDVBTSignalToNoise(struct drxk_state *state,
2543 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002544{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002545 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002546 u16 regData = 0;
2547 u32 EqRegTdSqrErrI = 0;
2548 u32 EqRegTdSqrErrQ = 0;
2549 u16 EqRegTdSqrErrExp = 0;
2550 u16 EqRegTdTpsPwrOfs = 0;
2551 u16 EqRegTdReqSmbCnt = 0;
2552 u32 tpsCnt = 0;
2553 u32 SqrErrIQ = 0;
2554 u32 a = 0;
2555 u32 b = 0;
2556 u32 c = 0;
2557 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558 u16 transmissionParams = 0;
2559
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002560 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002561
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002562 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2563 if (status < 0)
2564 goto error;
2565 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2566 if (status < 0)
2567 goto error;
2568 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2569 if (status < 0)
2570 goto error;
2571 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2572 if (status < 0)
2573 goto error;
2574 /* Extend SQR_ERR_I operational range */
2575 EqRegTdSqrErrI = (u32) regData;
2576 if ((EqRegTdSqrErrExp > 11) &&
2577 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2578 EqRegTdSqrErrI += 0x00010000UL;
2579 }
2580 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2581 if (status < 0)
2582 goto error;
2583 /* Extend SQR_ERR_Q operational range */
2584 EqRegTdSqrErrQ = (u32) regData;
2585 if ((EqRegTdSqrErrExp > 11) &&
2586 (EqRegTdSqrErrQ < 0x00000FFFUL))
2587 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002588
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002589 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2590 if (status < 0)
2591 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002593 /* Check input data for MER */
2594
2595 /* MER calculation (in 0.1 dB) without math.h */
2596 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2597 iMER = 0;
2598 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2599 /* No error at all, this must be the HW reset value
2600 * Apparently no first measurement yet
2601 * Set MER to 0.0 */
2602 iMER = 0;
2603 } else {
2604 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2605 EqRegTdSqrErrExp;
2606 if ((transmissionParams &
2607 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2608 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2609 tpsCnt = 17;
2610 else
2611 tpsCnt = 68;
2612
2613 /* IMER = 100 * log10 (x)
2614 where x = (EqRegTdTpsPwrOfs^2 *
2615 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2616
2617 => IMER = a + b -c
2618 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2619 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2620 c = 100 * log10 (SqrErrIQ)
2621 */
2622
2623 /* log(x) x = 9bits * 9bits->18 bits */
2624 a = Log10Times100(EqRegTdTpsPwrOfs *
2625 EqRegTdTpsPwrOfs);
2626 /* log(x) x = 16bits * 7bits->23 bits */
2627 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2628 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2629 c = Log10Times100(SqrErrIQ);
2630
Mauro Carvalho Chehab48f72a12013-03-22 06:37:32 -03002631 iMER = a + b - c;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002632 }
2633 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002634
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002635error:
2636 if (status < 0)
2637 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002638 return status;
2639}
2640
2641static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2642{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002643 dprintk(1, "\n");
2644
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002645 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002646 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002647 case OM_DVBT:
2648 return GetDVBTSignalToNoise(state, pSignalToNoise);
2649 case OM_QAM_ITU_A:
2650 case OM_QAM_ITU_C:
2651 return GetQAMSignalToNoise(state, pSignalToNoise);
2652 default:
2653 break;
2654 }
2655 return 0;
2656}
2657
2658#if 0
2659static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2660{
2661 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2662 int status = 0;
2663
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002664 dprintk(1, "\n");
2665
Oliver Endrissebc7de22011-07-03 13:49:44 -03002666 static s32 QE_SN[] = {
2667 51, /* QPSK 1/2 */
2668 69, /* QPSK 2/3 */
2669 79, /* QPSK 3/4 */
2670 89, /* QPSK 5/6 */
2671 97, /* QPSK 7/8 */
2672 108, /* 16-QAM 1/2 */
2673 131, /* 16-QAM 2/3 */
2674 146, /* 16-QAM 3/4 */
2675 156, /* 16-QAM 5/6 */
2676 160, /* 16-QAM 7/8 */
2677 165, /* 64-QAM 1/2 */
2678 187, /* 64-QAM 2/3 */
2679 202, /* 64-QAM 3/4 */
2680 216, /* 64-QAM 5/6 */
2681 225, /* 64-QAM 7/8 */
2682 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002683
2684 *pQuality = 0;
2685
2686 do {
2687 s32 SignalToNoise = 0;
2688 u16 Constellation = 0;
2689 u16 CodeRate = 0;
2690 u32 SignalToNoiseRel;
2691 u32 BERQuality;
2692
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002693 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2694 if (status < 0)
2695 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002696 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002697 if (status < 0)
2698 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002699 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2700
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002701 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002702 if (status < 0)
2703 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002704 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2705
2706 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2707 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2708 break;
2709 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002710 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002711 BERQuality = 100;
2712
Oliver Endrissebc7de22011-07-03 13:49:44 -03002713 if (SignalToNoiseRel < -70)
2714 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715 else if (SignalToNoiseRel < 30)
2716 *pQuality = ((SignalToNoiseRel + 70) *
2717 BERQuality) / 100;
2718 else
2719 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002720 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002721 return 0;
2722};
2723
Oliver Endrissebc7de22011-07-03 13:49:44 -03002724static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725{
2726 int status = 0;
2727 *pQuality = 0;
2728
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002729 dprintk(1, "\n");
2730
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002731 do {
2732 u32 SignalToNoise = 0;
2733 u32 BERQuality = 100;
2734 u32 SignalToNoiseRel = 0;
2735
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002736 status = GetQAMSignalToNoise(state, &SignalToNoise);
2737 if (status < 0)
2738 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002739
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002740 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002741 case QAM_16:
2742 SignalToNoiseRel = SignalToNoise - 200;
2743 break;
2744 case QAM_32:
2745 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002746 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747 case QAM_64:
2748 SignalToNoiseRel = SignalToNoise - 260;
2749 break;
2750 case QAM_128:
2751 SignalToNoiseRel = SignalToNoise - 290;
2752 break;
2753 default:
2754 case QAM_256:
2755 SignalToNoiseRel = SignalToNoise - 320;
2756 break;
2757 }
2758
2759 if (SignalToNoiseRel < -70)
2760 *pQuality = 0;
2761 else if (SignalToNoiseRel < 30)
2762 *pQuality = ((SignalToNoiseRel + 70) *
2763 BERQuality) / 100;
2764 else
2765 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002766 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767
2768 return status;
2769}
2770
2771static int GetQuality(struct drxk_state *state, s32 *pQuality)
2772{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002773 dprintk(1, "\n");
2774
Oliver Endrissebc7de22011-07-03 13:49:44 -03002775 switch (state->m_OperationMode) {
2776 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002777 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002778 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002779 return GetDVBCQuality(state, pQuality);
2780 default:
2781 break;
2782 }
2783
2784 return 0;
2785}
2786#endif
2787
2788/* Free data ram in SIO HI */
2789#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2790#define SIO_HI_RA_RAM_USR_END__A 0x420060
2791
2792#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2793#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2794#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2795#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2796
2797#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2798#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2799#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2800
2801static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2802{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002803 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002804
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002805 dprintk(1, "\n");
2806
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002808 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002809 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002812 if (state->no_i2c_bridge)
2813 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002815 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2816 if (status < 0)
2817 goto error;
2818 if (bEnableBridge) {
2819 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 -03002820 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002821 goto error;
2822 } else {
2823 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2824 if (status < 0)
2825 goto error;
2826 }
2827
2828 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2829
2830error:
2831 if (status < 0)
2832 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002833 return status;
2834}
2835
Oliver Endrissebc7de22011-07-03 13:49:44 -03002836static int SetPreSaw(struct drxk_state *state,
2837 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002838{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002839 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002841 dprintk(1, "\n");
2842
Oliver Endrissebc7de22011-07-03 13:49:44 -03002843 if ((pPreSawCfg == NULL)
2844 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002845 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002846
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002847 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002848error:
2849 if (status < 0)
2850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851 return status;
2852}
2853
2854static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002855 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002857 u16 blStatus = 0;
2858 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2859 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2860 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002861 unsigned long end;
2862
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002863 dprintk(1, "\n");
2864
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002865 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002866 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2867 if (status < 0)
2868 goto error;
2869 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2870 if (status < 0)
2871 goto error;
2872 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2873 if (status < 0)
2874 goto error;
2875 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2876 if (status < 0)
2877 goto error;
2878 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2879 if (status < 0)
2880 goto error;
2881 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2882 if (status < 0)
2883 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002884
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002885 end = jiffies + msecs_to_jiffies(timeOut);
2886 do {
2887 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2888 if (status < 0)
2889 goto error;
2890 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2891 if (blStatus == 0x1) {
2892 printk(KERN_ERR "drxk: SIO not ready\n");
2893 status = -EINVAL;
2894 goto error2;
2895 }
2896error:
2897 if (status < 0)
2898 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2899error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002900 mutex_unlock(&state->mutex);
2901 return status;
2902
2903}
2904
Oliver Endrissebc7de22011-07-03 13:49:44 -03002905static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002906{
2907 u16 data = 0;
2908 int status;
2909
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002910 dprintk(1, "\n");
2911
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002912 /* Start measurement */
2913 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2914 if (status < 0)
2915 goto error;
2916 status = write16(state, IQM_AF_START_LOCK__A, 1);
2917 if (status < 0)
2918 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002919
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002920 *count = 0;
2921 status = read16(state, IQM_AF_PHASE0__A, &data);
2922 if (status < 0)
2923 goto error;
2924 if (data == 127)
2925 *count = *count + 1;
2926 status = read16(state, IQM_AF_PHASE1__A, &data);
2927 if (status < 0)
2928 goto error;
2929 if (data == 127)
2930 *count = *count + 1;
2931 status = read16(state, IQM_AF_PHASE2__A, &data);
2932 if (status < 0)
2933 goto error;
2934 if (data == 127)
2935 *count = *count + 1;
2936
2937error:
2938 if (status < 0)
2939 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002940 return status;
2941}
2942
2943static int ADCSynchronization(struct drxk_state *state)
2944{
2945 u16 count = 0;
2946 int status;
2947
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002948 dprintk(1, "\n");
2949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002950 status = ADCSyncMeasurement(state, &count);
2951 if (status < 0)
2952 goto error;
2953
2954 if (count == 1) {
2955 /* Try sampling on a diffrent edge */
2956 u16 clkNeg = 0;
2957
2958 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2959 if (status < 0)
2960 goto error;
Dan Carpenter22a09b42012-06-26 04:40:38 -03002961 if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002962 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2963 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2964 clkNeg |=
2965 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2966 } else {
2967 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2968 clkNeg |=
2969 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2970 }
2971 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2972 if (status < 0)
2973 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002974 status = ADCSyncMeasurement(state, &count);
2975 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002976 goto error;
2977 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002978
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002979 if (count < 2)
2980 status = -EINVAL;
2981error:
2982 if (status < 0)
2983 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002984 return status;
2985}
2986
2987static int SetFrequencyShifter(struct drxk_state *state,
2988 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002989 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002990{
2991 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002992 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002993 u32 fmFrequencyShift = 0;
2994 bool tunerMirror = !state->m_bMirrorFreqSpect;
2995 u32 adcFreq;
2996 bool adcFlip;
2997 int status;
2998 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002999 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003000 u32 frequencyShift;
3001 bool imageToSelect;
3002
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003003 dprintk(1, "\n");
3004
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003005 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003006 Program frequency shifter
3007 No need to account for mirroring on RF
3008 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009 if (isDTV) {
3010 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3011 (state->m_OperationMode == OM_QAM_ITU_C) ||
3012 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003013 selectPosImage = true;
3014 else
3015 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016 }
3017 if (tunerMirror)
3018 /* tuner doesn't mirror */
3019 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003020 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021 else
3022 /* tuner mirrors */
3023 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003024 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003025 if (ifFreqActual > samplingFrequency / 2) {
3026 /* adc mirrors */
3027 adcFreq = samplingFrequency - ifFreqActual;
3028 adcFlip = true;
3029 } else {
3030 /* adc doesn't mirror */
3031 adcFreq = ifFreqActual;
3032 adcFlip = false;
3033 }
3034
3035 frequencyShift = adcFreq;
3036 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003037 adcFlip ^ selectPosImage;
3038 state->m_IqmFsRateOfs =
3039 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040
3041 if (imageToSelect)
3042 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3043
3044 /* Program frequency shifter with tuner offset compensation */
3045 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003046 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3047 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003048 if (status < 0)
3049 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003050 return status;
3051}
3052
3053static int InitAGC(struct drxk_state *state, bool isDTV)
3054{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003055 u16 ingainTgt = 0;
3056 u16 ingainTgtMin = 0;
3057 u16 ingainTgtMax = 0;
3058 u16 clpCyclen = 0;
3059 u16 clpSumMin = 0;
3060 u16 clpDirTo = 0;
3061 u16 snsSumMin = 0;
3062 u16 snsSumMax = 0;
3063 u16 clpSumMax = 0;
3064 u16 snsDirTo = 0;
3065 u16 kiInnergainMin = 0;
3066 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003067 u16 ifIaccuHiTgtMin = 0;
3068 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003069 u16 data = 0;
3070 u16 fastClpCtrlDelay = 0;
3071 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003072 int status = 0;
3073
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003074 dprintk(1, "\n");
3075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003076 /* Common settings */
3077 snsSumMax = 1023;
3078 ifIaccuHiTgtMin = 2047;
3079 clpCyclen = 500;
3080 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003081
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003082 /* AGCInit() not available for DVBT; init done in microcode */
3083 if (!IsQAM(state)) {
3084 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3085 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003086 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003087
3088 /* FIXME: Analog TV AGC require different settings */
3089
3090 /* Standard specific settings */
3091 clpSumMin = 8;
3092 clpDirTo = (u16) -9;
3093 clpCtrlMode = 0;
3094 snsSumMin = 8;
3095 snsDirTo = (u16) -9;
3096 kiInnergainMin = (u16) -1030;
3097 ifIaccuHiTgtMax = 0x2380;
3098 ifIaccuHiTgt = 0x2380;
3099 ingainTgtMin = 0x0511;
3100 ingainTgt = 0x0511;
3101 ingainTgtMax = 5119;
3102 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3103
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003104 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3105 if (status < 0)
3106 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003107
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003108 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3109 if (status < 0)
3110 goto error;
3111 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3112 if (status < 0)
3113 goto error;
3114 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3115 if (status < 0)
3116 goto error;
3117 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3118 if (status < 0)
3119 goto error;
3120 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3121 if (status < 0)
3122 goto error;
3123 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3124 if (status < 0)
3125 goto error;
3126 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3127 if (status < 0)
3128 goto error;
3129 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3130 if (status < 0)
3131 goto error;
3132 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3133 if (status < 0)
3134 goto error;
3135 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3136 if (status < 0)
3137 goto error;
3138 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3139 if (status < 0)
3140 goto error;
3141 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3142 if (status < 0)
3143 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003145 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3152 if (status < 0)
3153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003155 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3156 if (status < 0)
3157 goto error;
3158 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3159 if (status < 0)
3160 goto error;
3161 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3162 if (status < 0)
3163 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003164
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003165 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3166 if (status < 0)
3167 goto error;
3168 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3169 if (status < 0)
3170 goto error;
3171 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3178 if (status < 0)
3179 goto error;
3180 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3181 if (status < 0)
3182 goto error;
3183 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3184 if (status < 0)
3185 goto error;
3186 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3193 if (status < 0)
3194 goto error;
3195 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3196 if (status < 0)
3197 goto error;
3198 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3199 if (status < 0)
3200 goto error;
3201 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3208 if (status < 0)
3209 goto error;
3210 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3211 if (status < 0)
3212 goto error;
3213 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3214 if (status < 0)
3215 goto error;
3216 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3217 if (status < 0)
3218 goto error;
3219 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3220 if (status < 0)
3221 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003222
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003223 /* Initialize inner-loop KI gain factors */
3224 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3225 if (status < 0)
3226 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003227
3228 data = 0x0657;
3229 data &= ~SCU_RAM_AGC_KI_RF__M;
3230 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3231 data &= ~SCU_RAM_AGC_KI_IF__M;
3232 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003234 status = write16(state, SCU_RAM_AGC_KI__A, data);
3235error:
3236 if (status < 0)
3237 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238 return status;
3239}
3240
Oliver Endrissebc7de22011-07-03 13:49:44 -03003241static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003242{
3243 int status;
3244
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003245 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003246 if (packetErr == NULL)
3247 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3248 else
3249 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3250 if (status < 0)
3251 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003252 return status;
3253}
3254
3255static int DVBTScCommand(struct drxk_state *state,
3256 u16 cmd, u16 subcmd,
3257 u16 param0, u16 param1, u16 param2,
3258 u16 param3, u16 param4)
3259{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003260 u16 curCmd = 0;
3261 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003262 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003263 u16 scExec = 0;
3264 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003265
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003266 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003267 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 if (scExec != 1) {
3269 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003270 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003271 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003272 if (status < 0)
3273 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003274
3275 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003276 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 do {
3278 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003279 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003280 retryCnt++;
3281 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003282 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3283 goto error;
3284
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 /* Write sub-command */
3286 switch (cmd) {
3287 /* All commands using sub-cmd */
3288 case OFDM_SC_RA_RAM_CMD_PROC_START:
3289 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3290 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003291 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3292 if (status < 0)
3293 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 break;
3295 default:
3296 /* Do nothing */
3297 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003298 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299
3300 /* Write needed parameters and the command */
3301 switch (cmd) {
3302 /* All commands using 5 parameters */
3303 /* All commands using 4 parameters */
3304 /* All commands using 3 parameters */
3305 /* All commands using 2 parameters */
3306 case OFDM_SC_RA_RAM_CMD_PROC_START:
3307 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3308 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003309 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003310 /* All commands using 1 parameters */
3311 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3312 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003313 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003314 /* All commands using 0 parameters */
3315 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3316 case OFDM_SC_RA_RAM_CMD_NULL:
3317 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003318 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003319 break;
3320 default:
3321 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003322 status = -EINVAL;
3323 }
3324 if (status < 0)
3325 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326
3327 /* Wait until sc is ready processing command */
3328 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003329 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003331 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003332 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003333 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003334 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3335 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336
3337 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003338 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003339 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003341 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003342 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003343 if (status < 0)
3344 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345
3346 /* Retreive results parameters from SC */
3347 switch (cmd) {
3348 /* All commands yielding 5 results */
3349 /* All commands yielding 4 results */
3350 /* All commands yielding 3 results */
3351 /* All commands yielding 2 results */
3352 /* All commands yielding 1 result */
3353 case OFDM_SC_RA_RAM_CMD_USER_IO:
3354 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 /* All commands yielding 0 results */
3357 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3358 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3359 case OFDM_SC_RA_RAM_CMD_PROC_START:
3360 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3361 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3362 case OFDM_SC_RA_RAM_CMD_NULL:
3363 break;
3364 default:
3365 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003366 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003367 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003368 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003369error:
3370 if (status < 0)
3371 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372 return status;
3373}
3374
Oliver Endrissebc7de22011-07-03 13:49:44 -03003375static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003377 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003378 int status;
3379
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003380 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 status = CtrlPowerMode(state, &powerMode);
3382 if (status < 0)
3383 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003384 return status;
3385}
3386
Oliver Endrissebc7de22011-07-03 13:49:44 -03003387static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003391 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003393 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003394 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003395 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003396 if (status < 0)
3397 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003398 return status;
3399}
3400
3401#define DEFAULT_FR_THRES_8K 4000
3402static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3403{
3404
3405 int status;
3406
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003407 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 if (*enabled == true) {
3409 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003410 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003411 DEFAULT_FR_THRES_8K);
3412 } else {
3413 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003414 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003415 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003416 if (status < 0)
3417 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003418
3419 return status;
3420}
3421
3422static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3423 struct DRXKCfgDvbtEchoThres_t *echoThres)
3424{
3425 u16 data = 0;
3426 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003427
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003428 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003429 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3430 if (status < 0)
3431 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003433 switch (echoThres->fftMode) {
3434 case DRX_FFTMODE_2K:
3435 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3436 data |= ((echoThres->threshold <<
3437 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3438 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003439 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003440 case DRX_FFTMODE_8K:
3441 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3442 data |= ((echoThres->threshold <<
3443 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3444 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003445 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003446 default:
3447 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003448 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003449
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003450 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3451error:
3452 if (status < 0)
3453 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003454 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003455}
3456
3457static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003458 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003459{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003460 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003462 dprintk(1, "\n");
3463
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003464 switch (*speed) {
3465 case DRXK_DVBT_SQI_SPEED_FAST:
3466 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3467 case DRXK_DVBT_SQI_SPEED_SLOW:
3468 break;
3469 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003470 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003471 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003472 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003473 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003474error:
3475 if (status < 0)
3476 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003477 return status;
3478}
3479
3480/*============================================================================*/
3481
3482/**
3483* \brief Activate DVBT specific presets
3484* \param demod instance of demodulator.
3485* \return DRXStatus_t.
3486*
3487* Called in DVBTSetStandard
3488*
3489*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003490static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003491{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003492 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003493 bool setincenable = false;
3494 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003495
Oliver Endrissebc7de22011-07-03 13:49:44 -03003496 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3497 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003498
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003499 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003500 status = DVBTCtrlSetIncEnable(state, &setincenable);
3501 if (status < 0)
3502 goto error;
3503 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3504 if (status < 0)
3505 goto error;
3506 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3507 if (status < 0)
3508 goto error;
3509 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3510 if (status < 0)
3511 goto error;
3512 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3513error:
3514 if (status < 0)
3515 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003516 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003518
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003519/*============================================================================*/
3520
3521/**
3522* \brief Initialize channelswitch-independent settings for DVBT.
3523* \param demod instance of demodulator.
3524* \return DRXStatus_t.
3525*
3526* For ROM code channel filter taps are loaded from the bootloader. For microcode
3527* the DVB-T taps from the drxk_filters.h are used.
3528*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003529static int SetDVBTStandard(struct drxk_state *state,
3530 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003531{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003532 u16 cmdResult = 0;
3533 u16 data = 0;
3534 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003535
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003536 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003537
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003538 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003539 /* added antenna switch */
3540 SwitchAntennaToDVBT(state);
3541 /* send OFDM reset command */
3542 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 -03003543 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003544 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003546 /* send OFDM setenv command */
3547 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3548 if (status < 0)
3549 goto error;
3550
3551 /* reset datapath for OFDM, processors first */
3552 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3553 if (status < 0)
3554 goto error;
3555 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3556 if (status < 0)
3557 goto error;
3558 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3559 if (status < 0)
3560 goto error;
3561
3562 /* IQM setup */
3563 /* synchronize on ofdstate->m_festart */
3564 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3565 if (status < 0)
3566 goto error;
3567 /* window size for clipping ADC detection */
3568 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3569 if (status < 0)
3570 goto error;
3571 /* window size for for sense pre-SAW detection */
3572 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3573 if (status < 0)
3574 goto error;
3575 /* sense threshold for sense pre-SAW detection */
3576 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3577 if (status < 0)
3578 goto error;
3579 status = SetIqmAf(state, true);
3580 if (status < 0)
3581 goto error;
3582
3583 status = write16(state, IQM_AF_AGC_RF__A, 0);
3584 if (status < 0)
3585 goto error;
3586
3587 /* Impulse noise cruncher setup */
3588 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3589 if (status < 0)
3590 goto error;
3591 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3592 if (status < 0)
3593 goto error;
3594 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3595 if (status < 0)
3596 goto error;
3597
3598 status = write16(state, IQM_RC_STRETCH__A, 16);
3599 if (status < 0)
3600 goto error;
3601 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3602 if (status < 0)
3603 goto error;
3604 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3605 if (status < 0)
3606 goto error;
3607 status = write16(state, IQM_CF_SCALE__A, 1600);
3608 if (status < 0)
3609 goto error;
3610 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3611 if (status < 0)
3612 goto error;
3613
3614 /* virtual clipping threshold for clipping ADC detection */
3615 status = write16(state, IQM_AF_CLP_TH__A, 448);
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3619 if (status < 0)
3620 goto error;
3621
3622 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3623 if (status < 0)
3624 goto error;
3625
3626 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3627 if (status < 0)
3628 goto error;
3629 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3630 if (status < 0)
3631 goto error;
3632 /* enable power measurement interrupt */
3633 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3634 if (status < 0)
3635 goto error;
3636 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3637 if (status < 0)
3638 goto error;
3639
3640 /* IQM will not be reset from here, sync ADC and update/init AGC */
3641 status = ADCSynchronization(state);
3642 if (status < 0)
3643 goto error;
3644 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3645 if (status < 0)
3646 goto error;
3647
3648 /* Halt SCU to enable safe non-atomic accesses */
3649 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3650 if (status < 0)
3651 goto error;
3652
3653 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3654 if (status < 0)
3655 goto error;
3656 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3657 if (status < 0)
3658 goto error;
3659
3660 /* Set Noise Estimation notch width and enable DC fix */
3661 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3662 if (status < 0)
3663 goto error;
3664 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3665 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3666 if (status < 0)
3667 goto error;
3668
3669 /* Activate SCU to enable SCU commands */
3670 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3671 if (status < 0)
3672 goto error;
3673
3674 if (!state->m_DRXK_A3_ROM_CODE) {
3675 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3676 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3677 if (status < 0)
3678 goto error;
3679 }
3680
3681 /* OFDM_SC setup */
3682#ifdef COMPILE_FOR_NONRT
3683 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3684 if (status < 0)
3685 goto error;
3686 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3687 if (status < 0)
3688 goto error;
3689#endif
3690
3691 /* FEC setup */
3692 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3693 if (status < 0)
3694 goto error;
3695
3696
3697#ifdef COMPILE_FOR_NONRT
3698 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3699 if (status < 0)
3700 goto error;
3701#else
3702 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3703 if (status < 0)
3704 goto error;
3705#endif
3706 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3707 if (status < 0)
3708 goto error;
3709
3710 /* Setup MPEG bus */
3711 status = MPEGTSDtoSetup(state, OM_DVBT);
3712 if (status < 0)
3713 goto error;
3714 /* Set DVBT Presets */
3715 status = DVBTActivatePresets(state);
3716 if (status < 0)
3717 goto error;
3718
3719error:
3720 if (status < 0)
3721 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003722 return status;
3723}
3724
3725/*============================================================================*/
3726/**
3727* \brief Start dvbt demodulating for channel.
3728* \param demod instance of demodulator.
3729* \return DRXStatus_t.
3730*/
3731static int DVBTStart(struct drxk_state *state)
3732{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003733 u16 param1;
3734 int status;
3735 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003736
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003737 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003738 /* Start correct processes to get in lock */
3739 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003740 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3741 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3742 if (status < 0)
3743 goto error;
3744 /* Start FEC OC */
3745 status = MPEGTSStart(state);
3746 if (status < 0)
3747 goto error;
3748 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3749 if (status < 0)
3750 goto error;
3751error:
3752 if (status < 0)
3753 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003754 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003755}
3756
3757
3758/*============================================================================*/
3759
3760/**
3761* \brief Set up dvbt demodulator for channel.
3762* \param demod instance of demodulator.
3763* \return DRXStatus_t.
3764* // original DVBTSetChannel()
3765*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003766static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3767 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003769 u16 cmdResult = 0;
3770 u16 transmissionParams = 0;
3771 u16 operationMode = 0;
3772 u32 iqmRcRateOfs = 0;
3773 u32 bandwidth = 0;
3774 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003775 int status;
3776
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003777 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003778
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003779 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3780 if (status < 0)
3781 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003783 /* Halt SCU to enable safe non-atomic accesses */
3784 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3785 if (status < 0)
3786 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003788 /* Stop processors */
3789 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3790 if (status < 0)
3791 goto error;
3792 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3793 if (status < 0)
3794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 /* Mandatory fix, always stop CP, required to set spl offset back to
3797 hardware default (is set to 0 by ucode during pilot detection */
3798 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3799 if (status < 0)
3800 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003802 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003804 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003805 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003806 case TRANSMISSION_MODE_AUTO:
3807 default:
3808 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3809 /* fall through , try first guess DRX_FFTMODE_8K */
3810 case TRANSMISSION_MODE_8K:
3811 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003812 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 case TRANSMISSION_MODE_2K:
3814 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003815 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003816 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003819 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003820 default:
3821 case GUARD_INTERVAL_AUTO:
3822 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3823 /* fall through , try first guess DRX_GUARD_1DIV4 */
3824 case GUARD_INTERVAL_1_4:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003826 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 case GUARD_INTERVAL_1_32:
3828 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003829 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 case GUARD_INTERVAL_1_16:
3831 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003832 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 case GUARD_INTERVAL_1_8:
3834 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003835 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003836 }
3837
3838 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003839 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003840 case HIERARCHY_AUTO:
3841 case HIERARCHY_NONE:
3842 default:
3843 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3844 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3845 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3846 /* break; */
3847 case HIERARCHY_1:
3848 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3849 break;
3850 case HIERARCHY_2:
3851 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3852 break;
3853 case HIERARCHY_4:
3854 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3855 break;
3856 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003857
3858
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003859 /* modulation */
3860 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003861 case QAM_AUTO:
3862 default:
3863 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3864 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3865 case QAM_64:
3866 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3867 break;
3868 case QPSK:
3869 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3870 break;
3871 case QAM_16:
3872 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3873 break;
3874 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003875#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003876 /* No hierachical channels support in BDA */
3877 /* Priority (only for hierarchical channels) */
3878 switch (channel->priority) {
3879 case DRX_PRIORITY_LOW:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3881 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3882 OFDM_EC_SB_PRIOR_LO);
3883 break;
3884 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3887 OFDM_EC_SB_PRIOR_HI));
3888 break;
3889 case DRX_PRIORITY_UNKNOWN: /* fall through */
3890 default:
3891 status = -EINVAL;
3892 goto error;
3893 }
3894#else
3895 /* Set Priorty high */
3896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3897 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3898 if (status < 0)
3899 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003900#endif
3901
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003902 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003903 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003904 case FEC_AUTO:
3905 default:
3906 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3907 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3908 case FEC_2_3:
3909 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3910 break;
3911 case FEC_1_2:
3912 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3913 break;
3914 case FEC_3_4:
3915 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3916 break;
3917 case FEC_5_6:
3918 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3919 break;
3920 case FEC_7_8:
3921 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3922 break;
3923 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003925 /* SAW filter selection: normaly not necesarry, but if wanted
3926 the application can select a SAW filter via the driver by using UIOs */
3927 /* First determine real bandwidth (Hz) */
3928 /* Also set delay for impulse noise cruncher */
3929 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3930 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3931 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003932 switch (state->props.bandwidth_hz) {
3933 case 0:
3934 state->props.bandwidth_hz = 8000000;
3935 /* fall though */
3936 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003937 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3938 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003939 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003940 goto error;
3941 /* cochannel protection for PAL 8 MHz */
3942 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3943 if (status < 0)
3944 goto error;
3945 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3946 if (status < 0)
3947 goto error;
3948 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3949 if (status < 0)
3950 goto error;
3951 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3952 if (status < 0)
3953 goto error;
3954 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003955 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003956 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3957 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3958 if (status < 0)
3959 goto error;
3960 /* cochannel protection for PAL 7 MHz */
3961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3962 if (status < 0)
3963 goto error;
3964 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3965 if (status < 0)
3966 goto error;
3967 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3968 if (status < 0)
3969 goto error;
3970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3971 if (status < 0)
3972 goto error;
3973 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003974 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003975 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3976 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3977 if (status < 0)
3978 goto error;
3979 /* cochannel protection for NTSC 6 MHz */
3980 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3981 if (status < 0)
3982 goto error;
3983 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3984 if (status < 0)
3985 goto error;
3986 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3987 if (status < 0)
3988 goto error;
3989 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3990 if (status < 0)
3991 goto error;
3992 break;
3993 default:
3994 status = -EINVAL;
3995 goto error;
3996 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003997
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003998 if (iqmRcRateOfs == 0) {
3999 /* Now compute IQM_RC_RATE_OFS
4000 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4001 =>
4002 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4003 */
4004 /* (SysFreq / BandWidth) * (2^28) */
4005 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4006 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4007 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4008 iqmRcRateOfs = Frac28a((u32)
4009 ((state->m_sysClockFreq *
4010 1000) / 3), bandwidth);
4011 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4012 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4013 iqmRcRateOfs += 0x80L;
4014 iqmRcRateOfs = iqmRcRateOfs >> 7;
4015 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4016 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4017 }
4018
4019 iqmRcRateOfs &=
4020 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4021 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4022 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4023 if (status < 0)
4024 goto error;
4025
4026 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004027
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004028#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004029 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4030 if (status < 0)
4031 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004032#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004033 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4034 if (status < 0)
4035 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004036
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004037 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004038
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004039 /* Activate SCU to enable SCU commands */
4040 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4041 if (status < 0)
4042 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004044 /* Enable SC after setting all other parameters */
4045 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4046 if (status < 0)
4047 goto error;
4048 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4049 if (status < 0)
4050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051
4052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004053 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4054 if (status < 0)
4055 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004056
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004057 /* Write SC parameter registers, set all AUTO flags in operation mode */
4058 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4059 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4060 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4061 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4062 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4063 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4064 0, transmissionParams, param1, 0, 0, 0);
4065 if (status < 0)
4066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004068 if (!state->m_DRXK_A3_ROM_CODE)
4069 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4070error:
4071 if (status < 0)
4072 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004073
4074 return status;
4075}
4076
4077
4078/*============================================================================*/
4079
4080/**
4081* \brief Retreive lock status .
4082* \param demod Pointer to demodulator instance.
4083* \param lockStat Pointer to lock status structure.
4084* \return DRXStatus_t.
4085*
4086*/
4087static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4088{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004089 int status;
4090 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4091 OFDM_SC_RA_RAM_LOCK_FEC__M);
4092 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4093 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004094
Oliver Endrissebc7de22011-07-03 13:49:44 -03004095 u16 ScRaRamLock = 0;
4096 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004097
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004098 dprintk(1, "\n");
4099
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004100 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004101 /* driver 0.9.0 */
4102 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004103 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004104 if (status < 0)
4105 goto end;
4106 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4107 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004108
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004109 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004110 if (status < 0)
4111 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Oliver Endrissebc7de22011-07-03 13:49:44 -03004113 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4114 *pLockStatus = MPEG_LOCK;
4115 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4116 *pLockStatus = FEC_LOCK;
4117 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4118 *pLockStatus = DEMOD_LOCK;
4119 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4120 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004121end:
4122 if (status < 0)
4123 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004124
Oliver Endrissebc7de22011-07-03 13:49:44 -03004125 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004126}
4127
Oliver Endrissebc7de22011-07-03 13:49:44 -03004128static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004129{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004130 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004131 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004132
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004133 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004134 status = CtrlPowerMode(state, &powerMode);
4135 if (status < 0)
4136 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004137
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004139}
4140
4141
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143static int PowerDownQAM(struct drxk_state *state)
4144{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004145 u16 data = 0;
4146 u16 cmdResult;
4147 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004148
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004149 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004150 status = read16(state, SCU_COMM_EXEC__A, &data);
4151 if (status < 0)
4152 goto error;
4153 if (data == SCU_COMM_EXEC_ACTIVE) {
4154 /*
4155 STOP demodulator
4156 QAM and HW blocks
4157 */
4158 /* stop all comstate->m_exec */
4159 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004160 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004161 goto error;
4162 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 -03004163 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004164 goto error;
4165 }
4166 /* powerdown AFE */
4167 status = SetIqmAf(state, false);
4168
4169error:
4170 if (status < 0)
4171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004172
Oliver Endrissebc7de22011-07-03 13:49:44 -03004173 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004174}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004175
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004176/*============================================================================*/
4177
4178/**
4179* \brief Setup of the QAM Measurement intervals for signal quality
4180* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004181* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004182* \return DRXStatus_t.
4183*
4184* NOTE:
4185* Take into account that for certain settings the errorcounters can overflow.
4186* The implementation does not check this.
4187*
4188*/
4189static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004190 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191 u32 symbolRate)
4192{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004193 u32 fecBitsDesired = 0; /* BER accounting period */
4194 u32 fecRsPeriodTotal = 0; /* Total period */
4195 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4196 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004197 int status = 0;
4198
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004199 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004200
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004201 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004202 /* fecBitsDesired = symbolRate [kHz] *
4203 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004204 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004205 SyncLoss (== 1) *
4206 ViterbiLoss (==1)
4207 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004208 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004209 case DRX_CONSTELLATION_QAM16:
4210 fecBitsDesired = 4 * symbolRate;
4211 break;
4212 case DRX_CONSTELLATION_QAM32:
4213 fecBitsDesired = 5 * symbolRate;
4214 break;
4215 case DRX_CONSTELLATION_QAM64:
4216 fecBitsDesired = 6 * symbolRate;
4217 break;
4218 case DRX_CONSTELLATION_QAM128:
4219 fecBitsDesired = 7 * symbolRate;
4220 break;
4221 case DRX_CONSTELLATION_QAM256:
4222 fecBitsDesired = 8 * symbolRate;
4223 break;
4224 default:
4225 status = -EINVAL;
4226 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004227 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004228 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004230 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4231 fecBitsDesired *= 500; /* meas. period [ms] */
4232
4233 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4234 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4235 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4236
4237 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4238 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4239 if (fecRsPrescale == 0) {
4240 /* Divide by zero (though impossible) */
4241 status = -EINVAL;
4242 if (status < 0)
4243 goto error;
4244 }
4245 fecRsPeriod =
4246 ((u16) fecRsPeriodTotal +
4247 (fecRsPrescale >> 1)) / fecRsPrescale;
4248
4249 /* write corresponding registers */
4250 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4251 if (status < 0)
4252 goto error;
4253 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4254 if (status < 0)
4255 goto error;
4256 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4257error:
4258 if (status < 0)
4259 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004260 return status;
4261}
4262
Oliver Endrissebc7de22011-07-03 13:49:44 -03004263static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004264{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004265 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004266
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004267 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004268 /* QAM Equalizer Setup */
4269 /* Equalizer */
4270 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4271 if (status < 0)
4272 goto error;
4273 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4274 if (status < 0)
4275 goto error;
4276 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4277 if (status < 0)
4278 goto error;
4279 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 /* Decision Feedback Equalizer */
4289 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4290 if (status < 0)
4291 goto error;
4292 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4293 if (status < 0)
4294 goto error;
4295 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4305 if (status < 0)
4306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004307
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004308 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4309 if (status < 0)
4310 goto error;
4311 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4312 if (status < 0)
4313 goto error;
4314 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4315 if (status < 0)
4316 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004317
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004318 /* QAM Slicer Settings */
4319 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4320 if (status < 0)
4321 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004323 /* QAM Loop Controller Coeficients */
4324 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4325 if (status < 0)
4326 goto error;
4327 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4328 if (status < 0)
4329 goto error;
4330 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4331 if (status < 0)
4332 goto error;
4333 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4334 if (status < 0)
4335 goto error;
4336 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4346 if (status < 0)
4347 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004348
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004349 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4350 if (status < 0)
4351 goto error;
4352 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4353 if (status < 0)
4354 goto error;
4355 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4383 if (status < 0)
4384 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004385
4386
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004387 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004388
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004389 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4390 if (status < 0)
4391 goto error;
4392 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4393 if (status < 0)
4394 goto error;
4395 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4405 if (status < 0)
4406 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004407
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004408 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4412 if (status < 0)
4413 goto error;
4414 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4415 if (status < 0)
4416 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004417
4418
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004419 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004420
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004421 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4422 if (status < 0)
4423 goto error;
4424 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4425 if (status < 0)
4426 goto error;
4427 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4428 if (status < 0)
4429 goto error;
4430 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4431 if (status < 0)
4432 goto error;
4433 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4440 if (status < 0)
4441 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004442
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004443error:
4444 if (status < 0)
4445 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004446 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004447}
4448
4449/*============================================================================*/
4450
4451/**
4452* \brief QAM32 specific setup
4453* \param demod instance of demod.
4454* \return DRXStatus_t.
4455*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004456static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004457{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004458 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004459
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004460 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004461
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004462 /* QAM Equalizer Setup */
4463 /* Equalizer */
4464 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4465 if (status < 0)
4466 goto error;
4467 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4468 if (status < 0)
4469 goto error;
4470 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4471 if (status < 0)
4472 goto error;
4473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4480 if (status < 0)
4481 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004482
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004483 /* Decision Feedback Equalizer */
4484 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4485 if (status < 0)
4486 goto error;
4487 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4488 if (status < 0)
4489 goto error;
4490 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4491 if (status < 0)
4492 goto error;
4493 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4500 if (status < 0)
4501 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004502
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004503 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4504 if (status < 0)
4505 goto error;
4506 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4507 if (status < 0)
4508 goto error;
4509 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4510 if (status < 0)
4511 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004512
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004513 /* QAM Slicer Settings */
4514
4515 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4516 if (status < 0)
4517 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004518
4519
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004520 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004521
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004522 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4523 if (status < 0)
4524 goto error;
4525 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4526 if (status < 0)
4527 goto error;
4528 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4529 if (status < 0)
4530 goto error;
4531 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4532 if (status < 0)
4533 goto error;
4534 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4544 if (status < 0)
4545 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004546
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004547 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4548 if (status < 0)
4549 goto error;
4550 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4551 if (status < 0)
4552 goto error;
4553 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4581 if (status < 0)
4582 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004583
4584
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004585 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004586
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004587 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4588 if (status < 0)
4589 goto error;
4590 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4603 if (status < 0)
4604 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004605
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004606 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4607 if (status < 0)
4608 goto error;
4609 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4610 if (status < 0)
4611 goto error;
4612 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4613 if (status < 0)
4614 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004615
4616
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004617 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004618
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004619 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4620 if (status < 0)
4621 goto error;
4622 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4623 if (status < 0)
4624 goto error;
4625 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4626 if (status < 0)
4627 goto error;
4628 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4629 if (status < 0)
4630 goto error;
4631 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4632 if (status < 0)
4633 goto error;
4634 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4638error:
4639 if (status < 0)
4640 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004641 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004642}
4643
4644/*============================================================================*/
4645
4646/**
4647* \brief QAM64 specific setup
4648* \param demod instance of demod.
4649* \return DRXStatus_t.
4650*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004651static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004652{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004653 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004654
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004655 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004656 /* QAM Equalizer Setup */
4657 /* Equalizer */
4658 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4659 if (status < 0)
4660 goto error;
4661 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4662 if (status < 0)
4663 goto error;
4664 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4665 if (status < 0)
4666 goto error;
4667 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4668 if (status < 0)
4669 goto error;
4670 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4674 if (status < 0)
4675 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004676
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004677 /* Decision Feedback Equalizer */
4678 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4685 if (status < 0)
4686 goto error;
4687 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4694 if (status < 0)
4695 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004696
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004697 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4704 if (status < 0)
4705 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004707 /* QAM Slicer Settings */
4708 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4709 if (status < 0)
4710 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004711
4712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004713 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004715 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4716 if (status < 0)
4717 goto error;
4718 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4719 if (status < 0)
4720 goto error;
4721 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4722 if (status < 0)
4723 goto error;
4724 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4737 if (status < 0)
4738 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004740 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4741 if (status < 0)
4742 goto error;
4743 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4744 if (status < 0)
4745 goto error;
4746 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4774 if (status < 0)
4775 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004776
4777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004778 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004780 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4781 if (status < 0)
4782 goto error;
4783 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4796 if (status < 0)
4797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004799 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4800 if (status < 0)
4801 goto error;
4802 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4806 if (status < 0)
4807 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004808
4809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004810 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004811
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004812 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4813 if (status < 0)
4814 goto error;
4815 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4816 if (status < 0)
4817 goto error;
4818 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4819 if (status < 0)
4820 goto error;
4821 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4831error:
4832 if (status < 0)
4833 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004834
Oliver Endrissebc7de22011-07-03 13:49:44 -03004835 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004836}
4837
4838/*============================================================================*/
4839
4840/**
4841* \brief QAM128 specific setup
4842* \param demod: instance of demod.
4843* \return DRXStatus_t.
4844*/
4845static int SetQAM128(struct drxk_state *state)
4846{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004847 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004848
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004849 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004850 /* QAM Equalizer Setup */
4851 /* Equalizer */
4852 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4853 if (status < 0)
4854 goto error;
4855 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4856 if (status < 0)
4857 goto error;
4858 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4859 if (status < 0)
4860 goto error;
4861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4868 if (status < 0)
4869 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004870
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004871 /* Decision Feedback Equalizer */
4872 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4876 if (status < 0)
4877 goto error;
4878 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4888 if (status < 0)
4889 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004890
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004891 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4892 if (status < 0)
4893 goto error;
4894 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4895 if (status < 0)
4896 goto error;
4897 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4898 if (status < 0)
4899 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004900
4901
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004902 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004903
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004904 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4905 if (status < 0)
4906 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004907
4908
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004909 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004911 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4912 if (status < 0)
4913 goto error;
4914 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4915 if (status < 0)
4916 goto error;
4917 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4918 if (status < 0)
4919 goto error;
4920 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4933 if (status < 0)
4934 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004935
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004936 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4937 if (status < 0)
4938 goto error;
4939 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4940 if (status < 0)
4941 goto error;
4942 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4970 if (status < 0)
4971 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004972
4973
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004974 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004975
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004976 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4992 if (status < 0)
4993 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004994
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004995 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4996 if (status < 0)
4997 goto error;
4998 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4999 if (status < 0)
5000 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005001
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005002 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5003 if (status < 0)
5004 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005006 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005008 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5009 if (status < 0)
5010 goto error;
5011 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5012 if (status < 0)
5013 goto error;
5014 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5015 if (status < 0)
5016 goto error;
5017 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5027error:
5028 if (status < 0)
5029 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005030
Oliver Endrissebc7de22011-07-03 13:49:44 -03005031 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032}
5033
5034/*============================================================================*/
5035
5036/**
5037* \brief QAM256 specific setup
5038* \param demod: instance of demod.
5039* \return DRXStatus_t.
5040*/
5041static int SetQAM256(struct drxk_state *state)
5042{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005043 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005044
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005045 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005046 /* QAM Equalizer Setup */
5047 /* Equalizer */
5048 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5049 if (status < 0)
5050 goto error;
5051 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5052 if (status < 0)
5053 goto error;
5054 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5064 if (status < 0)
5065 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005067 /* Decision Feedback Equalizer */
5068 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5069 if (status < 0)
5070 goto error;
5071 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5072 if (status < 0)
5073 goto error;
5074 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5075 if (status < 0)
5076 goto error;
5077 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5084 if (status < 0)
5085 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005086
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005087 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5088 if (status < 0)
5089 goto error;
5090 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5091 if (status < 0)
5092 goto error;
5093 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5094 if (status < 0)
5095 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005096
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005097 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005098
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005099 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5100 if (status < 0)
5101 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005102
5103
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005104 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005106 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5107 if (status < 0)
5108 goto error;
5109 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5110 if (status < 0)
5111 goto error;
5112 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5113 if (status < 0)
5114 goto error;
5115 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5116 if (status < 0)
5117 goto error;
5118 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5128 if (status < 0)
5129 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005131 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5132 if (status < 0)
5133 goto error;
5134 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5135 if (status < 0)
5136 goto error;
5137 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5165 if (status < 0)
5166 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005167
5168
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005169 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005171 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5172 if (status < 0)
5173 goto error;
5174 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5175 if (status < 0)
5176 goto error;
5177 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5187 if (status < 0)
5188 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005189
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005190 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5191 if (status < 0)
5192 goto error;
5193 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5194 if (status < 0)
5195 goto error;
5196 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5197 if (status < 0)
5198 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005199
5200
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005201 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005202
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005203 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5204 if (status < 0)
5205 goto error;
5206 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5207 if (status < 0)
5208 goto error;
5209 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5210 if (status < 0)
5211 goto error;
5212 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5213 if (status < 0)
5214 goto error;
5215 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5216 if (status < 0)
5217 goto error;
5218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5222error:
5223 if (status < 0)
5224 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005225 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005226}
5227
5228
5229/*============================================================================*/
5230/**
5231* \brief Reset QAM block.
5232* \param demod: instance of demod.
5233* \param channel: pointer to channel data.
5234* \return DRXStatus_t.
5235*/
5236static int QAMResetQAM(struct drxk_state *state)
5237{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005238 int status;
5239 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005240
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005241 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005242 /* Stop QAM comstate->m_exec */
5243 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5244 if (status < 0)
5245 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005246
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005247 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5248error:
5249 if (status < 0)
5250 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005251 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005252}
5253
5254/*============================================================================*/
5255
5256/**
5257* \brief Set QAM symbolrate.
5258* \param demod: instance of demod.
5259* \param channel: pointer to channel data.
5260* \return DRXStatus_t.
5261*/
5262static int QAMSetSymbolrate(struct drxk_state *state)
5263{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005264 u32 adcFrequency = 0;
5265 u32 symbFreq = 0;
5266 u32 iqmRcRate = 0;
5267 u16 ratesel = 0;
5268 u32 lcSymbRate = 0;
5269 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005271 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005272 /* Select & calculate correct IQM rate */
5273 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5274 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005275 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5276 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005277 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005278 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005279 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005280 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005281 ratesel = 1;
5282 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5283 if (status < 0)
5284 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005285
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005286 /*
5287 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5288 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005289 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005290 if (symbFreq == 0) {
5291 /* Divide by zero */
5292 status = -EINVAL;
5293 goto error;
5294 }
5295 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5296 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5297 (1 << 23);
5298 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5299 if (status < 0)
5300 goto error;
5301 state->m_iqmRcRate = iqmRcRate;
5302 /*
5303 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5304 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005305 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005306 if (adcFrequency == 0) {
5307 /* Divide by zero */
5308 status = -EINVAL;
5309 goto error;
5310 }
5311 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5312 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5313 16);
5314 if (lcSymbRate > 511)
5315 lcSymbRate = 511;
5316 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005317
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005318error:
5319 if (status < 0)
5320 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005321 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005322}
5323
5324/*============================================================================*/
5325
5326/**
5327* \brief Get QAM lock status.
5328* \param demod: instance of demod.
5329* \param channel: pointer to channel data.
5330* \return DRXStatus_t.
5331*/
5332
5333static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5334{
5335 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005336 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005337
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005338 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005339 *pLockStatus = NOT_LOCKED;
5340 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005341 SCU_RAM_COMMAND_STANDARD_QAM |
5342 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5343 Result);
5344 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005345 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005346
5347 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005348 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005349 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005350 /* 0x4000 DEMOD LOCKED */
5351 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005353 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5354 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005355 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005356 /* 0xC000 NEVER LOCKED */
5357 /* (system will never be able to lock to the signal) */
5358 /* TODO: check this, intermediate & standard specific lock states are not
5359 taken into account here */
5360 *pLockStatus = NEVER_LOCK;
5361 }
5362 return status;
5363}
5364
5365#define QAM_MIRROR__M 0x03
5366#define QAM_MIRROR_NORMAL 0x00
5367#define QAM_MIRRORED 0x01
5368#define QAM_MIRROR_AUTO_ON 0x02
5369#define QAM_LOCKRANGE__M 0x10
5370#define QAM_LOCKRANGE_NORMAL 0x10
5371
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005372static int QAMDemodulatorCommand(struct drxk_state *state,
5373 int numberOfParameters)
5374{
5375 int status;
5376 u16 cmdResult;
5377 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5378
5379 setParamParameters[0] = state->m_Constellation; /* modulation */
5380 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5381
5382 if (numberOfParameters == 2) {
5383 u16 setEnvParameters[1] = { 0 };
5384
5385 if (state->m_OperationMode == OM_QAM_ITU_C)
5386 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5387 else
5388 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5389
5390 status = scu_command(state,
5391 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5392 1, setEnvParameters, 1, &cmdResult);
5393 if (status < 0)
5394 goto error;
5395
5396 status = scu_command(state,
5397 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5398 numberOfParameters, setParamParameters,
5399 1, &cmdResult);
5400 } else if (numberOfParameters == 4) {
5401 if (state->m_OperationMode == OM_QAM_ITU_C)
5402 setParamParameters[2] = QAM_TOP_ANNEX_C;
5403 else
5404 setParamParameters[2] = QAM_TOP_ANNEX_A;
5405
5406 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5407 /* Env parameters */
5408 /* check for LOCKRANGE Extented */
5409 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5410
5411 status = scu_command(state,
5412 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5413 numberOfParameters, setParamParameters,
5414 1, &cmdResult);
5415 } else {
5416 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5417 "count %d\n", numberOfParameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005418 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005419 }
5420
5421error:
5422 if (status < 0)
5423 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5424 status, __func__);
5425 return status;
5426}
5427
Oliver Endrissebc7de22011-07-03 13:49:44 -03005428static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5429 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005430{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005431 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005432 u16 cmdResult;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005433 int qamDemodParamCount = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005434
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005435 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005436 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005437 * STEP 1: reset demodulator
5438 * resets FEC DI and FEC RS
5439 * resets QAM block
5440 * resets SCU variables
5441 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005442 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005443 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005444 goto error;
5445 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5446 if (status < 0)
5447 goto error;
5448 status = QAMResetQAM(state);
5449 if (status < 0)
5450 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005451
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005452 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005453 * STEP 2: configure demodulator
5454 * -set params; resets IQM,QAM,FEC HW; initializes some
5455 * SCU variables
5456 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005457 status = QAMSetSymbolrate(state);
5458 if (status < 0)
5459 goto error;
5460
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005461 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005462 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005463 case QAM_256:
5464 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5465 break;
5466 case QAM_AUTO:
5467 case QAM_64:
5468 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5469 break;
5470 case QAM_16:
5471 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5472 break;
5473 case QAM_32:
5474 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5475 break;
5476 case QAM_128:
5477 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5478 break;
5479 default:
5480 status = -EINVAL;
5481 break;
5482 }
5483 if (status < 0)
5484 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005485
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005486 /* Use the 4-parameter if it's requested or we're probing for
5487 * the correct command. */
5488 if (state->qam_demod_parameter_count == 4
5489 || !state->qam_demod_parameter_count) {
5490 qamDemodParamCount = 4;
5491 status = QAMDemodulatorCommand(state, qamDemodParamCount);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005492 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005493
5494 /* Use the 2-parameter command if it was requested or if we're
5495 * probing for the correct command and the 4-parameter command
5496 * failed. */
5497 if (state->qam_demod_parameter_count == 2
5498 || (!state->qam_demod_parameter_count && status < 0)) {
5499 qamDemodParamCount = 2;
5500 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5501 }
5502
5503 if (status < 0) {
5504 dprintk(1, "Could not set demodulator parameters. Make "
5505 "sure qam_demod_parameter_count (%d) is correct for "
5506 "your firmware (%s).\n",
5507 state->qam_demod_parameter_count,
5508 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005509 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005510 } else if (!state->qam_demod_parameter_count) {
5511 dprintk(1, "Auto-probing the correct QAM demodulator command "
5512 "parameters was successful - using %d parameters.\n",
5513 qamDemodParamCount);
5514
Mauro Carvalho Chehab7eaf71882012-07-06 14:53:51 -03005515 /*
5516 * One of our commands was successful. We don't need to
5517 * auto-probe anymore, now that we got the correct command.
5518 */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005519 state->qam_demod_parameter_count = qamDemodParamCount;
5520 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005521
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005522 /*
5523 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005524 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005525 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005526#if 0
5527 status = SetFrequency(channel, tunerFreqOffset));
5528 if (status < 0)
5529 goto error;
5530#endif
5531 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5532 if (status < 0)
5533 goto error;
5534
5535 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005536 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005537 if (status < 0)
5538 goto error;
5539
5540 /* Reset default values */
5541 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5542 if (status < 0)
5543 goto error;
5544 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5545 if (status < 0)
5546 goto error;
5547
5548 /* Reset default LC values */
5549 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5550 if (status < 0)
5551 goto error;
5552 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5553 if (status < 0)
5554 goto error;
5555 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5556 if (status < 0)
5557 goto error;
5558 status = write16(state, QAM_LC_MODE__A, 7);
5559 if (status < 0)
5560 goto error;
5561
5562 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5563 if (status < 0)
5564 goto error;
5565 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5566 if (status < 0)
5567 goto error;
5568 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5569 if (status < 0)
5570 goto error;
5571 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5572 if (status < 0)
5573 goto error;
5574 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5575 if (status < 0)
5576 goto error;
5577 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5578 if (status < 0)
5579 goto error;
5580 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5581 if (status < 0)
5582 goto error;
5583 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5584 if (status < 0)
5585 goto error;
5586 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5587 if (status < 0)
5588 goto error;
5589 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5590 if (status < 0)
5591 goto error;
5592 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5593 if (status < 0)
5594 goto error;
5595 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5596 if (status < 0)
5597 goto error;
5598 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5599 if (status < 0)
5600 goto error;
5601 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5602 if (status < 0)
5603 goto error;
5604 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5605 if (status < 0)
5606 goto error;
5607
5608 /* Mirroring, QAM-block starting point not inverted */
5609 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5610 if (status < 0)
5611 goto error;
5612
5613 /* Halt SCU to enable safe non-atomic accesses */
5614 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5615 if (status < 0)
5616 goto error;
5617
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005618 /* STEP 4: modulation specific setup */
5619 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005620 case QAM_16:
5621 status = SetQAM16(state);
5622 break;
5623 case QAM_32:
5624 status = SetQAM32(state);
5625 break;
5626 case QAM_AUTO:
5627 case QAM_64:
5628 status = SetQAM64(state);
5629 break;
5630 case QAM_128:
5631 status = SetQAM128(state);
5632 break;
5633 case QAM_256:
5634 status = SetQAM256(state);
5635 break;
5636 default:
5637 status = -EINVAL;
5638 break;
5639 }
5640 if (status < 0)
5641 goto error;
5642
5643 /* Activate SCU to enable SCU commands */
5644 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5645 if (status < 0)
5646 goto error;
5647
5648 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005649 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005650 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5651 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5652 if (status < 0)
5653 goto error;
5654
5655 /* Start processes */
5656 status = MPEGTSStart(state);
5657 if (status < 0)
5658 goto error;
5659 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5660 if (status < 0)
5661 goto error;
5662 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5663 if (status < 0)
5664 goto error;
5665 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5666 if (status < 0)
5667 goto error;
5668
5669 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5670 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5671 if (status < 0)
5672 goto error;
5673
5674 /* update global DRXK data container */
5675/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5676
5677error:
5678 if (status < 0)
5679 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005680 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005681}
5682
Oliver Endrissebc7de22011-07-03 13:49:44 -03005683static int SetQAMStandard(struct drxk_state *state,
5684 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005685{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005686 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005687#ifdef DRXK_QAM_TAPS
5688#define DRXK_QAMA_TAPS_SELECT
5689#include "drxk_filters.h"
5690#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005691#endif
5692
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005693 dprintk(1, "\n");
5694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005695 /* added antenna switch */
5696 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005697
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005698 /* Ensure correct power-up mode */
5699 status = PowerUpQAM(state);
5700 if (status < 0)
5701 goto error;
5702 /* Reset QAM block */
5703 status = QAMResetQAM(state);
5704 if (status < 0)
5705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005707 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005708
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005709 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5710 if (status < 0)
5711 goto error;
5712 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5713 if (status < 0)
5714 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005715
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005716 /* Upload IQM Channel Filter settings by
5717 boot loader from ROM table */
5718 switch (oMode) {
5719 case OM_QAM_ITU_A:
5720 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5721 break;
5722 case OM_QAM_ITU_C:
5723 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 -03005724 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005725 goto error;
5726 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5727 break;
5728 default:
5729 status = -EINVAL;
5730 }
5731 if (status < 0)
5732 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005733
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005734 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5735 if (status < 0)
5736 goto error;
5737 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5738 if (status < 0)
5739 goto error;
5740 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5741 if (status < 0)
5742 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005744 status = write16(state, IQM_RC_STRETCH__A, 21);
5745 if (status < 0)
5746 goto error;
5747 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5748 if (status < 0)
5749 goto error;
5750 status = write16(state, IQM_AF_CLP_TH__A, 448);
5751 if (status < 0)
5752 goto error;
5753 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5754 if (status < 0)
5755 goto error;
5756 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5757 if (status < 0)
5758 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005759
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005760 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5761 if (status < 0)
5762 goto error;
5763 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5764 if (status < 0)
5765 goto error;
5766 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5767 if (status < 0)
5768 goto error;
5769 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5770 if (status < 0)
5771 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005772
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005773 /* IQM Impulse Noise Processing Unit */
5774 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5775 if (status < 0)
5776 goto error;
5777 status = write16(state, IQM_CF_DATATH__A, 1000);
5778 if (status < 0)
5779 goto error;
5780 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5781 if (status < 0)
5782 goto error;
5783 status = write16(state, IQM_CF_DET_LCT__A, 0);
5784 if (status < 0)
5785 goto error;
5786 status = write16(state, IQM_CF_WND_LEN__A, 1);
5787 if (status < 0)
5788 goto error;
5789 status = write16(state, IQM_CF_PKDTH__A, 1);
5790 if (status < 0)
5791 goto error;
5792 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5793 if (status < 0)
5794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005796 /* turn on IQMAF. Must be done before setAgc**() */
5797 status = SetIqmAf(state, true);
5798 if (status < 0)
5799 goto error;
5800 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5801 if (status < 0)
5802 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005804 /* IQM will not be reset from here, sync ADC and update/init AGC */
5805 status = ADCSynchronization(state);
5806 if (status < 0)
5807 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005809 /* Set the FSM step period */
5810 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5811 if (status < 0)
5812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005814 /* Halt SCU to enable safe non-atomic accesses */
5815 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5816 if (status < 0)
5817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005819 /* No more resets of the IQM, current standard correctly set =>
5820 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005822 status = InitAGC(state, true);
5823 if (status < 0)
5824 goto error;
5825 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5826 if (status < 0)
5827 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005829 /* Configure AGC's */
5830 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5831 if (status < 0)
5832 goto error;
5833 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5834 if (status < 0)
5835 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005836
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005837 /* Activate SCU to enable SCU commands */
5838 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5839error:
5840 if (status < 0)
5841 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005842 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005843}
5844
5845static int WriteGPIO(struct drxk_state *state)
5846{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005847 int status;
5848 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005849
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005850 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005851 /* stop lock indicator process */
5852 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5853 if (status < 0)
5854 goto error;
5855
5856 /* Write magic word to enable pdr reg write */
5857 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5858 if (status < 0)
5859 goto error;
5860
5861 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005862 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5863 /* write to io pad configuration register - output mode */
5864 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5865 if (status < 0)
5866 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005867
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005868 /* use corresponding bit in io data output registar */
5869 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5870 if (status < 0)
5871 goto error;
5872 if ((state->m_GPIO & 0x0001) == 0)
5873 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5874 else
5875 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5876 /* write back to io data output register */
5877 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5878 if (status < 0)
5879 goto error;
5880 }
5881 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5882 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005883 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005884 if (status < 0)
5885 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005886
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005887 /* use corresponding bit in io data output registar */
5888 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5889 if (status < 0)
5890 goto error;
5891 if ((state->m_GPIO & 0x0002) == 0)
5892 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5893 else
5894 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5895 /* write back to io data output register */
5896 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5897 if (status < 0)
5898 goto error;
5899 }
5900 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5901 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005902 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005903 if (status < 0)
5904 goto error;
5905
5906 /* use corresponding bit in io data output registar */
5907 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5908 if (status < 0)
5909 goto error;
5910 if ((state->m_GPIO & 0x0004) == 0)
5911 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5912 else
5913 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5914 /* write back to io data output register */
5915 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5916 if (status < 0)
5917 goto error;
5918 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005919 }
5920 /* Write magic word to disable pdr reg write */
5921 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5922error:
5923 if (status < 0)
5924 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005925 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005926}
5927
5928static int SwitchAntennaToQAM(struct drxk_state *state)
5929{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005930 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005931 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005932
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005933 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005934
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005935 if (!state->antenna_gpio)
5936 return 0;
5937
5938 gpio_state = state->m_GPIO & state->antenna_gpio;
5939
5940 if (state->antenna_dvbt ^ gpio_state) {
5941 /* Antenna is on DVB-T mode. Switch */
5942 if (state->antenna_dvbt)
5943 state->m_GPIO &= ~state->antenna_gpio;
5944 else
5945 state->m_GPIO |= state->antenna_gpio;
5946 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005947 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005948 if (status < 0)
5949 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005950 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005951}
5952
5953static int SwitchAntennaToDVBT(struct drxk_state *state)
5954{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005955 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005956 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005957
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005958 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005959
5960 if (!state->antenna_gpio)
5961 return 0;
5962
5963 gpio_state = state->m_GPIO & state->antenna_gpio;
5964
5965 if (!(state->antenna_dvbt ^ gpio_state)) {
5966 /* Antenna is on DVB-C mode. Switch */
5967 if (state->antenna_dvbt)
5968 state->m_GPIO |= state->antenna_gpio;
5969 else
5970 state->m_GPIO &= ~state->antenna_gpio;
5971 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005973 if (status < 0)
5974 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005975 return status;
5976}
5977
5978
5979static int PowerDownDevice(struct drxk_state *state)
5980{
5981 /* Power down to requested mode */
5982 /* Backup some register settings */
5983 /* Set pins with possible pull-ups connected to them in input mode */
5984 /* Analog power down */
5985 /* ADC power down */
5986 /* Power down device */
5987 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005988
5989 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005990 if (state->m_bPDownOpenBridge) {
5991 /* Open I2C bridge before power down of DRXK */
5992 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005993 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005994 goto error;
5995 }
5996 /* driver 0.9.0 */
5997 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005998 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005999 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006000
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006001 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
6002 if (status < 0)
6003 goto error;
6004 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6005 if (status < 0)
6006 goto error;
6007 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6008 status = HI_CfgCommand(state);
6009error:
6010 if (status < 0)
6011 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6012
6013 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006014}
6015
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006016static int init_drxk(struct drxk_state *state)
6017{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006018 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006019 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006020 u16 driverVersion;
6021
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006022 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006023 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006024 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 status = PowerUpDevice(state);
6026 if (status < 0)
6027 goto error;
6028 status = DRXX_Open(state);
6029 if (status < 0)
6030 goto error;
6031 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6032 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);
6033 if (status < 0)
6034 goto error;
6035 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6036 if (status < 0)
6037 goto error;
6038 /* TODO is this needed, if yes how much delay in worst case scenario */
6039 msleep(1);
6040 state->m_DRXK_A3_PATCH_CODE = true;
6041 status = GetDeviceCapabilities(state);
6042 if (status < 0)
6043 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006045 /* Bridge delay, uses oscilator clock */
6046 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6047 /* SDA brdige delay */
6048 state->m_HICfgBridgeDelay =
6049 (u16) ((state->m_oscClockFreq / 1000) *
6050 HI_I2C_BRIDGE_DELAY) / 1000;
6051 /* Clipping */
6052 if (state->m_HICfgBridgeDelay >
6053 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006054 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006055 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6056 }
6057 /* SCL bridge delay, same as SDA for now */
6058 state->m_HICfgBridgeDelay +=
6059 state->m_HICfgBridgeDelay <<
6060 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006062 status = InitHI(state);
6063 if (status < 0)
6064 goto error;
6065 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006066#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006067 if (!(state->m_DRXK_A1_ROM_CODE)
6068 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006069#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006070 {
6071 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6072 if (status < 0)
6073 goto error;
6074 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 /* disable MPEG port */
6077 status = MPEGTSDisable(state);
6078 if (status < 0)
6079 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006081 /* Stop AUD and SCU */
6082 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6083 if (status < 0)
6084 goto error;
6085 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6086 if (status < 0)
6087 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006088
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006089 /* enable token-ring bus through OFDM block for possible ucode upload */
6090 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6091 if (status < 0)
6092 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006093
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006094 /* include boot loader section */
6095 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6096 if (status < 0)
6097 goto error;
6098 status = BLChainCmd(state, 0, 6, 100);
6099 if (status < 0)
6100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006101
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006102 if (state->fw) {
6103 status = DownloadMicrocode(state, state->fw->data,
6104 state->fw->size);
6105 if (status < 0)
6106 goto error;
6107 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006109 /* disable token-ring bus through OFDM block for possible ucode upload */
6110 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6111 if (status < 0)
6112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006114 /* Run SCU for a little while to initialize microcode version numbers */
6115 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6116 if (status < 0)
6117 goto error;
6118 status = DRXX_Open(state);
6119 if (status < 0)
6120 goto error;
6121 /* added for test */
6122 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006124 powerMode = DRXK_POWER_DOWN_OFDM;
6125 status = CtrlPowerMode(state, &powerMode);
6126 if (status < 0)
6127 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006128
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006129 /* Stamp driver version number in SCU data RAM in BCD code
6130 Done to enable field application engineers to retreive drxdriver version
6131 via I2C from SCU RAM.
6132 Not using SCU command interface for SCU register access since no
6133 microcode may be present.
6134 */
6135 driverVersion =
6136 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6137 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6138 ((DRXK_VERSION_MAJOR % 10) << 4) +
6139 (DRXK_VERSION_MINOR % 10);
6140 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6141 if (status < 0)
6142 goto error;
6143 driverVersion =
6144 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6145 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6146 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6147 (DRXK_VERSION_PATCH % 10);
6148 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6149 if (status < 0)
6150 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006151
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006152 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6153 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6154 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006155
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006156 /* Dirty fix of default values for ROM/PATCH microcode
6157 Dirty because this fix makes it impossible to setup suitable values
6158 before calling DRX_Open. This solution requires changes to RF AGC speed
6159 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006160
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006161 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006162
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006163 /* Reset driver debug flags to 0 */
6164 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6165 if (status < 0)
6166 goto error;
6167 /* driver 0.9.0 */
6168 /* Setup FEC OC:
6169 NOTE: No more full FEC resets allowed afterwards!! */
6170 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6171 if (status < 0)
6172 goto error;
6173 /* MPEGTS functions are still the same */
6174 status = MPEGTSDtoInit(state);
6175 if (status < 0)
6176 goto error;
6177 status = MPEGTSStop(state);
6178 if (status < 0)
6179 goto error;
6180 status = MPEGTSConfigurePolarity(state);
6181 if (status < 0)
6182 goto error;
6183 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6184 if (status < 0)
6185 goto error;
6186 /* added: configure GPIO */
6187 status = WriteGPIO(state);
6188 if (status < 0)
6189 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006191 state->m_DrxkState = DRXK_STOPPED;
6192
6193 if (state->m_bPowerDown) {
6194 status = PowerDownDevice(state);
6195 if (status < 0)
6196 goto error;
6197 state->m_DrxkState = DRXK_POWERED_DOWN;
6198 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006199 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006200
6201 /* Initialize the supported delivery systems */
6202 n = 0;
6203 if (state->m_hasDVBC) {
6204 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6205 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6206 strlcat(state->frontend.ops.info.name, " DVB-C",
6207 sizeof(state->frontend.ops.info.name));
6208 }
6209 if (state->m_hasDVBT) {
6210 state->frontend.ops.delsys[n++] = SYS_DVBT;
6211 strlcat(state->frontend.ops.info.name, " DVB-T",
6212 sizeof(state->frontend.ops.info.name));
6213 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006214 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006215 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006216error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006217 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006218 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006219 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006220 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006221 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006222
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006223 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006224}
6225
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006226static void load_firmware_cb(const struct firmware *fw,
6227 void *context)
6228{
6229 struct drxk_state *state = context;
6230
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006231 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006232 if (!fw) {
6233 printk(KERN_ERR
6234 "drxk: Could not load firmware file %s.\n",
6235 state->microcode_name);
6236 printk(KERN_INFO
6237 "drxk: Copy %s to your hotplug directory!\n",
6238 state->microcode_name);
6239 state->microcode_name = NULL;
6240
6241 /*
6242 * As firmware is now load asynchronous, it is not possible
6243 * anymore to fail at frontend attach. We might silently
6244 * return here, and hope that the driver won't crash.
6245 * We might also change all DVB callbacks to return -ENODEV
6246 * if the device is not initialized.
6247 * As the DRX-K devices have their own internal firmware,
6248 * let's just hope that it will match a firmware revision
6249 * compatible with this driver and proceed.
6250 */
6251 }
6252 state->fw = fw;
6253
6254 init_drxk(state);
6255}
6256
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006257static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006258{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006259 struct drxk_state *state = fe->demodulator_priv;
6260
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006261 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006262 if (state->fw)
6263 release_firmware(state->fw);
6264
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006265 kfree(state);
6266}
6267
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006268static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006269{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006270 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006271
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006272 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006273
6274 if (state->m_DrxkState == DRXK_NO_DEV)
6275 return -ENODEV;
6276 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6277 return 0;
6278
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006280 return 0;
6281}
6282
Oliver Endrissebc7de22011-07-03 13:49:44 -03006283static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284{
6285 struct drxk_state *state = fe->demodulator_priv;
6286
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006287 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006288
6289 if (state->m_DrxkState == DRXK_NO_DEV)
6290 return -ENODEV;
6291
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006292 return ConfigureI2CBridge(state, enable ? true : false);
6293}
6294
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006295static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006296{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006297 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006298 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006299 struct drxk_state *state = fe->demodulator_priv;
6300 u32 IF;
6301
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006302 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006303
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006304 if (state->m_DrxkState == DRXK_NO_DEV)
6305 return -ENODEV;
6306
6307 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6308 return -EAGAIN;
6309
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006310 if (!fe->ops.tuner_ops.get_if_frequency) {
6311 printk(KERN_ERR
6312 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6313 return -EINVAL;
6314 }
6315
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006316 if (fe->ops.i2c_gate_ctrl)
6317 fe->ops.i2c_gate_ctrl(fe, 1);
6318 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006319 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006320 if (fe->ops.i2c_gate_ctrl)
6321 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006322
6323 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006324 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006325
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006326 if (old_delsys != delsys) {
6327 ShutDown(state);
6328 switch (delsys) {
6329 case SYS_DVBC_ANNEX_A:
6330 case SYS_DVBC_ANNEX_C:
6331 if (!state->m_hasDVBC)
6332 return -EINVAL;
6333 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6334 if (state->m_itut_annex_c)
6335 SetOperationMode(state, OM_QAM_ITU_C);
6336 else
6337 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006338 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006339 case SYS_DVBT:
6340 if (!state->m_hasDVBT)
6341 return -EINVAL;
6342 SetOperationMode(state, OM_DVBT);
6343 break;
6344 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006345 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006346 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006347 }
6348
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006349 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006350 Start(state, 0, IF);
6351
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006352 /* After set_frontend, stats aren't avaliable */
6353 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6354 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6355 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6356 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6357 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6358 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6359 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6360 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6361
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006362 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006363
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006364 return 0;
6365}
6366
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006367static int get_strength(struct drxk_state *state, u64 *strength)
6368{
6369 int status;
6370 struct SCfgAgc rfAgc, ifAgc;
6371 u32 totalGain = 0;
6372 u32 atten = 0;
6373 u32 agcRange = 0;
6374 u16 scu_lvl = 0;
6375 u16 scu_coc = 0;
6376 /* FIXME: those are part of the tuner presets */
6377 u16 tunerRfGain = 50; /* Default value on az6007 driver */
6378 u16 tunerIfGain = 40; /* Default value on az6007 driver */
6379
6380 *strength = 0;
6381
6382 if (IsDVBT(state)) {
6383 rfAgc = state->m_dvbtRfAgcCfg;
6384 ifAgc = state->m_dvbtIfAgcCfg;
6385 } else if (IsQAM(state)) {
6386 rfAgc = state->m_qamRfAgcCfg;
6387 ifAgc = state->m_qamIfAgcCfg;
6388 } else {
6389 rfAgc = state->m_atvRfAgcCfg;
6390 ifAgc = state->m_atvIfAgcCfg;
6391 }
6392
6393 if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6394 /* SCU outputLevel */
6395 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6396 if (status < 0)
6397 return status;
6398
6399 /* SCU c.o.c. */
6400 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6401 if (status < 0)
6402 return status;
6403
6404 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6405 rfAgc.outputLevel = scu_lvl + scu_coc;
6406 else
6407 rfAgc.outputLevel = 0xffff;
6408
6409 /* Take RF gain into account */
6410 totalGain += tunerRfGain;
6411
6412 /* clip output value */
6413 if (rfAgc.outputLevel < rfAgc.minOutputLevel)
6414 rfAgc.outputLevel = rfAgc.minOutputLevel;
6415 if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
6416 rfAgc.outputLevel = rfAgc.maxOutputLevel;
6417
6418 agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
6419 if (agcRange > 0) {
6420 atten += 100UL *
6421 ((u32)(tunerRfGain)) *
6422 ((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
6423 / agcRange;
6424 }
6425 }
6426
6427 if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6428 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6429 &ifAgc.outputLevel);
6430 if (status < 0)
6431 return status;
6432
6433 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6434 &ifAgc.top);
6435 if (status < 0)
6436 return status;
6437
6438 /* Take IF gain into account */
6439 totalGain += (u32) tunerIfGain;
6440
6441 /* clip output value */
6442 if (ifAgc.outputLevel < ifAgc.minOutputLevel)
6443 ifAgc.outputLevel = ifAgc.minOutputLevel;
6444 if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
6445 ifAgc.outputLevel = ifAgc.maxOutputLevel;
6446
6447 agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
6448 if (agcRange > 0) {
6449 atten += 100UL *
6450 ((u32)(tunerIfGain)) *
6451 ((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
6452 / agcRange;
6453 }
6454 }
6455
6456 /*
6457 * Convert to 0..65535 scale.
6458 * If it can't be measured (AGC is disabled), just show 100%.
6459 */
6460 if (totalGain > 0)
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006461 *strength = (65535UL * atten / totalGain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006462 else
6463 *strength = 65535;
6464
6465 return 0;
6466}
6467
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006468static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006469{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006470 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006471 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006472 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006473 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006474 u16 reg16;
6475 u32 post_bit_count;
6476 u32 post_bit_err_count;
6477 u32 post_bit_error_scale;
6478 u32 pre_bit_err_count;
6479 u32 pre_bit_count;
6480 u32 pkt_count;
6481 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006482 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006483
6484 if (state->m_DrxkState == DRXK_NO_DEV)
6485 return -ENODEV;
6486 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6487 return -EAGAIN;
6488
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006489 /* get status */
6490 state->fe_status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006491 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006492 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006493 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006494 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006495 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006496 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006497 state->fe_status |= 0x07;
6498
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006499 /*
6500 * Estimate signal strength from AGC
6501 */
6502 get_strength(state, &c->strength.stat[0].uvalue);
6503 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6504
6505
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006506 if (stat >= DEMOD_LOCK) {
6507 GetSignalToNoise(state, &cnr);
6508 c->cnr.stat[0].svalue = cnr * 100;
6509 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6510 } else {
6511 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6512 }
6513
6514 if (stat < FEC_LOCK) {
6515 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6516 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6517 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6518 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6519 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6520 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6521 return 0;
6522 }
6523
6524 /* Get post BER */
6525
6526 /* BER measurement is valid if at least FEC lock is achieved */
6527
6528 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6529 to set nr of symbols or bits over which
6530 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6531
6532 /* Read registers for post/preViterbi BER calculation */
6533 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6534 if (status < 0)
6535 goto error;
6536 pre_bit_err_count = reg16;
6537
6538 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6539 if (status < 0)
6540 goto error;
6541 pre_bit_count = reg16;
6542
6543 /* Number of bit-errors */
6544 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6545 if (status < 0)
6546 goto error;
6547 post_bit_err_count = reg16;
6548
6549 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6550 if (status < 0)
6551 goto error;
6552 post_bit_error_scale = reg16;
6553
6554 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6555 if (status < 0)
6556 goto error;
6557 pkt_count = reg16;
6558
6559 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6560 if (status < 0)
6561 goto error;
6562 pkt_error_count = reg16;
6563 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6564
6565 post_bit_err_count *= post_bit_error_scale;
6566
6567 post_bit_count = pkt_count * 204 * 8;
6568
6569 /* Store the results */
6570 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6571 c->block_error.stat[0].uvalue += pkt_error_count;
6572 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6573 c->block_count.stat[0].uvalue += pkt_count;
6574
6575 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6576 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6577 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6578 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6579
6580 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6581 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6582 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6583 c->post_bit_count.stat[0].uvalue += post_bit_count;
6584
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006585error:
6586 return status;
6587}
6588
6589
6590static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6591{
6592 struct drxk_state *state = fe->demodulator_priv;
6593 int rc;
6594
6595 dprintk(1, "\n");
6596
6597 rc = drxk_get_stats(fe);
6598 if (rc < 0)
6599 return rc;
6600
6601 *status = state->fe_status;
6602
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006603 return 0;
6604}
6605
Oliver Endrissebc7de22011-07-03 13:49:44 -03006606static int drxk_read_signal_strength(struct dvb_frontend *fe,
6607 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006608{
6609 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006610 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006611
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006612 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006613
6614 if (state->m_DrxkState == DRXK_NO_DEV)
6615 return -ENODEV;
6616 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6617 return -EAGAIN;
6618
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006619 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006620 return 0;
6621}
6622
6623static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6624{
6625 struct drxk_state *state = fe->demodulator_priv;
6626 s32 snr2;
6627
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006628 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006629
6630 if (state->m_DrxkState == DRXK_NO_DEV)
6631 return -ENODEV;
6632 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6633 return -EAGAIN;
6634
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006635 GetSignalToNoise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006636
6637 /* No negative SNR, clip to zero */
6638 if (snr2 < 0)
6639 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006640 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006641 return 0;
6642}
6643
6644static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6645{
6646 struct drxk_state *state = fe->demodulator_priv;
6647 u16 err;
6648
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006649 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006650
6651 if (state->m_DrxkState == DRXK_NO_DEV)
6652 return -ENODEV;
6653 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6654 return -EAGAIN;
6655
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006656 DVBTQAMGetAccPktErr(state, &err);
6657 *ucblocks = (u32) err;
6658 return 0;
6659}
6660
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006661static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006662 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006663{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006664 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006665 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006666
6667 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006668
6669 if (state->m_DrxkState == DRXK_NO_DEV)
6670 return -ENODEV;
6671 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6672 return -EAGAIN;
6673
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006674 switch (p->delivery_system) {
6675 case SYS_DVBC_ANNEX_A:
6676 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006677 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006678 sets->min_delay_ms = 3000;
6679 sets->max_drift = 0;
6680 sets->step_size = 0;
6681 return 0;
6682 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006683 return -EINVAL;
6684 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006685}
6686
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006687static struct dvb_frontend_ops drxk_ops = {
6688 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006689 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006690 .name = "DRXK",
6691 .frequency_min = 47000000,
6692 .frequency_max = 865000000,
6693 /* For DVB-C */
6694 .symbol_rate_min = 870000,
6695 .symbol_rate_max = 11700000,
6696 /* For DVB-T */
6697 .frequency_stepsize = 166667,
6698
6699 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6700 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6701 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6702 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6703 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6704 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6705 },
6706
6707 .release = drxk_release,
6708 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006709 .i2c_gate_ctrl = drxk_gate_ctrl,
6710
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006711 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006712 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006713
6714 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006715 .read_signal_strength = drxk_read_signal_strength,
6716 .read_snr = drxk_read_snr,
6717 .read_ucblocks = drxk_read_ucblocks,
6718};
6719
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006720struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006721 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006722{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006723 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006724 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006725 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006726 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006727
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006728 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006729 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006730 if (!state)
6731 return NULL;
6732
Oliver Endrissebc7de22011-07-03 13:49:44 -03006733 state->i2c = i2c;
6734 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006735 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006736 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006737 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006738 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006739 state->antenna_gpio = config->antenna_gpio;
6740 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006741 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006742 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006743
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006744 if (config->dynamic_clk) {
6745 state->m_DVBTStaticCLK = 0;
6746 state->m_DVBCStaticCLK = 0;
6747 } else {
6748 state->m_DVBTStaticCLK = 1;
6749 state->m_DVBCStaticCLK = 1;
6750 }
6751
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006752
6753 if (config->mpeg_out_clk_strength)
6754 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6755 else
6756 state->m_TSClockkStrength = 0x06;
6757
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006758 if (config->parallel_ts)
6759 state->m_enableParallel = true;
6760 else
6761 state->m_enableParallel = false;
6762
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006763 /* NOTE: as more UIO bits will be used, add them to the mask */
6764 state->UIO_mask = config->antenna_gpio;
6765
6766 /* Default gpio to DVB-C */
6767 if (!state->antenna_dvbt && state->antenna_gpio)
6768 state->m_GPIO |= state->antenna_gpio;
6769 else
6770 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006771
6772 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006773
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006774 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6775 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006776
6777 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006778
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006779 /* Load firmware and initialize DRX-K */
6780 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006781 if (config->load_firmware_sync) {
6782 const struct firmware *fw = NULL;
6783
6784 status = request_firmware(&fw, state->microcode_name,
6785 state->i2c->dev.parent);
6786 if (status < 0)
6787 fw = NULL;
6788 load_firmware_cb(fw, state);
6789 } else {
6790 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006791 state->microcode_name,
6792 state->i2c->dev.parent,
6793 GFP_KERNEL,
6794 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006795 if (status < 0) {
6796 printk(KERN_ERR
6797 "drxk: failed to request a firmware\n");
6798 return NULL;
6799 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006800 }
6801 } else if (init_drxk(state) < 0)
6802 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006803
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006804
6805 /* Initialize stats */
6806 p = &state->frontend.dtv_property_cache;
6807 p->strength.len = 1;
6808 p->cnr.len = 1;
6809 p->block_error.len = 1;
6810 p->block_count.len = 1;
6811 p->pre_bit_error.len = 1;
6812 p->pre_bit_count.len = 1;
6813 p->post_bit_error.len = 1;
6814 p->post_bit_count.len = 1;
6815
6816 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6817 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6818 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6819 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6820 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6821 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6822 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6823 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6824
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006825 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006826 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006827
6828error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006829 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006830 kfree(state);
6831 return NULL;
6832}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006833EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006834
6835MODULE_DESCRIPTION("DRX-K driver");
6836MODULE_AUTHOR("Ralph Metzler");
6837MODULE_LICENSE("GPL");