blob: 6e250533b6288a62b560432b6217a55c7cd37959 [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
2493static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2494{
2495 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002496 int status;
2497 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002498
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002499 dprintk(1, "\n");
2500
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002501 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2502 if (status < 0) {
2503 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2504 return status;
2505 }
2506
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507 *pValue = 0;
2508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002509 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2510 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2511 if (Level < 14000)
2512 *pValue = (14000 - Level) / 4;
2513 else
2514 *pValue = 0;
2515
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002516 return status;
2517}
2518
Oliver Endrissebc7de22011-07-03 13:49:44 -03002519static int GetQAMSignalToNoise(struct drxk_state *state,
2520 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002521{
2522 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002523 u16 qamSlErrPower = 0; /* accum. error between
2524 raw and sliced symbols */
2525 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002526 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002527 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002528
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002529 dprintk(1, "\n");
2530
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002531 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002532
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002533 /* get the register value needed for MER */
2534 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2535 if (status < 0) {
2536 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2537 return -EINVAL;
2538 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002539
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002540 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002541 case QAM_16:
2542 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2543 break;
2544 case QAM_32:
2545 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2546 break;
2547 case QAM_64:
2548 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2549 break;
2550 case QAM_128:
2551 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2552 break;
2553 default:
2554 case QAM_256:
2555 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2556 break;
2557 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002559 if (qamSlErrPower > 0) {
2560 qamSlMer = Log10Times100(qamSlSigPower) -
2561 Log10Times100((u32) qamSlErrPower);
2562 }
2563 *pSignalToNoise = qamSlMer;
2564
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002565 return status;
2566}
2567
Oliver Endrissebc7de22011-07-03 13:49:44 -03002568static int GetDVBTSignalToNoise(struct drxk_state *state,
2569 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002570{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002571 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002572 u16 regData = 0;
2573 u32 EqRegTdSqrErrI = 0;
2574 u32 EqRegTdSqrErrQ = 0;
2575 u16 EqRegTdSqrErrExp = 0;
2576 u16 EqRegTdTpsPwrOfs = 0;
2577 u16 EqRegTdReqSmbCnt = 0;
2578 u32 tpsCnt = 0;
2579 u32 SqrErrIQ = 0;
2580 u32 a = 0;
2581 u32 b = 0;
2582 u32 c = 0;
2583 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002584 u16 transmissionParams = 0;
2585
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002586 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002587
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002588 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2589 if (status < 0)
2590 goto error;
2591 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2592 if (status < 0)
2593 goto error;
2594 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2595 if (status < 0)
2596 goto error;
2597 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2598 if (status < 0)
2599 goto error;
2600 /* Extend SQR_ERR_I operational range */
2601 EqRegTdSqrErrI = (u32) regData;
2602 if ((EqRegTdSqrErrExp > 11) &&
2603 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2604 EqRegTdSqrErrI += 0x00010000UL;
2605 }
2606 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2607 if (status < 0)
2608 goto error;
2609 /* Extend SQR_ERR_Q operational range */
2610 EqRegTdSqrErrQ = (u32) regData;
2611 if ((EqRegTdSqrErrExp > 11) &&
2612 (EqRegTdSqrErrQ < 0x00000FFFUL))
2613 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002614
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002615 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2616 if (status < 0)
2617 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002618
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002619 /* Check input data for MER */
2620
2621 /* MER calculation (in 0.1 dB) without math.h */
2622 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2623 iMER = 0;
2624 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2625 /* No error at all, this must be the HW reset value
2626 * Apparently no first measurement yet
2627 * Set MER to 0.0 */
2628 iMER = 0;
2629 } else {
2630 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2631 EqRegTdSqrErrExp;
2632 if ((transmissionParams &
2633 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2634 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2635 tpsCnt = 17;
2636 else
2637 tpsCnt = 68;
2638
2639 /* IMER = 100 * log10 (x)
2640 where x = (EqRegTdTpsPwrOfs^2 *
2641 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2642
2643 => IMER = a + b -c
2644 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2645 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2646 c = 100 * log10 (SqrErrIQ)
2647 */
2648
2649 /* log(x) x = 9bits * 9bits->18 bits */
2650 a = Log10Times100(EqRegTdTpsPwrOfs *
2651 EqRegTdTpsPwrOfs);
2652 /* log(x) x = 16bits * 7bits->23 bits */
2653 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2654 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2655 c = Log10Times100(SqrErrIQ);
2656
2657 iMER = a + b;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002658 }
2659 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002661error:
2662 if (status < 0)
2663 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002664 return status;
2665}
2666
2667static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2668{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002669 dprintk(1, "\n");
2670
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002671 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002672 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002673 case OM_DVBT:
2674 return GetDVBTSignalToNoise(state, pSignalToNoise);
2675 case OM_QAM_ITU_A:
2676 case OM_QAM_ITU_C:
2677 return GetQAMSignalToNoise(state, pSignalToNoise);
2678 default:
2679 break;
2680 }
2681 return 0;
2682}
2683
2684#if 0
2685static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2686{
2687 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2688 int status = 0;
2689
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002690 dprintk(1, "\n");
2691
Oliver Endrissebc7de22011-07-03 13:49:44 -03002692 static s32 QE_SN[] = {
2693 51, /* QPSK 1/2 */
2694 69, /* QPSK 2/3 */
2695 79, /* QPSK 3/4 */
2696 89, /* QPSK 5/6 */
2697 97, /* QPSK 7/8 */
2698 108, /* 16-QAM 1/2 */
2699 131, /* 16-QAM 2/3 */
2700 146, /* 16-QAM 3/4 */
2701 156, /* 16-QAM 5/6 */
2702 160, /* 16-QAM 7/8 */
2703 165, /* 64-QAM 1/2 */
2704 187, /* 64-QAM 2/3 */
2705 202, /* 64-QAM 3/4 */
2706 216, /* 64-QAM 5/6 */
2707 225, /* 64-QAM 7/8 */
2708 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002709
2710 *pQuality = 0;
2711
2712 do {
2713 s32 SignalToNoise = 0;
2714 u16 Constellation = 0;
2715 u16 CodeRate = 0;
2716 u32 SignalToNoiseRel;
2717 u32 BERQuality;
2718
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002719 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2720 if (status < 0)
2721 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002722 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002723 if (status < 0)
2724 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2726
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002727 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002728 if (status < 0)
2729 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2731
2732 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2733 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2734 break;
2735 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002736 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002737 BERQuality = 100;
2738
Oliver Endrissebc7de22011-07-03 13:49:44 -03002739 if (SignalToNoiseRel < -70)
2740 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002741 else if (SignalToNoiseRel < 30)
2742 *pQuality = ((SignalToNoiseRel + 70) *
2743 BERQuality) / 100;
2744 else
2745 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002746 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002747 return 0;
2748};
2749
Oliver Endrissebc7de22011-07-03 13:49:44 -03002750static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751{
2752 int status = 0;
2753 *pQuality = 0;
2754
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002755 dprintk(1, "\n");
2756
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757 do {
2758 u32 SignalToNoise = 0;
2759 u32 BERQuality = 100;
2760 u32 SignalToNoiseRel = 0;
2761
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002762 status = GetQAMSignalToNoise(state, &SignalToNoise);
2763 if (status < 0)
2764 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002765
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002766 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767 case QAM_16:
2768 SignalToNoiseRel = SignalToNoise - 200;
2769 break;
2770 case QAM_32:
2771 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002772 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002773 case QAM_64:
2774 SignalToNoiseRel = SignalToNoise - 260;
2775 break;
2776 case QAM_128:
2777 SignalToNoiseRel = SignalToNoise - 290;
2778 break;
2779 default:
2780 case QAM_256:
2781 SignalToNoiseRel = SignalToNoise - 320;
2782 break;
2783 }
2784
2785 if (SignalToNoiseRel < -70)
2786 *pQuality = 0;
2787 else if (SignalToNoiseRel < 30)
2788 *pQuality = ((SignalToNoiseRel + 70) *
2789 BERQuality) / 100;
2790 else
2791 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793
2794 return status;
2795}
2796
2797static int GetQuality(struct drxk_state *state, s32 *pQuality)
2798{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002799 dprintk(1, "\n");
2800
Oliver Endrissebc7de22011-07-03 13:49:44 -03002801 switch (state->m_OperationMode) {
2802 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002803 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002804 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002805 return GetDVBCQuality(state, pQuality);
2806 default:
2807 break;
2808 }
2809
2810 return 0;
2811}
2812#endif
2813
2814/* Free data ram in SIO HI */
2815#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2816#define SIO_HI_RA_RAM_USR_END__A 0x420060
2817
2818#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2819#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2820#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2821#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2822
2823#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2824#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2825#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2826
2827static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2828{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002829 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002831 dprintk(1, "\n");
2832
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002833 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002834 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002835 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002836 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002837
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002838 if (state->no_i2c_bridge)
2839 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002841 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2842 if (status < 0)
2843 goto error;
2844 if (bEnableBridge) {
2845 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 -03002846 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002847 goto error;
2848 } else {
2849 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2850 if (status < 0)
2851 goto error;
2852 }
2853
2854 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2855
2856error:
2857 if (status < 0)
2858 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002859 return status;
2860}
2861
Oliver Endrissebc7de22011-07-03 13:49:44 -03002862static int SetPreSaw(struct drxk_state *state,
2863 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002865 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002866
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002867 dprintk(1, "\n");
2868
Oliver Endrissebc7de22011-07-03 13:49:44 -03002869 if ((pPreSawCfg == NULL)
2870 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002871 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002872
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002873 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002874error:
2875 if (status < 0)
2876 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002877 return status;
2878}
2879
2880static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002881 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002882{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002883 u16 blStatus = 0;
2884 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2885 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2886 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002887 unsigned long end;
2888
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002889 dprintk(1, "\n");
2890
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002891 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002892 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2893 if (status < 0)
2894 goto error;
2895 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2896 if (status < 0)
2897 goto error;
2898 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2899 if (status < 0)
2900 goto error;
2901 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2902 if (status < 0)
2903 goto error;
2904 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2905 if (status < 0)
2906 goto error;
2907 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2908 if (status < 0)
2909 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002911 end = jiffies + msecs_to_jiffies(timeOut);
2912 do {
2913 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2914 if (status < 0)
2915 goto error;
2916 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2917 if (blStatus == 0x1) {
2918 printk(KERN_ERR "drxk: SIO not ready\n");
2919 status = -EINVAL;
2920 goto error2;
2921 }
2922error:
2923 if (status < 0)
2924 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2925error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002926 mutex_unlock(&state->mutex);
2927 return status;
2928
2929}
2930
Oliver Endrissebc7de22011-07-03 13:49:44 -03002931static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932{
2933 u16 data = 0;
2934 int status;
2935
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002936 dprintk(1, "\n");
2937
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002938 /* Start measurement */
2939 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2940 if (status < 0)
2941 goto error;
2942 status = write16(state, IQM_AF_START_LOCK__A, 1);
2943 if (status < 0)
2944 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002945
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002946 *count = 0;
2947 status = read16(state, IQM_AF_PHASE0__A, &data);
2948 if (status < 0)
2949 goto error;
2950 if (data == 127)
2951 *count = *count + 1;
2952 status = read16(state, IQM_AF_PHASE1__A, &data);
2953 if (status < 0)
2954 goto error;
2955 if (data == 127)
2956 *count = *count + 1;
2957 status = read16(state, IQM_AF_PHASE2__A, &data);
2958 if (status < 0)
2959 goto error;
2960 if (data == 127)
2961 *count = *count + 1;
2962
2963error:
2964 if (status < 0)
2965 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002966 return status;
2967}
2968
2969static int ADCSynchronization(struct drxk_state *state)
2970{
2971 u16 count = 0;
2972 int status;
2973
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002974 dprintk(1, "\n");
2975
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002976 status = ADCSyncMeasurement(state, &count);
2977 if (status < 0)
2978 goto error;
2979
2980 if (count == 1) {
2981 /* Try sampling on a diffrent edge */
2982 u16 clkNeg = 0;
2983
2984 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2985 if (status < 0)
2986 goto error;
Dan Carpenter22a09b42012-06-26 04:40:38 -03002987 if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002988 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2989 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2990 clkNeg |=
2991 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2992 } else {
2993 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2994 clkNeg |=
2995 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2996 }
2997 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2998 if (status < 0)
2999 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003000 status = ADCSyncMeasurement(state, &count);
3001 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003002 goto error;
3003 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003005 if (count < 2)
3006 status = -EINVAL;
3007error:
3008 if (status < 0)
3009 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003010 return status;
3011}
3012
3013static int SetFrequencyShifter(struct drxk_state *state,
3014 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003015 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003016{
3017 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003018 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019 u32 fmFrequencyShift = 0;
3020 bool tunerMirror = !state->m_bMirrorFreqSpect;
3021 u32 adcFreq;
3022 bool adcFlip;
3023 int status;
3024 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003025 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003026 u32 frequencyShift;
3027 bool imageToSelect;
3028
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003029 dprintk(1, "\n");
3030
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003032 Program frequency shifter
3033 No need to account for mirroring on RF
3034 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003035 if (isDTV) {
3036 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3037 (state->m_OperationMode == OM_QAM_ITU_C) ||
3038 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003039 selectPosImage = true;
3040 else
3041 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003042 }
3043 if (tunerMirror)
3044 /* tuner doesn't mirror */
3045 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003046 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003047 else
3048 /* tuner mirrors */
3049 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003050 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051 if (ifFreqActual > samplingFrequency / 2) {
3052 /* adc mirrors */
3053 adcFreq = samplingFrequency - ifFreqActual;
3054 adcFlip = true;
3055 } else {
3056 /* adc doesn't mirror */
3057 adcFreq = ifFreqActual;
3058 adcFlip = false;
3059 }
3060
3061 frequencyShift = adcFreq;
3062 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003063 adcFlip ^ selectPosImage;
3064 state->m_IqmFsRateOfs =
3065 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066
3067 if (imageToSelect)
3068 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3069
3070 /* Program frequency shifter with tuner offset compensation */
3071 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003072 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3073 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003074 if (status < 0)
3075 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003076 return status;
3077}
3078
3079static int InitAGC(struct drxk_state *state, bool isDTV)
3080{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003081 u16 ingainTgt = 0;
3082 u16 ingainTgtMin = 0;
3083 u16 ingainTgtMax = 0;
3084 u16 clpCyclen = 0;
3085 u16 clpSumMin = 0;
3086 u16 clpDirTo = 0;
3087 u16 snsSumMin = 0;
3088 u16 snsSumMax = 0;
3089 u16 clpSumMax = 0;
3090 u16 snsDirTo = 0;
3091 u16 kiInnergainMin = 0;
3092 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003093 u16 ifIaccuHiTgtMin = 0;
3094 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003095 u16 data = 0;
3096 u16 fastClpCtrlDelay = 0;
3097 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003098 int status = 0;
3099
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003100 dprintk(1, "\n");
3101
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003102 /* Common settings */
3103 snsSumMax = 1023;
3104 ifIaccuHiTgtMin = 2047;
3105 clpCyclen = 500;
3106 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003107
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003108 /* AGCInit() not available for DVBT; init done in microcode */
3109 if (!IsQAM(state)) {
3110 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3111 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003112 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003113
3114 /* FIXME: Analog TV AGC require different settings */
3115
3116 /* Standard specific settings */
3117 clpSumMin = 8;
3118 clpDirTo = (u16) -9;
3119 clpCtrlMode = 0;
3120 snsSumMin = 8;
3121 snsDirTo = (u16) -9;
3122 kiInnergainMin = (u16) -1030;
3123 ifIaccuHiTgtMax = 0x2380;
3124 ifIaccuHiTgt = 0x2380;
3125 ingainTgtMin = 0x0511;
3126 ingainTgt = 0x0511;
3127 ingainTgtMax = 5119;
3128 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003130 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3131 if (status < 0)
3132 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003134 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3153 if (status < 0)
3154 goto error;
3155 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3156 if (status < 0)
3157 goto error;
3158 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3159 if (status < 0)
3160 goto error;
3161 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3162 if (status < 0)
3163 goto error;
3164 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3165 if (status < 0)
3166 goto error;
3167 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3168 if (status < 0)
3169 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003170
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003171 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3172 if (status < 0)
3173 goto error;
3174 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3175 if (status < 0)
3176 goto error;
3177 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3178 if (status < 0)
3179 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003180
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003181 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3188 if (status < 0)
3189 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003190
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003191 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3231 if (status < 0)
3232 goto error;
3233 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3234 if (status < 0)
3235 goto error;
3236 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3237 if (status < 0)
3238 goto error;
3239 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3240 if (status < 0)
3241 goto error;
3242 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3243 if (status < 0)
3244 goto error;
3245 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3246 if (status < 0)
3247 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003249 /* Initialize inner-loop KI gain factors */
3250 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3251 if (status < 0)
3252 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003253
3254 data = 0x0657;
3255 data &= ~SCU_RAM_AGC_KI_RF__M;
3256 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3257 data &= ~SCU_RAM_AGC_KI_IF__M;
3258 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3259
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003260 status = write16(state, SCU_RAM_AGC_KI__A, data);
3261error:
3262 if (status < 0)
3263 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003264 return status;
3265}
3266
Oliver Endrissebc7de22011-07-03 13:49:44 -03003267static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268{
3269 int status;
3270
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003271 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003272 if (packetErr == NULL)
3273 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3274 else
3275 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3276 if (status < 0)
3277 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 return status;
3279}
3280
3281static int DVBTScCommand(struct drxk_state *state,
3282 u16 cmd, u16 subcmd,
3283 u16 param0, u16 param1, u16 param2,
3284 u16 param3, u16 param4)
3285{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003286 u16 curCmd = 0;
3287 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003289 u16 scExec = 0;
3290 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003292 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003293 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 if (scExec != 1) {
3295 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003296 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003297 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003298 if (status < 0)
3299 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300
3301 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003302 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 do {
3304 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003305 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003306 retryCnt++;
3307 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003308 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3309 goto error;
3310
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311 /* Write sub-command */
3312 switch (cmd) {
3313 /* All commands using sub-cmd */
3314 case OFDM_SC_RA_RAM_CMD_PROC_START:
3315 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3316 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003317 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3318 if (status < 0)
3319 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003320 break;
3321 default:
3322 /* Do nothing */
3323 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003324 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325
3326 /* Write needed parameters and the command */
3327 switch (cmd) {
3328 /* All commands using 5 parameters */
3329 /* All commands using 4 parameters */
3330 /* All commands using 3 parameters */
3331 /* All commands using 2 parameters */
3332 case OFDM_SC_RA_RAM_CMD_PROC_START:
3333 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3334 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003335 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336 /* All commands using 1 parameters */
3337 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3338 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003339 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 /* All commands using 0 parameters */
3341 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3342 case OFDM_SC_RA_RAM_CMD_NULL:
3343 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003344 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 break;
3346 default:
3347 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003348 status = -EINVAL;
3349 }
3350 if (status < 0)
3351 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352
3353 /* Wait until sc is ready processing command */
3354 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003355 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003357 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003358 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003359 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003360 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3361 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003362
3363 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003364 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003365 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003367 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003368 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003369 if (status < 0)
3370 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371
3372 /* Retreive results parameters from SC */
3373 switch (cmd) {
3374 /* All commands yielding 5 results */
3375 /* All commands yielding 4 results */
3376 /* All commands yielding 3 results */
3377 /* All commands yielding 2 results */
3378 /* All commands yielding 1 result */
3379 case OFDM_SC_RA_RAM_CMD_USER_IO:
3380 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 /* All commands yielding 0 results */
3383 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3384 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3385 case OFDM_SC_RA_RAM_CMD_PROC_START:
3386 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3387 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3388 case OFDM_SC_RA_RAM_CMD_NULL:
3389 break;
3390 default:
3391 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003392 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003394 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003395error:
3396 if (status < 0)
3397 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 return status;
3399}
3400
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003404 int status;
3405
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003406 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003407 status = CtrlPowerMode(state, &powerMode);
3408 if (status < 0)
3409 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003410 return status;
3411}
3412
Oliver Endrissebc7de22011-07-03 13:49:44 -03003413static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003414{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003415 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003417 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003418 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003419 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003420 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003421 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003422 if (status < 0)
3423 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003424 return status;
3425}
3426
3427#define DEFAULT_FR_THRES_8K 4000
3428static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3429{
3430
3431 int status;
3432
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003433 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003434 if (*enabled == true) {
3435 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003436 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003437 DEFAULT_FR_THRES_8K);
3438 } else {
3439 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003440 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003441 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003442 if (status < 0)
3443 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003444
3445 return status;
3446}
3447
3448static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3449 struct DRXKCfgDvbtEchoThres_t *echoThres)
3450{
3451 u16 data = 0;
3452 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003453
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003454 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003455 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3456 if (status < 0)
3457 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003458
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 switch (echoThres->fftMode) {
3460 case DRX_FFTMODE_2K:
3461 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3462 data |= ((echoThres->threshold <<
3463 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3464 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003465 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003466 case DRX_FFTMODE_8K:
3467 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3468 data |= ((echoThres->threshold <<
3469 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3470 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003471 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003472 default:
3473 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003474 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003475
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003476 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3477error:
3478 if (status < 0)
3479 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003480 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481}
3482
3483static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003484 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003485{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003486 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003487
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003488 dprintk(1, "\n");
3489
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490 switch (*speed) {
3491 case DRXK_DVBT_SQI_SPEED_FAST:
3492 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3493 case DRXK_DVBT_SQI_SPEED_SLOW:
3494 break;
3495 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003496 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003497 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003498 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003499 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003500error:
3501 if (status < 0)
3502 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003503 return status;
3504}
3505
3506/*============================================================================*/
3507
3508/**
3509* \brief Activate DVBT specific presets
3510* \param demod instance of demodulator.
3511* \return DRXStatus_t.
3512*
3513* Called in DVBTSetStandard
3514*
3515*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003516static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003518 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003519 bool setincenable = false;
3520 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003521
Oliver Endrissebc7de22011-07-03 13:49:44 -03003522 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3523 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003524
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003525 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003526 status = DVBTCtrlSetIncEnable(state, &setincenable);
3527 if (status < 0)
3528 goto error;
3529 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3530 if (status < 0)
3531 goto error;
3532 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3533 if (status < 0)
3534 goto error;
3535 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3536 if (status < 0)
3537 goto error;
3538 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3539error:
3540 if (status < 0)
3541 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003542 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003543}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003544
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003545/*============================================================================*/
3546
3547/**
3548* \brief Initialize channelswitch-independent settings for DVBT.
3549* \param demod instance of demodulator.
3550* \return DRXStatus_t.
3551*
3552* For ROM code channel filter taps are loaded from the bootloader. For microcode
3553* the DVB-T taps from the drxk_filters.h are used.
3554*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003555static int SetDVBTStandard(struct drxk_state *state,
3556 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003557{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003558 u16 cmdResult = 0;
3559 u16 data = 0;
3560 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003561
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003562 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003563
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003564 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003565 /* added antenna switch */
3566 SwitchAntennaToDVBT(state);
3567 /* send OFDM reset command */
3568 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 -03003569 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003570 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003571
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003572 /* send OFDM setenv command */
3573 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3574 if (status < 0)
3575 goto error;
3576
3577 /* reset datapath for OFDM, processors first */
3578 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3579 if (status < 0)
3580 goto error;
3581 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3582 if (status < 0)
3583 goto error;
3584 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3585 if (status < 0)
3586 goto error;
3587
3588 /* IQM setup */
3589 /* synchronize on ofdstate->m_festart */
3590 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3591 if (status < 0)
3592 goto error;
3593 /* window size for clipping ADC detection */
3594 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3595 if (status < 0)
3596 goto error;
3597 /* window size for for sense pre-SAW detection */
3598 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3599 if (status < 0)
3600 goto error;
3601 /* sense threshold for sense pre-SAW detection */
3602 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3603 if (status < 0)
3604 goto error;
3605 status = SetIqmAf(state, true);
3606 if (status < 0)
3607 goto error;
3608
3609 status = write16(state, IQM_AF_AGC_RF__A, 0);
3610 if (status < 0)
3611 goto error;
3612
3613 /* Impulse noise cruncher setup */
3614 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3615 if (status < 0)
3616 goto error;
3617 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3618 if (status < 0)
3619 goto error;
3620 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3621 if (status < 0)
3622 goto error;
3623
3624 status = write16(state, IQM_RC_STRETCH__A, 16);
3625 if (status < 0)
3626 goto error;
3627 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3628 if (status < 0)
3629 goto error;
3630 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3631 if (status < 0)
3632 goto error;
3633 status = write16(state, IQM_CF_SCALE__A, 1600);
3634 if (status < 0)
3635 goto error;
3636 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3637 if (status < 0)
3638 goto error;
3639
3640 /* virtual clipping threshold for clipping ADC detection */
3641 status = write16(state, IQM_AF_CLP_TH__A, 448);
3642 if (status < 0)
3643 goto error;
3644 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3645 if (status < 0)
3646 goto error;
3647
3648 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3649 if (status < 0)
3650 goto error;
3651
3652 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3653 if (status < 0)
3654 goto error;
3655 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3656 if (status < 0)
3657 goto error;
3658 /* enable power measurement interrupt */
3659 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3660 if (status < 0)
3661 goto error;
3662 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3663 if (status < 0)
3664 goto error;
3665
3666 /* IQM will not be reset from here, sync ADC and update/init AGC */
3667 status = ADCSynchronization(state);
3668 if (status < 0)
3669 goto error;
3670 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3671 if (status < 0)
3672 goto error;
3673
3674 /* Halt SCU to enable safe non-atomic accesses */
3675 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3676 if (status < 0)
3677 goto error;
3678
3679 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3680 if (status < 0)
3681 goto error;
3682 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3683 if (status < 0)
3684 goto error;
3685
3686 /* Set Noise Estimation notch width and enable DC fix */
3687 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3688 if (status < 0)
3689 goto error;
3690 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3691 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3692 if (status < 0)
3693 goto error;
3694
3695 /* Activate SCU to enable SCU commands */
3696 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3697 if (status < 0)
3698 goto error;
3699
3700 if (!state->m_DRXK_A3_ROM_CODE) {
3701 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3702 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3703 if (status < 0)
3704 goto error;
3705 }
3706
3707 /* OFDM_SC setup */
3708#ifdef COMPILE_FOR_NONRT
3709 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3710 if (status < 0)
3711 goto error;
3712 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3713 if (status < 0)
3714 goto error;
3715#endif
3716
3717 /* FEC setup */
3718 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3719 if (status < 0)
3720 goto error;
3721
3722
3723#ifdef COMPILE_FOR_NONRT
3724 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3725 if (status < 0)
3726 goto error;
3727#else
3728 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3729 if (status < 0)
3730 goto error;
3731#endif
3732 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3733 if (status < 0)
3734 goto error;
3735
3736 /* Setup MPEG bus */
3737 status = MPEGTSDtoSetup(state, OM_DVBT);
3738 if (status < 0)
3739 goto error;
3740 /* Set DVBT Presets */
3741 status = DVBTActivatePresets(state);
3742 if (status < 0)
3743 goto error;
3744
3745error:
3746 if (status < 0)
3747 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003748 return status;
3749}
3750
3751/*============================================================================*/
3752/**
3753* \brief Start dvbt demodulating for channel.
3754* \param demod instance of demodulator.
3755* \return DRXStatus_t.
3756*/
3757static int DVBTStart(struct drxk_state *state)
3758{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003759 u16 param1;
3760 int status;
3761 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003762
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003763 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003764 /* Start correct processes to get in lock */
3765 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003766 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3767 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3768 if (status < 0)
3769 goto error;
3770 /* Start FEC OC */
3771 status = MPEGTSStart(state);
3772 if (status < 0)
3773 goto error;
3774 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3775 if (status < 0)
3776 goto error;
3777error:
3778 if (status < 0)
3779 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003780 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003781}
3782
3783
3784/*============================================================================*/
3785
3786/**
3787* \brief Set up dvbt demodulator for channel.
3788* \param demod instance of demodulator.
3789* \return DRXStatus_t.
3790* // original DVBTSetChannel()
3791*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003792static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3793 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003794{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003795 u16 cmdResult = 0;
3796 u16 transmissionParams = 0;
3797 u16 operationMode = 0;
3798 u32 iqmRcRateOfs = 0;
3799 u32 bandwidth = 0;
3800 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801 int status;
3802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003803 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003805 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3806 if (status < 0)
3807 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003809 /* Halt SCU to enable safe non-atomic accesses */
3810 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3811 if (status < 0)
3812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003814 /* Stop processors */
3815 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3816 if (status < 0)
3817 goto error;
3818 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3819 if (status < 0)
3820 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003822 /* Mandatory fix, always stop CP, required to set spl offset back to
3823 hardware default (is set to 0 by ucode during pilot detection */
3824 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3825 if (status < 0)
3826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003831 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003832 case TRANSMISSION_MODE_AUTO:
3833 default:
3834 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3835 /* fall through , try first guess DRX_FFTMODE_8K */
3836 case TRANSMISSION_MODE_8K:
3837 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003838 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003839 case TRANSMISSION_MODE_2K:
3840 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003841 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003842 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003843
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003845 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 default:
3847 case GUARD_INTERVAL_AUTO:
3848 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3849 /* fall through , try first guess DRX_GUARD_1DIV4 */
3850 case GUARD_INTERVAL_1_4:
3851 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003852 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003853 case GUARD_INTERVAL_1_32:
3854 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003855 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003856 case GUARD_INTERVAL_1_16:
3857 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003858 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003859 case GUARD_INTERVAL_1_8:
3860 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003861 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003862 }
3863
3864 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003865 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003866 case HIERARCHY_AUTO:
3867 case HIERARCHY_NONE:
3868 default:
3869 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3870 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3871 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3872 /* break; */
3873 case HIERARCHY_1:
3874 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3875 break;
3876 case HIERARCHY_2:
3877 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3878 break;
3879 case HIERARCHY_4:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3881 break;
3882 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003883
3884
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003885 /* modulation */
3886 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003887 case QAM_AUTO:
3888 default:
3889 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3890 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3891 case QAM_64:
3892 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3893 break;
3894 case QPSK:
3895 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3896 break;
3897 case QAM_16:
3898 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3899 break;
3900 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003901#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003902 /* No hierachical channels support in BDA */
3903 /* Priority (only for hierarchical channels) */
3904 switch (channel->priority) {
3905 case DRX_PRIORITY_LOW:
3906 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3907 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3908 OFDM_EC_SB_PRIOR_LO);
3909 break;
3910 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003911 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003912 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3913 OFDM_EC_SB_PRIOR_HI));
3914 break;
3915 case DRX_PRIORITY_UNKNOWN: /* fall through */
3916 default:
3917 status = -EINVAL;
3918 goto error;
3919 }
3920#else
3921 /* Set Priorty high */
3922 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3923 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3924 if (status < 0)
3925 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003926#endif
3927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003928 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003929 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003930 case FEC_AUTO:
3931 default:
3932 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3933 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3934 case FEC_2_3:
3935 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3936 break;
3937 case FEC_1_2:
3938 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3939 break;
3940 case FEC_3_4:
3941 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3942 break;
3943 case FEC_5_6:
3944 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3945 break;
3946 case FEC_7_8:
3947 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3948 break;
3949 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003950
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003951 /* SAW filter selection: normaly not necesarry, but if wanted
3952 the application can select a SAW filter via the driver by using UIOs */
3953 /* First determine real bandwidth (Hz) */
3954 /* Also set delay for impulse noise cruncher */
3955 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3956 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3957 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003958 switch (state->props.bandwidth_hz) {
3959 case 0:
3960 state->props.bandwidth_hz = 8000000;
3961 /* fall though */
3962 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003963 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3964 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003965 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003966 goto error;
3967 /* cochannel protection for PAL 8 MHz */
3968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3969 if (status < 0)
3970 goto error;
3971 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3972 if (status < 0)
3973 goto error;
3974 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3975 if (status < 0)
3976 goto error;
3977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3978 if (status < 0)
3979 goto error;
3980 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003981 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003982 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3983 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3984 if (status < 0)
3985 goto error;
3986 /* cochannel protection for PAL 7 MHz */
3987 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3988 if (status < 0)
3989 goto error;
3990 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3991 if (status < 0)
3992 goto error;
3993 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3994 if (status < 0)
3995 goto error;
3996 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3997 if (status < 0)
3998 goto error;
3999 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004000 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004001 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
4002 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
4003 if (status < 0)
4004 goto error;
4005 /* cochannel protection for NTSC 6 MHz */
4006 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
4007 if (status < 0)
4008 goto error;
4009 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4010 if (status < 0)
4011 goto error;
4012 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4013 if (status < 0)
4014 goto error;
4015 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4016 if (status < 0)
4017 goto error;
4018 break;
4019 default:
4020 status = -EINVAL;
4021 goto error;
4022 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004024 if (iqmRcRateOfs == 0) {
4025 /* Now compute IQM_RC_RATE_OFS
4026 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4027 =>
4028 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4029 */
4030 /* (SysFreq / BandWidth) * (2^28) */
4031 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4032 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4033 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4034 iqmRcRateOfs = Frac28a((u32)
4035 ((state->m_sysClockFreq *
4036 1000) / 3), bandwidth);
4037 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4038 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4039 iqmRcRateOfs += 0x80L;
4040 iqmRcRateOfs = iqmRcRateOfs >> 7;
4041 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4042 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4043 }
4044
4045 iqmRcRateOfs &=
4046 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4047 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4048 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4049 if (status < 0)
4050 goto error;
4051
4052 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004053
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004054#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004055 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4056 if (status < 0)
4057 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004058#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004059 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4060 if (status < 0)
4061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004063 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004064
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004065 /* Activate SCU to enable SCU commands */
4066 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4067 if (status < 0)
4068 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004069
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004070 /* Enable SC after setting all other parameters */
4071 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4072 if (status < 0)
4073 goto error;
4074 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4075 if (status < 0)
4076 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004077
4078
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004079 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4080 if (status < 0)
4081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004083 /* Write SC parameter registers, set all AUTO flags in operation mode */
4084 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4085 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4086 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4087 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4088 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4089 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4090 0, transmissionParams, param1, 0, 0, 0);
4091 if (status < 0)
4092 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004093
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004094 if (!state->m_DRXK_A3_ROM_CODE)
4095 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4096error:
4097 if (status < 0)
4098 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004099
4100 return status;
4101}
4102
4103
4104/*============================================================================*/
4105
4106/**
4107* \brief Retreive lock status .
4108* \param demod Pointer to demodulator instance.
4109* \param lockStat Pointer to lock status structure.
4110* \return DRXStatus_t.
4111*
4112*/
4113static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4114{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004115 int status;
4116 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4117 OFDM_SC_RA_RAM_LOCK_FEC__M);
4118 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4119 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004120
Oliver Endrissebc7de22011-07-03 13:49:44 -03004121 u16 ScRaRamLock = 0;
4122 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004123
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004124 dprintk(1, "\n");
4125
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004126 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004127 /* driver 0.9.0 */
4128 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004129 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004130 if (status < 0)
4131 goto end;
4132 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4133 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004134
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004135 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004136 if (status < 0)
4137 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004138
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4140 *pLockStatus = MPEG_LOCK;
4141 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4142 *pLockStatus = FEC_LOCK;
4143 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4144 *pLockStatus = DEMOD_LOCK;
4145 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4146 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004147end:
4148 if (status < 0)
4149 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004150
Oliver Endrissebc7de22011-07-03 13:49:44 -03004151 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004152}
4153
Oliver Endrissebc7de22011-07-03 13:49:44 -03004154static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004155{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004156 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004157 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004158
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004159 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004160 status = CtrlPowerMode(state, &powerMode);
4161 if (status < 0)
4162 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163
Oliver Endrissebc7de22011-07-03 13:49:44 -03004164 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004165}
4166
4167
Oliver Endrissebc7de22011-07-03 13:49:44 -03004168/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004169static int PowerDownQAM(struct drxk_state *state)
4170{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004171 u16 data = 0;
4172 u16 cmdResult;
4173 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004174
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004175 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004176 status = read16(state, SCU_COMM_EXEC__A, &data);
4177 if (status < 0)
4178 goto error;
4179 if (data == SCU_COMM_EXEC_ACTIVE) {
4180 /*
4181 STOP demodulator
4182 QAM and HW blocks
4183 */
4184 /* stop all comstate->m_exec */
4185 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004186 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004187 goto error;
4188 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 -03004189 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004190 goto error;
4191 }
4192 /* powerdown AFE */
4193 status = SetIqmAf(state, false);
4194
4195error:
4196 if (status < 0)
4197 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004198
Oliver Endrissebc7de22011-07-03 13:49:44 -03004199 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004200}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004201
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004202/*============================================================================*/
4203
4204/**
4205* \brief Setup of the QAM Measurement intervals for signal quality
4206* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004207* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004208* \return DRXStatus_t.
4209*
4210* NOTE:
4211* Take into account that for certain settings the errorcounters can overflow.
4212* The implementation does not check this.
4213*
4214*/
4215static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004216 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004217 u32 symbolRate)
4218{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004219 u32 fecBitsDesired = 0; /* BER accounting period */
4220 u32 fecRsPeriodTotal = 0; /* Total period */
4221 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4222 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004223 int status = 0;
4224
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004225 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004226
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004227 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004228 /* fecBitsDesired = symbolRate [kHz] *
4229 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004230 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004231 SyncLoss (== 1) *
4232 ViterbiLoss (==1)
4233 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004234 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004235 case DRX_CONSTELLATION_QAM16:
4236 fecBitsDesired = 4 * symbolRate;
4237 break;
4238 case DRX_CONSTELLATION_QAM32:
4239 fecBitsDesired = 5 * symbolRate;
4240 break;
4241 case DRX_CONSTELLATION_QAM64:
4242 fecBitsDesired = 6 * symbolRate;
4243 break;
4244 case DRX_CONSTELLATION_QAM128:
4245 fecBitsDesired = 7 * symbolRate;
4246 break;
4247 case DRX_CONSTELLATION_QAM256:
4248 fecBitsDesired = 8 * symbolRate;
4249 break;
4250 default:
4251 status = -EINVAL;
4252 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004253 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004254 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004255
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004256 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4257 fecBitsDesired *= 500; /* meas. period [ms] */
4258
4259 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4260 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4261 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4262
4263 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4264 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4265 if (fecRsPrescale == 0) {
4266 /* Divide by zero (though impossible) */
4267 status = -EINVAL;
4268 if (status < 0)
4269 goto error;
4270 }
4271 fecRsPeriod =
4272 ((u16) fecRsPeriodTotal +
4273 (fecRsPrescale >> 1)) / fecRsPrescale;
4274
4275 /* write corresponding registers */
4276 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4277 if (status < 0)
4278 goto error;
4279 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4283error:
4284 if (status < 0)
4285 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004286 return status;
4287}
4288
Oliver Endrissebc7de22011-07-03 13:49:44 -03004289static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004290{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004291 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004292
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004293 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004294 /* QAM Equalizer Setup */
4295 /* Equalizer */
4296 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4297 if (status < 0)
4298 goto error;
4299 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4300 if (status < 0)
4301 goto error;
4302 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4303 if (status < 0)
4304 goto error;
4305 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4306 if (status < 0)
4307 goto error;
4308 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4309 if (status < 0)
4310 goto error;
4311 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4312 if (status < 0)
4313 goto error;
4314 /* Decision Feedback Equalizer */
4315 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4316 if (status < 0)
4317 goto error;
4318 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4319 if (status < 0)
4320 goto error;
4321 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4322 if (status < 0)
4323 goto error;
4324 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4325 if (status < 0)
4326 goto error;
4327 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4328 if (status < 0)
4329 goto error;
4330 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4331 if (status < 0)
4332 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004333
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004334 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4335 if (status < 0)
4336 goto error;
4337 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4338 if (status < 0)
4339 goto error;
4340 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4341 if (status < 0)
4342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004344 /* QAM Slicer Settings */
4345 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4346 if (status < 0)
4347 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004348
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004349 /* QAM Loop Controller Coeficients */
4350 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4351 if (status < 0)
4352 goto error;
4353 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4354 if (status < 0)
4355 goto error;
4356 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4357 if (status < 0)
4358 goto error;
4359 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4360 if (status < 0)
4361 goto error;
4362 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4363 if (status < 0)
4364 goto error;
4365 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4366 if (status < 0)
4367 goto error;
4368 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4372 if (status < 0)
4373 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004374
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004375 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4391 if (status < 0)
4392 goto error;
4393 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4394 if (status < 0)
4395 goto error;
4396 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4397 if (status < 0)
4398 goto error;
4399 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4400 if (status < 0)
4401 goto error;
4402 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4403 if (status < 0)
4404 goto error;
4405 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4409 if (status < 0)
4410 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004411
4412
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004413 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004414
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004415 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4419 if (status < 0)
4420 goto error;
4421 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4422 if (status < 0)
4423 goto error;
4424 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4425 if (status < 0)
4426 goto error;
4427 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4428 if (status < 0)
4429 goto error;
4430 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4431 if (status < 0)
4432 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004434 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4435 if (status < 0)
4436 goto error;
4437 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4441 if (status < 0)
4442 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004443
4444
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004445 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004446
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004447 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4448 if (status < 0)
4449 goto error;
4450 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4451 if (status < 0)
4452 goto error;
4453 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4454 if (status < 0)
4455 goto error;
4456 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4457 if (status < 0)
4458 goto error;
4459 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4460 if (status < 0)
4461 goto error;
4462 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4463 if (status < 0)
4464 goto error;
4465 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4466 if (status < 0)
4467 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004468
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004469error:
4470 if (status < 0)
4471 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004472 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473}
4474
4475/*============================================================================*/
4476
4477/**
4478* \brief QAM32 specific setup
4479* \param demod instance of demod.
4480* \return DRXStatus_t.
4481*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004482static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004483{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004484 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004485
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004486 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004487
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004488 /* QAM Equalizer Setup */
4489 /* Equalizer */
4490 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4491 if (status < 0)
4492 goto error;
4493 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4506 if (status < 0)
4507 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004508
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004509 /* Decision Feedback Equalizer */
4510 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4514 if (status < 0)
4515 goto error;
4516 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4517 if (status < 0)
4518 goto error;
4519 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4520 if (status < 0)
4521 goto error;
4522 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4523 if (status < 0)
4524 goto error;
4525 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4526 if (status < 0)
4527 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004528
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004529 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4530 if (status < 0)
4531 goto error;
4532 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4533 if (status < 0)
4534 goto error;
4535 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4536 if (status < 0)
4537 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004539 /* QAM Slicer Settings */
4540
4541 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4542 if (status < 0)
4543 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004544
4545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004546 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004547
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004548 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4552 if (status < 0)
4553 goto error;
4554 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4555 if (status < 0)
4556 goto error;
4557 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4558 if (status < 0)
4559 goto error;
4560 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4561 if (status < 0)
4562 goto error;
4563 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4564 if (status < 0)
4565 goto error;
4566 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4567 if (status < 0)
4568 goto error;
4569 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4570 if (status < 0)
4571 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004572
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004573 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4589 if (status < 0)
4590 goto error;
4591 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4592 if (status < 0)
4593 goto error;
4594 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4595 if (status < 0)
4596 goto error;
4597 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4598 if (status < 0)
4599 goto error;
4600 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4601 if (status < 0)
4602 goto error;
4603 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4604 if (status < 0)
4605 goto error;
4606 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4607 if (status < 0)
4608 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004609
4610
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004611 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004612
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004613 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4614 if (status < 0)
4615 goto error;
4616 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4617 if (status < 0)
4618 goto error;
4619 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4620 if (status < 0)
4621 goto error;
4622 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4623 if (status < 0)
4624 goto error;
4625 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4626 if (status < 0)
4627 goto error;
4628 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4629 if (status < 0)
4630 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004631
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004632 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4633 if (status < 0)
4634 goto error;
4635 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4639 if (status < 0)
4640 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004641
4642
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004643 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004644
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004645 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4649 if (status < 0)
4650 goto error;
4651 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4652 if (status < 0)
4653 goto error;
4654 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4655 if (status < 0)
4656 goto error;
4657 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4658 if (status < 0)
4659 goto error;
4660 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4661 if (status < 0)
4662 goto error;
4663 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4664error:
4665 if (status < 0)
4666 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004667 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004668}
4669
4670/*============================================================================*/
4671
4672/**
4673* \brief QAM64 specific setup
4674* \param demod instance of demod.
4675* \return DRXStatus_t.
4676*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004677static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004678{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004679 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004680
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004681 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004682 /* QAM Equalizer Setup */
4683 /* Equalizer */
4684 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4685 if (status < 0)
4686 goto error;
4687 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4700 if (status < 0)
4701 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004702
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004703 /* Decision Feedback Equalizer */
4704 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4708 if (status < 0)
4709 goto error;
4710 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4711 if (status < 0)
4712 goto error;
4713 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4717 if (status < 0)
4718 goto error;
4719 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4720 if (status < 0)
4721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4724 if (status < 0)
4725 goto error;
4726 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4730 if (status < 0)
4731 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004732
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004733 /* QAM Slicer Settings */
4734 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4735 if (status < 0)
4736 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004737
4738
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004739 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004740
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004741 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4742 if (status < 0)
4743 goto error;
4744 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4745 if (status < 0)
4746 goto error;
4747 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4748 if (status < 0)
4749 goto error;
4750 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4751 if (status < 0)
4752 goto error;
4753 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4754 if (status < 0)
4755 goto error;
4756 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4757 if (status < 0)
4758 goto error;
4759 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4760 if (status < 0)
4761 goto error;
4762 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4763 if (status < 0)
4764 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004765
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004766 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4779 if (status < 0)
4780 goto error;
4781 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4782 if (status < 0)
4783 goto error;
4784 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4785 if (status < 0)
4786 goto error;
4787 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4788 if (status < 0)
4789 goto error;
4790 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4791 if (status < 0)
4792 goto error;
4793 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4794 if (status < 0)
4795 goto error;
4796 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4797 if (status < 0)
4798 goto error;
4799 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4800 if (status < 0)
4801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004802
4803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004804 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004805
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004806 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4807 if (status < 0)
4808 goto error;
4809 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4810 if (status < 0)
4811 goto error;
4812 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4813 if (status < 0)
4814 goto error;
4815 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4816 if (status < 0)
4817 goto error;
4818 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4819 if (status < 0)
4820 goto error;
4821 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4822 if (status < 0)
4823 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004824
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004825 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4826 if (status < 0)
4827 goto error;
4828 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4832 if (status < 0)
4833 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004834
4835
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004836 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004837
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004838 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4842 if (status < 0)
4843 goto error;
4844 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4845 if (status < 0)
4846 goto error;
4847 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4848 if (status < 0)
4849 goto error;
4850 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4851 if (status < 0)
4852 goto error;
4853 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4854 if (status < 0)
4855 goto error;
4856 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4857error:
4858 if (status < 0)
4859 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004860
Oliver Endrissebc7de22011-07-03 13:49:44 -03004861 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004862}
4863
4864/*============================================================================*/
4865
4866/**
4867* \brief QAM128 specific setup
4868* \param demod: instance of demod.
4869* \return DRXStatus_t.
4870*/
4871static int SetQAM128(struct drxk_state *state)
4872{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004873 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004874
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004875 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004876 /* QAM Equalizer Setup */
4877 /* Equalizer */
4878 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4894 if (status < 0)
4895 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004896
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004897 /* Decision Feedback Equalizer */
4898 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4899 if (status < 0)
4900 goto error;
4901 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4902 if (status < 0)
4903 goto error;
4904 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4905 if (status < 0)
4906 goto error;
4907 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4908 if (status < 0)
4909 goto error;
4910 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4911 if (status < 0)
4912 goto error;
4913 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4914 if (status < 0)
4915 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4918 if (status < 0)
4919 goto error;
4920 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4924 if (status < 0)
4925 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004926
4927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004928 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004929
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004930 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4931 if (status < 0)
4932 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004933
4934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004935 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004937 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4944 if (status < 0)
4945 goto error;
4946 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4947 if (status < 0)
4948 goto error;
4949 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4950 if (status < 0)
4951 goto error;
4952 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4953 if (status < 0)
4954 goto error;
4955 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4959 if (status < 0)
4960 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004961
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004962 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4975 if (status < 0)
4976 goto error;
4977 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4978 if (status < 0)
4979 goto error;
4980 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4981 if (status < 0)
4982 goto error;
4983 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4984 if (status < 0)
4985 goto error;
4986 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4987 if (status < 0)
4988 goto error;
4989 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4990 if (status < 0)
4991 goto error;
4992 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4996 if (status < 0)
4997 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004998
4999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005000 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005001
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005002 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5003 if (status < 0)
5004 goto error;
5005 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5006 if (status < 0)
5007 goto error;
5008 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5009 if (status < 0)
5010 goto error;
5011 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5012 if (status < 0)
5013 goto error;
5014 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5015 if (status < 0)
5016 goto error;
5017 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5018 if (status < 0)
5019 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005020
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005021 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5022 if (status < 0)
5023 goto error;
5024 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5025 if (status < 0)
5026 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005027
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005028 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5029 if (status < 0)
5030 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005031
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005032 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005033
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005034 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5035 if (status < 0)
5036 goto error;
5037 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5038 if (status < 0)
5039 goto error;
5040 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5041 if (status < 0)
5042 goto error;
5043 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5044 if (status < 0)
5045 goto error;
5046 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5047 if (status < 0)
5048 goto error;
5049 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5050 if (status < 0)
5051 goto error;
5052 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5053error:
5054 if (status < 0)
5055 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005056
Oliver Endrissebc7de22011-07-03 13:49:44 -03005057 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005058}
5059
5060/*============================================================================*/
5061
5062/**
5063* \brief QAM256 specific setup
5064* \param demod: instance of demod.
5065* \return DRXStatus_t.
5066*/
5067static int SetQAM256(struct drxk_state *state)
5068{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005069 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005070
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005071 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005072 /* QAM Equalizer Setup */
5073 /* Equalizer */
5074 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5075 if (status < 0)
5076 goto error;
5077 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5090 if (status < 0)
5091 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005093 /* Decision Feedback Equalizer */
5094 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5098 if (status < 0)
5099 goto error;
5100 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5101 if (status < 0)
5102 goto error;
5103 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5104 if (status < 0)
5105 goto error;
5106 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5107 if (status < 0)
5108 goto error;
5109 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5110 if (status < 0)
5111 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5114 if (status < 0)
5115 goto error;
5116 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5117 if (status < 0)
5118 goto error;
5119 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5120 if (status < 0)
5121 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005123 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005125 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5126 if (status < 0)
5127 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005128
5129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005130 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005131
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005132 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5139 if (status < 0)
5140 goto error;
5141 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5142 if (status < 0)
5143 goto error;
5144 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5145 if (status < 0)
5146 goto error;
5147 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5148 if (status < 0)
5149 goto error;
5150 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5151 if (status < 0)
5152 goto error;
5153 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5154 if (status < 0)
5155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005157 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5173 if (status < 0)
5174 goto error;
5175 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5176 if (status < 0)
5177 goto error;
5178 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5179 if (status < 0)
5180 goto error;
5181 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5182 if (status < 0)
5183 goto error;
5184 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5185 if (status < 0)
5186 goto error;
5187 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5188 if (status < 0)
5189 goto error;
5190 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5191 if (status < 0)
5192 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005193
5194
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005195 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005196
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005197 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5198 if (status < 0)
5199 goto error;
5200 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5201 if (status < 0)
5202 goto error;
5203 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5204 if (status < 0)
5205 goto error;
5206 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5207 if (status < 0)
5208 goto error;
5209 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5210 if (status < 0)
5211 goto error;
5212 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5213 if (status < 0)
5214 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005215
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005216 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5217 if (status < 0)
5218 goto error;
5219 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5220 if (status < 0)
5221 goto error;
5222 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5223 if (status < 0)
5224 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005225
5226
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005227 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005229 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5233 if (status < 0)
5234 goto error;
5235 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5236 if (status < 0)
5237 goto error;
5238 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5239 if (status < 0)
5240 goto error;
5241 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5242 if (status < 0)
5243 goto error;
5244 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5245 if (status < 0)
5246 goto error;
5247 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
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 Reset QAM block.
5258* \param demod: instance of demod.
5259* \param channel: pointer to channel data.
5260* \return DRXStatus_t.
5261*/
5262static int QAMResetQAM(struct drxk_state *state)
5263{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005264 int status;
5265 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005266
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005267 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005268 /* Stop QAM comstate->m_exec */
5269 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5270 if (status < 0)
5271 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005272
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005273 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5274error:
5275 if (status < 0)
5276 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005277 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005278}
5279
5280/*============================================================================*/
5281
5282/**
5283* \brief Set QAM symbolrate.
5284* \param demod: instance of demod.
5285* \param channel: pointer to channel data.
5286* \return DRXStatus_t.
5287*/
5288static int QAMSetSymbolrate(struct drxk_state *state)
5289{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005290 u32 adcFrequency = 0;
5291 u32 symbFreq = 0;
5292 u32 iqmRcRate = 0;
5293 u16 ratesel = 0;
5294 u32 lcSymbRate = 0;
5295 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005296
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005297 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005298 /* Select & calculate correct IQM rate */
5299 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5300 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005301 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5302 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005303 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005304 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005305 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005306 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005307 ratesel = 1;
5308 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5309 if (status < 0)
5310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005311
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005312 /*
5313 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5314 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005315 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005316 if (symbFreq == 0) {
5317 /* Divide by zero */
5318 status = -EINVAL;
5319 goto error;
5320 }
5321 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5322 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5323 (1 << 23);
5324 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5325 if (status < 0)
5326 goto error;
5327 state->m_iqmRcRate = iqmRcRate;
5328 /*
5329 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5330 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005331 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005332 if (adcFrequency == 0) {
5333 /* Divide by zero */
5334 status = -EINVAL;
5335 goto error;
5336 }
5337 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5338 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5339 16);
5340 if (lcSymbRate > 511)
5341 lcSymbRate = 511;
5342 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005344error:
5345 if (status < 0)
5346 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005347 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005348}
5349
5350/*============================================================================*/
5351
5352/**
5353* \brief Get QAM lock status.
5354* \param demod: instance of demod.
5355* \param channel: pointer to channel data.
5356* \return DRXStatus_t.
5357*/
5358
5359static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5360{
5361 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005364 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005365 *pLockStatus = NOT_LOCKED;
5366 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 SCU_RAM_COMMAND_STANDARD_QAM |
5368 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5369 Result);
5370 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005371 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005372
5373 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005374 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005375 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005376 /* 0x4000 DEMOD LOCKED */
5377 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005378 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005379 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5380 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005381 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005382 /* 0xC000 NEVER LOCKED */
5383 /* (system will never be able to lock to the signal) */
5384 /* TODO: check this, intermediate & standard specific lock states are not
5385 taken into account here */
5386 *pLockStatus = NEVER_LOCK;
5387 }
5388 return status;
5389}
5390
5391#define QAM_MIRROR__M 0x03
5392#define QAM_MIRROR_NORMAL 0x00
5393#define QAM_MIRRORED 0x01
5394#define QAM_MIRROR_AUTO_ON 0x02
5395#define QAM_LOCKRANGE__M 0x10
5396#define QAM_LOCKRANGE_NORMAL 0x10
5397
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005398static int QAMDemodulatorCommand(struct drxk_state *state,
5399 int numberOfParameters)
5400{
5401 int status;
5402 u16 cmdResult;
5403 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5404
5405 setParamParameters[0] = state->m_Constellation; /* modulation */
5406 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5407
5408 if (numberOfParameters == 2) {
5409 u16 setEnvParameters[1] = { 0 };
5410
5411 if (state->m_OperationMode == OM_QAM_ITU_C)
5412 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5413 else
5414 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5415
5416 status = scu_command(state,
5417 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5418 1, setEnvParameters, 1, &cmdResult);
5419 if (status < 0)
5420 goto error;
5421
5422 status = scu_command(state,
5423 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5424 numberOfParameters, setParamParameters,
5425 1, &cmdResult);
5426 } else if (numberOfParameters == 4) {
5427 if (state->m_OperationMode == OM_QAM_ITU_C)
5428 setParamParameters[2] = QAM_TOP_ANNEX_C;
5429 else
5430 setParamParameters[2] = QAM_TOP_ANNEX_A;
5431
5432 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5433 /* Env parameters */
5434 /* check for LOCKRANGE Extented */
5435 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5436
5437 status = scu_command(state,
5438 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5439 numberOfParameters, setParamParameters,
5440 1, &cmdResult);
5441 } else {
5442 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5443 "count %d\n", numberOfParameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005444 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005445 }
5446
5447error:
5448 if (status < 0)
5449 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5450 status, __func__);
5451 return status;
5452}
5453
Oliver Endrissebc7de22011-07-03 13:49:44 -03005454static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5455 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005456{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005457 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005458 u16 cmdResult;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005459 int qamDemodParamCount = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005460
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005461 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005462 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005463 * STEP 1: reset demodulator
5464 * resets FEC DI and FEC RS
5465 * resets QAM block
5466 * resets SCU variables
5467 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005468 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005469 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005470 goto error;
5471 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5472 if (status < 0)
5473 goto error;
5474 status = QAMResetQAM(state);
5475 if (status < 0)
5476 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005477
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005478 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005479 * STEP 2: configure demodulator
5480 * -set params; resets IQM,QAM,FEC HW; initializes some
5481 * SCU variables
5482 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005483 status = QAMSetSymbolrate(state);
5484 if (status < 0)
5485 goto error;
5486
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005487 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005488 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005489 case QAM_256:
5490 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5491 break;
5492 case QAM_AUTO:
5493 case QAM_64:
5494 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5495 break;
5496 case QAM_16:
5497 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5498 break;
5499 case QAM_32:
5500 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5501 break;
5502 case QAM_128:
5503 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5504 break;
5505 default:
5506 status = -EINVAL;
5507 break;
5508 }
5509 if (status < 0)
5510 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005511
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005512 /* Use the 4-parameter if it's requested or we're probing for
5513 * the correct command. */
5514 if (state->qam_demod_parameter_count == 4
5515 || !state->qam_demod_parameter_count) {
5516 qamDemodParamCount = 4;
5517 status = QAMDemodulatorCommand(state, qamDemodParamCount);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005518 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005519
5520 /* Use the 2-parameter command if it was requested or if we're
5521 * probing for the correct command and the 4-parameter command
5522 * failed. */
5523 if (state->qam_demod_parameter_count == 2
5524 || (!state->qam_demod_parameter_count && status < 0)) {
5525 qamDemodParamCount = 2;
5526 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5527 }
5528
5529 if (status < 0) {
5530 dprintk(1, "Could not set demodulator parameters. Make "
5531 "sure qam_demod_parameter_count (%d) is correct for "
5532 "your firmware (%s).\n",
5533 state->qam_demod_parameter_count,
5534 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005535 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005536 } else if (!state->qam_demod_parameter_count) {
5537 dprintk(1, "Auto-probing the correct QAM demodulator command "
5538 "parameters was successful - using %d parameters.\n",
5539 qamDemodParamCount);
5540
Mauro Carvalho Chehab7eaf71882012-07-06 14:53:51 -03005541 /*
5542 * One of our commands was successful. We don't need to
5543 * auto-probe anymore, now that we got the correct command.
5544 */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005545 state->qam_demod_parameter_count = qamDemodParamCount;
5546 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005547
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005548 /*
5549 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005550 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005551 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005552#if 0
5553 status = SetFrequency(channel, tunerFreqOffset));
5554 if (status < 0)
5555 goto error;
5556#endif
5557 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5558 if (status < 0)
5559 goto error;
5560
5561 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005562 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005563 if (status < 0)
5564 goto error;
5565
5566 /* Reset default values */
5567 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5568 if (status < 0)
5569 goto error;
5570 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5571 if (status < 0)
5572 goto error;
5573
5574 /* Reset default LC values */
5575 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5576 if (status < 0)
5577 goto error;
5578 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5579 if (status < 0)
5580 goto error;
5581 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5582 if (status < 0)
5583 goto error;
5584 status = write16(state, QAM_LC_MODE__A, 7);
5585 if (status < 0)
5586 goto error;
5587
5588 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5589 if (status < 0)
5590 goto error;
5591 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5592 if (status < 0)
5593 goto error;
5594 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5595 if (status < 0)
5596 goto error;
5597 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5598 if (status < 0)
5599 goto error;
5600 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5601 if (status < 0)
5602 goto error;
5603 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5604 if (status < 0)
5605 goto error;
5606 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5607 if (status < 0)
5608 goto error;
5609 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5610 if (status < 0)
5611 goto error;
5612 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5613 if (status < 0)
5614 goto error;
5615 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5616 if (status < 0)
5617 goto error;
5618 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5619 if (status < 0)
5620 goto error;
5621 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5622 if (status < 0)
5623 goto error;
5624 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5625 if (status < 0)
5626 goto error;
5627 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5628 if (status < 0)
5629 goto error;
5630 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5631 if (status < 0)
5632 goto error;
5633
5634 /* Mirroring, QAM-block starting point not inverted */
5635 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5636 if (status < 0)
5637 goto error;
5638
5639 /* Halt SCU to enable safe non-atomic accesses */
5640 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5641 if (status < 0)
5642 goto error;
5643
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005644 /* STEP 4: modulation specific setup */
5645 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005646 case QAM_16:
5647 status = SetQAM16(state);
5648 break;
5649 case QAM_32:
5650 status = SetQAM32(state);
5651 break;
5652 case QAM_AUTO:
5653 case QAM_64:
5654 status = SetQAM64(state);
5655 break;
5656 case QAM_128:
5657 status = SetQAM128(state);
5658 break;
5659 case QAM_256:
5660 status = SetQAM256(state);
5661 break;
5662 default:
5663 status = -EINVAL;
5664 break;
5665 }
5666 if (status < 0)
5667 goto error;
5668
5669 /* Activate SCU to enable SCU commands */
5670 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5671 if (status < 0)
5672 goto error;
5673
5674 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005675 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005676 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5677 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5678 if (status < 0)
5679 goto error;
5680
5681 /* Start processes */
5682 status = MPEGTSStart(state);
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5692 if (status < 0)
5693 goto error;
5694
5695 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5696 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5697 if (status < 0)
5698 goto error;
5699
5700 /* update global DRXK data container */
5701/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5702
5703error:
5704 if (status < 0)
5705 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005706 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707}
5708
Oliver Endrissebc7de22011-07-03 13:49:44 -03005709static int SetQAMStandard(struct drxk_state *state,
5710 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005711{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005712 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005713#ifdef DRXK_QAM_TAPS
5714#define DRXK_QAMA_TAPS_SELECT
5715#include "drxk_filters.h"
5716#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005717#endif
5718
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005719 dprintk(1, "\n");
5720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005721 /* added antenna switch */
5722 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005724 /* Ensure correct power-up mode */
5725 status = PowerUpQAM(state);
5726 if (status < 0)
5727 goto error;
5728 /* Reset QAM block */
5729 status = QAMResetQAM(state);
5730 if (status < 0)
5731 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005732
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005733 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005734
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005735 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5739 if (status < 0)
5740 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005741
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005742 /* Upload IQM Channel Filter settings by
5743 boot loader from ROM table */
5744 switch (oMode) {
5745 case OM_QAM_ITU_A:
5746 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5747 break;
5748 case OM_QAM_ITU_C:
5749 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 -03005750 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005751 goto error;
5752 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5753 break;
5754 default:
5755 status = -EINVAL;
5756 }
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_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5761 if (status < 0)
5762 goto error;
5763 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5764 if (status < 0)
5765 goto error;
5766 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5767 if (status < 0)
5768 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005769
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005770 status = write16(state, IQM_RC_STRETCH__A, 21);
5771 if (status < 0)
5772 goto error;
5773 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5774 if (status < 0)
5775 goto error;
5776 status = write16(state, IQM_AF_CLP_TH__A, 448);
5777 if (status < 0)
5778 goto error;
5779 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5780 if (status < 0)
5781 goto error;
5782 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5783 if (status < 0)
5784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005786 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5787 if (status < 0)
5788 goto error;
5789 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5790 if (status < 0)
5791 goto error;
5792 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5793 if (status < 0)
5794 goto error;
5795 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5796 if (status < 0)
5797 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005798
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005799 /* IQM Impulse Noise Processing Unit */
5800 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5801 if (status < 0)
5802 goto error;
5803 status = write16(state, IQM_CF_DATATH__A, 1000);
5804 if (status < 0)
5805 goto error;
5806 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5807 if (status < 0)
5808 goto error;
5809 status = write16(state, IQM_CF_DET_LCT__A, 0);
5810 if (status < 0)
5811 goto error;
5812 status = write16(state, IQM_CF_WND_LEN__A, 1);
5813 if (status < 0)
5814 goto error;
5815 status = write16(state, IQM_CF_PKDTH__A, 1);
5816 if (status < 0)
5817 goto error;
5818 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5819 if (status < 0)
5820 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005822 /* turn on IQMAF. Must be done before setAgc**() */
5823 status = SetIqmAf(state, true);
5824 if (status < 0)
5825 goto error;
5826 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5827 if (status < 0)
5828 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005830 /* IQM will not be reset from here, sync ADC and update/init AGC */
5831 status = ADCSynchronization(state);
5832 if (status < 0)
5833 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005834
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005835 /* Set the FSM step period */
5836 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5837 if (status < 0)
5838 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005839
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005840 /* Halt SCU to enable safe non-atomic accesses */
5841 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5842 if (status < 0)
5843 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005844
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005845 /* No more resets of the IQM, current standard correctly set =>
5846 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005847
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005848 status = InitAGC(state, true);
5849 if (status < 0)
5850 goto error;
5851 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5852 if (status < 0)
5853 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005854
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005855 /* Configure AGC's */
5856 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5857 if (status < 0)
5858 goto error;
5859 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5860 if (status < 0)
5861 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005862
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005863 /* Activate SCU to enable SCU commands */
5864 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5865error:
5866 if (status < 0)
5867 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005868 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005869}
5870
5871static int WriteGPIO(struct drxk_state *state)
5872{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005873 int status;
5874 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005876 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005877 /* stop lock indicator process */
5878 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5879 if (status < 0)
5880 goto error;
5881
5882 /* Write magic word to enable pdr reg write */
5883 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5884 if (status < 0)
5885 goto error;
5886
5887 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005888 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5889 /* write to io pad configuration register - output mode */
5890 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5891 if (status < 0)
5892 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005893
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005894 /* use corresponding bit in io data output registar */
5895 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5896 if (status < 0)
5897 goto error;
5898 if ((state->m_GPIO & 0x0001) == 0)
5899 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5900 else
5901 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5902 /* write back to io data output register */
5903 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5904 if (status < 0)
5905 goto error;
5906 }
5907 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5908 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005909 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005910 if (status < 0)
5911 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005912
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005913 /* use corresponding bit in io data output registar */
5914 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5915 if (status < 0)
5916 goto error;
5917 if ((state->m_GPIO & 0x0002) == 0)
5918 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5919 else
5920 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5921 /* write back to io data output register */
5922 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5923 if (status < 0)
5924 goto error;
5925 }
5926 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5927 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005928 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005929 if (status < 0)
5930 goto error;
5931
5932 /* use corresponding bit in io data output registar */
5933 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5934 if (status < 0)
5935 goto error;
5936 if ((state->m_GPIO & 0x0004) == 0)
5937 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5938 else
5939 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5940 /* write back to io data output register */
5941 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5942 if (status < 0)
5943 goto error;
5944 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005945 }
5946 /* Write magic word to disable pdr reg write */
5947 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5948error:
5949 if (status < 0)
5950 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005952}
5953
5954static int SwitchAntennaToQAM(struct drxk_state *state)
5955{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005956 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005957 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005958
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005959 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005960
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005961 if (!state->antenna_gpio)
5962 return 0;
5963
5964 gpio_state = state->m_GPIO & state->antenna_gpio;
5965
5966 if (state->antenna_dvbt ^ gpio_state) {
5967 /* Antenna is on DVB-T mode. Switch */
5968 if (state->antenna_dvbt)
5969 state->m_GPIO &= ~state->antenna_gpio;
5970 else
5971 state->m_GPIO |= state->antenna_gpio;
5972 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005973 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005974 if (status < 0)
5975 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005976 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977}
5978
5979static int SwitchAntennaToDVBT(struct drxk_state *state)
5980{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005981 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005982 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005983
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005984 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005985
5986 if (!state->antenna_gpio)
5987 return 0;
5988
5989 gpio_state = state->m_GPIO & state->antenna_gpio;
5990
5991 if (!(state->antenna_dvbt ^ gpio_state)) {
5992 /* Antenna is on DVB-C mode. Switch */
5993 if (state->antenna_dvbt)
5994 state->m_GPIO |= state->antenna_gpio;
5995 else
5996 state->m_GPIO &= ~state->antenna_gpio;
5997 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005998 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005999 if (status < 0)
6000 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006001 return status;
6002}
6003
6004
6005static int PowerDownDevice(struct drxk_state *state)
6006{
6007 /* Power down to requested mode */
6008 /* Backup some register settings */
6009 /* Set pins with possible pull-ups connected to them in input mode */
6010 /* Analog power down */
6011 /* ADC power down */
6012 /* Power down device */
6013 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006014
6015 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006016 if (state->m_bPDownOpenBridge) {
6017 /* Open I2C bridge before power down of DRXK */
6018 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006019 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006020 goto error;
6021 }
6022 /* driver 0.9.0 */
6023 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006024 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006026
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006027 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
6028 if (status < 0)
6029 goto error;
6030 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6031 if (status < 0)
6032 goto error;
6033 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6034 status = HI_CfgCommand(state);
6035error:
6036 if (status < 0)
6037 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6038
6039 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006040}
6041
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006042static int init_drxk(struct drxk_state *state)
6043{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006044 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006045 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006046 u16 driverVersion;
6047
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006048 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006049 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006050 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006051 status = PowerUpDevice(state);
6052 if (status < 0)
6053 goto error;
6054 status = DRXX_Open(state);
6055 if (status < 0)
6056 goto error;
6057 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6058 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);
6059 if (status < 0)
6060 goto error;
6061 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6062 if (status < 0)
6063 goto error;
6064 /* TODO is this needed, if yes how much delay in worst case scenario */
6065 msleep(1);
6066 state->m_DRXK_A3_PATCH_CODE = true;
6067 status = GetDeviceCapabilities(state);
6068 if (status < 0)
6069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006071 /* Bridge delay, uses oscilator clock */
6072 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6073 /* SDA brdige delay */
6074 state->m_HICfgBridgeDelay =
6075 (u16) ((state->m_oscClockFreq / 1000) *
6076 HI_I2C_BRIDGE_DELAY) / 1000;
6077 /* Clipping */
6078 if (state->m_HICfgBridgeDelay >
6079 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006080 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006081 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6082 }
6083 /* SCL bridge delay, same as SDA for now */
6084 state->m_HICfgBridgeDelay +=
6085 state->m_HICfgBridgeDelay <<
6086 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006088 status = InitHI(state);
6089 if (status < 0)
6090 goto error;
6091 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 if (!(state->m_DRXK_A1_ROM_CODE)
6094 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006096 {
6097 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6098 if (status < 0)
6099 goto error;
6100 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006101
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006102 /* disable MPEG port */
6103 status = MPEGTSDisable(state);
6104 if (status < 0)
6105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006107 /* Stop AUD and SCU */
6108 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6109 if (status < 0)
6110 goto error;
6111 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6112 if (status < 0)
6113 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006115 /* enable token-ring bus through OFDM block for possible ucode upload */
6116 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6117 if (status < 0)
6118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 /* include boot loader section */
6121 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6122 if (status < 0)
6123 goto error;
6124 status = BLChainCmd(state, 0, 6, 100);
6125 if (status < 0)
6126 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006127
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006128 if (state->fw) {
6129 status = DownloadMicrocode(state, state->fw->data,
6130 state->fw->size);
6131 if (status < 0)
6132 goto error;
6133 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006135 /* disable token-ring bus through OFDM block for possible ucode upload */
6136 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6137 if (status < 0)
6138 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006139
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006140 /* Run SCU for a little while to initialize microcode version numbers */
6141 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6142 if (status < 0)
6143 goto error;
6144 status = DRXX_Open(state);
6145 if (status < 0)
6146 goto error;
6147 /* added for test */
6148 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006150 powerMode = DRXK_POWER_DOWN_OFDM;
6151 status = CtrlPowerMode(state, &powerMode);
6152 if (status < 0)
6153 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006155 /* Stamp driver version number in SCU data RAM in BCD code
6156 Done to enable field application engineers to retreive drxdriver version
6157 via I2C from SCU RAM.
6158 Not using SCU command interface for SCU register access since no
6159 microcode may be present.
6160 */
6161 driverVersion =
6162 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6163 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6164 ((DRXK_VERSION_MAJOR % 10) << 4) +
6165 (DRXK_VERSION_MINOR % 10);
6166 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6167 if (status < 0)
6168 goto error;
6169 driverVersion =
6170 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6171 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6172 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6173 (DRXK_VERSION_PATCH % 10);
6174 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6175 if (status < 0)
6176 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006178 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6179 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6180 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006182 /* Dirty fix of default values for ROM/PATCH microcode
6183 Dirty because this fix makes it impossible to setup suitable values
6184 before calling DRX_Open. This solution requires changes to RF AGC speed
6185 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006187 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006188
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006189 /* Reset driver debug flags to 0 */
6190 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6191 if (status < 0)
6192 goto error;
6193 /* driver 0.9.0 */
6194 /* Setup FEC OC:
6195 NOTE: No more full FEC resets allowed afterwards!! */
6196 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6197 if (status < 0)
6198 goto error;
6199 /* MPEGTS functions are still the same */
6200 status = MPEGTSDtoInit(state);
6201 if (status < 0)
6202 goto error;
6203 status = MPEGTSStop(state);
6204 if (status < 0)
6205 goto error;
6206 status = MPEGTSConfigurePolarity(state);
6207 if (status < 0)
6208 goto error;
6209 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6210 if (status < 0)
6211 goto error;
6212 /* added: configure GPIO */
6213 status = WriteGPIO(state);
6214 if (status < 0)
6215 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006217 state->m_DrxkState = DRXK_STOPPED;
6218
6219 if (state->m_bPowerDown) {
6220 status = PowerDownDevice(state);
6221 if (status < 0)
6222 goto error;
6223 state->m_DrxkState = DRXK_POWERED_DOWN;
6224 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006225 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006226
6227 /* Initialize the supported delivery systems */
6228 n = 0;
6229 if (state->m_hasDVBC) {
6230 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6231 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6232 strlcat(state->frontend.ops.info.name, " DVB-C",
6233 sizeof(state->frontend.ops.info.name));
6234 }
6235 if (state->m_hasDVBT) {
6236 state->frontend.ops.delsys[n++] = SYS_DVBT;
6237 strlcat(state->frontend.ops.info.name, " DVB-T",
6238 sizeof(state->frontend.ops.info.name));
6239 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006240 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006241 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006242error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006243 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006244 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006245 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006246 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006247 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006248
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006249 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250}
6251
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006252static void load_firmware_cb(const struct firmware *fw,
6253 void *context)
6254{
6255 struct drxk_state *state = context;
6256
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006257 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006258 if (!fw) {
6259 printk(KERN_ERR
6260 "drxk: Could not load firmware file %s.\n",
6261 state->microcode_name);
6262 printk(KERN_INFO
6263 "drxk: Copy %s to your hotplug directory!\n",
6264 state->microcode_name);
6265 state->microcode_name = NULL;
6266
6267 /*
6268 * As firmware is now load asynchronous, it is not possible
6269 * anymore to fail at frontend attach. We might silently
6270 * return here, and hope that the driver won't crash.
6271 * We might also change all DVB callbacks to return -ENODEV
6272 * if the device is not initialized.
6273 * As the DRX-K devices have their own internal firmware,
6274 * let's just hope that it will match a firmware revision
6275 * compatible with this driver and proceed.
6276 */
6277 }
6278 state->fw = fw;
6279
6280 init_drxk(state);
6281}
6282
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006283static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006285 struct drxk_state *state = fe->demodulator_priv;
6286
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006287 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006288 if (state->fw)
6289 release_firmware(state->fw);
6290
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 kfree(state);
6292}
6293
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006294static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006295{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006296 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006297
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006298 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006299
6300 if (state->m_DrxkState == DRXK_NO_DEV)
6301 return -ENODEV;
6302 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6303 return 0;
6304
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006305 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006306 return 0;
6307}
6308
Oliver Endrissebc7de22011-07-03 13:49:44 -03006309static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006310{
6311 struct drxk_state *state = fe->demodulator_priv;
6312
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006313 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006314
6315 if (state->m_DrxkState == DRXK_NO_DEV)
6316 return -ENODEV;
6317
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318 return ConfigureI2CBridge(state, enable ? true : false);
6319}
6320
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006321static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006322{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006323 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006324 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006325 struct drxk_state *state = fe->demodulator_priv;
6326 u32 IF;
6327
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006328 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006329
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006330 if (state->m_DrxkState == DRXK_NO_DEV)
6331 return -ENODEV;
6332
6333 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6334 return -EAGAIN;
6335
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006336 if (!fe->ops.tuner_ops.get_if_frequency) {
6337 printk(KERN_ERR
6338 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6339 return -EINVAL;
6340 }
6341
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006342 if (fe->ops.i2c_gate_ctrl)
6343 fe->ops.i2c_gate_ctrl(fe, 1);
6344 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006345 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006346 if (fe->ops.i2c_gate_ctrl)
6347 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006348
6349 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006350 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006351
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006352 if (old_delsys != delsys) {
6353 ShutDown(state);
6354 switch (delsys) {
6355 case SYS_DVBC_ANNEX_A:
6356 case SYS_DVBC_ANNEX_C:
6357 if (!state->m_hasDVBC)
6358 return -EINVAL;
6359 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6360 if (state->m_itut_annex_c)
6361 SetOperationMode(state, OM_QAM_ITU_C);
6362 else
6363 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006364 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006365 case SYS_DVBT:
6366 if (!state->m_hasDVBT)
6367 return -EINVAL;
6368 SetOperationMode(state, OM_DVBT);
6369 break;
6370 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006371 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006372 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006373 }
6374
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006375 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376 Start(state, 0, IF);
6377
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006378 /* After set_frontend, stats aren't avaliable */
6379 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6380 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6381 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6382 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6383 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6384 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6385 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6386 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6387
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006388 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006389
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006390 return 0;
6391}
6392
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006393static int get_strength(struct drxk_state *state, u64 *strength)
6394{
6395 int status;
6396 struct SCfgAgc rfAgc, ifAgc;
6397 u32 totalGain = 0;
6398 u32 atten = 0;
6399 u32 agcRange = 0;
6400 u16 scu_lvl = 0;
6401 u16 scu_coc = 0;
6402 /* FIXME: those are part of the tuner presets */
6403 u16 tunerRfGain = 50; /* Default value on az6007 driver */
6404 u16 tunerIfGain = 40; /* Default value on az6007 driver */
6405
6406 *strength = 0;
6407
6408 if (IsDVBT(state)) {
6409 rfAgc = state->m_dvbtRfAgcCfg;
6410 ifAgc = state->m_dvbtIfAgcCfg;
6411 } else if (IsQAM(state)) {
6412 rfAgc = state->m_qamRfAgcCfg;
6413 ifAgc = state->m_qamIfAgcCfg;
6414 } else {
6415 rfAgc = state->m_atvRfAgcCfg;
6416 ifAgc = state->m_atvIfAgcCfg;
6417 }
6418
6419 if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6420 /* SCU outputLevel */
6421 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6422 if (status < 0)
6423 return status;
6424
6425 /* SCU c.o.c. */
6426 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6427 if (status < 0)
6428 return status;
6429
6430 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6431 rfAgc.outputLevel = scu_lvl + scu_coc;
6432 else
6433 rfAgc.outputLevel = 0xffff;
6434
6435 /* Take RF gain into account */
6436 totalGain += tunerRfGain;
6437
6438 /* clip output value */
6439 if (rfAgc.outputLevel < rfAgc.minOutputLevel)
6440 rfAgc.outputLevel = rfAgc.minOutputLevel;
6441 if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
6442 rfAgc.outputLevel = rfAgc.maxOutputLevel;
6443
6444 agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
6445 if (agcRange > 0) {
6446 atten += 100UL *
6447 ((u32)(tunerRfGain)) *
6448 ((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
6449 / agcRange;
6450 }
6451 }
6452
6453 if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6454 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6455 &ifAgc.outputLevel);
6456 if (status < 0)
6457 return status;
6458
6459 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6460 &ifAgc.top);
6461 if (status < 0)
6462 return status;
6463
6464 /* Take IF gain into account */
6465 totalGain += (u32) tunerIfGain;
6466
6467 /* clip output value */
6468 if (ifAgc.outputLevel < ifAgc.minOutputLevel)
6469 ifAgc.outputLevel = ifAgc.minOutputLevel;
6470 if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
6471 ifAgc.outputLevel = ifAgc.maxOutputLevel;
6472
6473 agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
6474 if (agcRange > 0) {
6475 atten += 100UL *
6476 ((u32)(tunerIfGain)) *
6477 ((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
6478 / agcRange;
6479 }
6480 }
6481
6482 /*
6483 * Convert to 0..65535 scale.
6484 * If it can't be measured (AGC is disabled), just show 100%.
6485 */
6486 if (totalGain > 0)
6487 *strength = (65535UL * atten / totalGain);
6488 else
6489 *strength = 65535;
6490
6491 return 0;
6492}
6493
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006494static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006495{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006496 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006497 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006498 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006499 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006500 u16 reg16;
6501 u32 post_bit_count;
6502 u32 post_bit_err_count;
6503 u32 post_bit_error_scale;
6504 u32 pre_bit_err_count;
6505 u32 pre_bit_count;
6506 u32 pkt_count;
6507 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006508 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006509
6510 if (state->m_DrxkState == DRXK_NO_DEV)
6511 return -ENODEV;
6512 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6513 return -EAGAIN;
6514
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006515 /* get status */
6516 state->fe_status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006517 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006518 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006519 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006520 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006521 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006522 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006523 state->fe_status |= 0x07;
6524
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006525 /*
6526 * Estimate signal strength from AGC
6527 */
6528 get_strength(state, &c->strength.stat[0].uvalue);
6529 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6530
6531
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006532 if (stat >= DEMOD_LOCK) {
6533 GetSignalToNoise(state, &cnr);
6534 c->cnr.stat[0].svalue = cnr * 100;
6535 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6536 } else {
6537 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6538 }
6539
6540 if (stat < FEC_LOCK) {
6541 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6542 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6543 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6544 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6545 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6546 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6547 return 0;
6548 }
6549
6550 /* Get post BER */
6551
6552 /* BER measurement is valid if at least FEC lock is achieved */
6553
6554 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6555 to set nr of symbols or bits over which
6556 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6557
6558 /* Read registers for post/preViterbi BER calculation */
6559 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6560 if (status < 0)
6561 goto error;
6562 pre_bit_err_count = reg16;
6563
6564 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6565 if (status < 0)
6566 goto error;
6567 pre_bit_count = reg16;
6568
6569 /* Number of bit-errors */
6570 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6571 if (status < 0)
6572 goto error;
6573 post_bit_err_count = reg16;
6574
6575 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6576 if (status < 0)
6577 goto error;
6578 post_bit_error_scale = reg16;
6579
6580 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6581 if (status < 0)
6582 goto error;
6583 pkt_count = reg16;
6584
6585 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6586 if (status < 0)
6587 goto error;
6588 pkt_error_count = reg16;
6589 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6590
6591 post_bit_err_count *= post_bit_error_scale;
6592
6593 post_bit_count = pkt_count * 204 * 8;
6594
6595 /* Store the results */
6596 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6597 c->block_error.stat[0].uvalue += pkt_error_count;
6598 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6599 c->block_count.stat[0].uvalue += pkt_count;
6600
6601 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6602 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6603 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6604 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6605
6606 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6607 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6608 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6609 c->post_bit_count.stat[0].uvalue += post_bit_count;
6610
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006611error:
6612 return status;
6613}
6614
6615
6616static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6617{
6618 struct drxk_state *state = fe->demodulator_priv;
6619 int rc;
6620
6621 dprintk(1, "\n");
6622
6623 rc = drxk_get_stats(fe);
6624 if (rc < 0)
6625 return rc;
6626
6627 *status = state->fe_status;
6628
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006629 return 0;
6630}
6631
Oliver Endrissebc7de22011-07-03 13:49:44 -03006632static int drxk_read_signal_strength(struct dvb_frontend *fe,
6633 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006634{
6635 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006636 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006637
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006638 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006639
6640 if (state->m_DrxkState == DRXK_NO_DEV)
6641 return -ENODEV;
6642 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6643 return -EAGAIN;
6644
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006645 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006646 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006647 return 0;
6648}
6649
6650static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6651{
6652 struct drxk_state *state = fe->demodulator_priv;
6653 s32 snr2;
6654
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006655 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006656
6657 if (state->m_DrxkState == DRXK_NO_DEV)
6658 return -ENODEV;
6659 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6660 return -EAGAIN;
6661
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006662 GetSignalToNoise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006663
6664 /* No negative SNR, clip to zero */
6665 if (snr2 < 0)
6666 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006667 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006668 return 0;
6669}
6670
6671static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6672{
6673 struct drxk_state *state = fe->demodulator_priv;
6674 u16 err;
6675
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006676 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006677
6678 if (state->m_DrxkState == DRXK_NO_DEV)
6679 return -ENODEV;
6680 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6681 return -EAGAIN;
6682
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006683 DVBTQAMGetAccPktErr(state, &err);
6684 *ucblocks = (u32) err;
6685 return 0;
6686}
6687
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006688static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006689 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006690{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006691 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006692 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006693
6694 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006695
6696 if (state->m_DrxkState == DRXK_NO_DEV)
6697 return -ENODEV;
6698 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6699 return -EAGAIN;
6700
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006701 switch (p->delivery_system) {
6702 case SYS_DVBC_ANNEX_A:
6703 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006704 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006705 sets->min_delay_ms = 3000;
6706 sets->max_drift = 0;
6707 sets->step_size = 0;
6708 return 0;
6709 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006710 return -EINVAL;
6711 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006712}
6713
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006714static struct dvb_frontend_ops drxk_ops = {
6715 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006716 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006717 .name = "DRXK",
6718 .frequency_min = 47000000,
6719 .frequency_max = 865000000,
6720 /* For DVB-C */
6721 .symbol_rate_min = 870000,
6722 .symbol_rate_max = 11700000,
6723 /* For DVB-T */
6724 .frequency_stepsize = 166667,
6725
6726 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6727 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6728 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6729 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6730 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6731 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6732 },
6733
6734 .release = drxk_release,
6735 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006736 .i2c_gate_ctrl = drxk_gate_ctrl,
6737
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006738 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006739 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006740
6741 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006742 .read_signal_strength = drxk_read_signal_strength,
6743 .read_snr = drxk_read_snr,
6744 .read_ucblocks = drxk_read_ucblocks,
6745};
6746
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006747struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006748 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006749{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006750 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006751 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006752 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006753 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006754
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006755 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006756 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006757 if (!state)
6758 return NULL;
6759
Oliver Endrissebc7de22011-07-03 13:49:44 -03006760 state->i2c = i2c;
6761 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006762 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006763 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006764 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006765 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006766 state->antenna_gpio = config->antenna_gpio;
6767 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006768 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006769 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006770
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006771 if (config->dynamic_clk) {
6772 state->m_DVBTStaticCLK = 0;
6773 state->m_DVBCStaticCLK = 0;
6774 } else {
6775 state->m_DVBTStaticCLK = 1;
6776 state->m_DVBCStaticCLK = 1;
6777 }
6778
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006779
6780 if (config->mpeg_out_clk_strength)
6781 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6782 else
6783 state->m_TSClockkStrength = 0x06;
6784
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006785 if (config->parallel_ts)
6786 state->m_enableParallel = true;
6787 else
6788 state->m_enableParallel = false;
6789
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006790 /* NOTE: as more UIO bits will be used, add them to the mask */
6791 state->UIO_mask = config->antenna_gpio;
6792
6793 /* Default gpio to DVB-C */
6794 if (!state->antenna_dvbt && state->antenna_gpio)
6795 state->m_GPIO |= state->antenna_gpio;
6796 else
6797 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006798
6799 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006800
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006801 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6802 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006803
6804 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006805
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006806 /* Load firmware and initialize DRX-K */
6807 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006808 if (config->load_firmware_sync) {
6809 const struct firmware *fw = NULL;
6810
6811 status = request_firmware(&fw, state->microcode_name,
6812 state->i2c->dev.parent);
6813 if (status < 0)
6814 fw = NULL;
6815 load_firmware_cb(fw, state);
6816 } else {
6817 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006818 state->microcode_name,
6819 state->i2c->dev.parent,
6820 GFP_KERNEL,
6821 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006822 if (status < 0) {
6823 printk(KERN_ERR
6824 "drxk: failed to request a firmware\n");
6825 return NULL;
6826 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006827 }
6828 } else if (init_drxk(state) < 0)
6829 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006830
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006831
6832 /* Initialize stats */
6833 p = &state->frontend.dtv_property_cache;
6834 p->strength.len = 1;
6835 p->cnr.len = 1;
6836 p->block_error.len = 1;
6837 p->block_count.len = 1;
6838 p->pre_bit_error.len = 1;
6839 p->pre_bit_count.len = 1;
6840 p->post_bit_error.len = 1;
6841 p->post_bit_count.len = 1;
6842
6843 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6844 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6845 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6846 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6847 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6848 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6849 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6850 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6851
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006852 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006853 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006854
6855error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006856 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006857 kfree(state);
6858 return NULL;
6859}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006860EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006861
6862MODULE_DESCRIPTION("DRX-K driver");
6863MODULE_AUTHOR("Ralph Metzler");
6864MODULE_LICENSE("GPL");