blob: 0e40832a9a594ecc72c29cf85f32d0893699741a [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;
2658 /* No negative MER, clip to zero */
2659 if (iMER > c)
2660 iMER -= c;
2661 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002662 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002663 }
2664 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002665
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002666error:
2667 if (status < 0)
2668 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002669 return status;
2670}
2671
2672static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2673{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002674 dprintk(1, "\n");
2675
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002676 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002677 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678 case OM_DVBT:
2679 return GetDVBTSignalToNoise(state, pSignalToNoise);
2680 case OM_QAM_ITU_A:
2681 case OM_QAM_ITU_C:
2682 return GetQAMSignalToNoise(state, pSignalToNoise);
2683 default:
2684 break;
2685 }
2686 return 0;
2687}
2688
2689#if 0
2690static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2691{
2692 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2693 int status = 0;
2694
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002695 dprintk(1, "\n");
2696
Oliver Endrissebc7de22011-07-03 13:49:44 -03002697 static s32 QE_SN[] = {
2698 51, /* QPSK 1/2 */
2699 69, /* QPSK 2/3 */
2700 79, /* QPSK 3/4 */
2701 89, /* QPSK 5/6 */
2702 97, /* QPSK 7/8 */
2703 108, /* 16-QAM 1/2 */
2704 131, /* 16-QAM 2/3 */
2705 146, /* 16-QAM 3/4 */
2706 156, /* 16-QAM 5/6 */
2707 160, /* 16-QAM 7/8 */
2708 165, /* 64-QAM 1/2 */
2709 187, /* 64-QAM 2/3 */
2710 202, /* 64-QAM 3/4 */
2711 216, /* 64-QAM 5/6 */
2712 225, /* 64-QAM 7/8 */
2713 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002714
2715 *pQuality = 0;
2716
2717 do {
2718 s32 SignalToNoise = 0;
2719 u16 Constellation = 0;
2720 u16 CodeRate = 0;
2721 u32 SignalToNoiseRel;
2722 u32 BERQuality;
2723
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002724 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2725 if (status < 0)
2726 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002727 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002728 if (status < 0)
2729 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002730 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2731
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002732 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002733 if (status < 0)
2734 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002735 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2736
2737 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2738 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2739 break;
2740 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002741 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742 BERQuality = 100;
2743
Oliver Endrissebc7de22011-07-03 13:49:44 -03002744 if (SignalToNoiseRel < -70)
2745 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002746 else if (SignalToNoiseRel < 30)
2747 *pQuality = ((SignalToNoiseRel + 70) *
2748 BERQuality) / 100;
2749 else
2750 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002751 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002752 return 0;
2753};
2754
Oliver Endrissebc7de22011-07-03 13:49:44 -03002755static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756{
2757 int status = 0;
2758 *pQuality = 0;
2759
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002760 dprintk(1, "\n");
2761
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 do {
2763 u32 SignalToNoise = 0;
2764 u32 BERQuality = 100;
2765 u32 SignalToNoiseRel = 0;
2766
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002767 status = GetQAMSignalToNoise(state, &SignalToNoise);
2768 if (status < 0)
2769 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002770
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002771 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002772 case QAM_16:
2773 SignalToNoiseRel = SignalToNoise - 200;
2774 break;
2775 case QAM_32:
2776 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002777 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002778 case QAM_64:
2779 SignalToNoiseRel = SignalToNoise - 260;
2780 break;
2781 case QAM_128:
2782 SignalToNoiseRel = SignalToNoise - 290;
2783 break;
2784 default:
2785 case QAM_256:
2786 SignalToNoiseRel = SignalToNoise - 320;
2787 break;
2788 }
2789
2790 if (SignalToNoiseRel < -70)
2791 *pQuality = 0;
2792 else if (SignalToNoiseRel < 30)
2793 *pQuality = ((SignalToNoiseRel + 70) *
2794 BERQuality) / 100;
2795 else
2796 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002797 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002798
2799 return status;
2800}
2801
2802static int GetQuality(struct drxk_state *state, s32 *pQuality)
2803{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002804 dprintk(1, "\n");
2805
Oliver Endrissebc7de22011-07-03 13:49:44 -03002806 switch (state->m_OperationMode) {
2807 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002808 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002809 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002810 return GetDVBCQuality(state, pQuality);
2811 default:
2812 break;
2813 }
2814
2815 return 0;
2816}
2817#endif
2818
2819/* Free data ram in SIO HI */
2820#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2821#define SIO_HI_RA_RAM_USR_END__A 0x420060
2822
2823#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2824#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2825#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2826#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2827
2828#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2829#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2830#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2831
2832static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2833{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002834 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002835
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002836 dprintk(1, "\n");
2837
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002838 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002839 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002841 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002842
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002843 if (state->no_i2c_bridge)
2844 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002845
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002846 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2847 if (status < 0)
2848 goto error;
2849 if (bEnableBridge) {
2850 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 -03002851 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002852 goto error;
2853 } else {
2854 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2855 if (status < 0)
2856 goto error;
2857 }
2858
2859 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2860
2861error:
2862 if (status < 0)
2863 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002864 return status;
2865}
2866
Oliver Endrissebc7de22011-07-03 13:49:44 -03002867static int SetPreSaw(struct drxk_state *state,
2868 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002869{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002870 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002871
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002872 dprintk(1, "\n");
2873
Oliver Endrissebc7de22011-07-03 13:49:44 -03002874 if ((pPreSawCfg == NULL)
2875 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002876 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002877
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002878 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002879error:
2880 if (status < 0)
2881 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002882 return status;
2883}
2884
2885static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002886 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002887{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002888 u16 blStatus = 0;
2889 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2890 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2891 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002892 unsigned long end;
2893
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002894 dprintk(1, "\n");
2895
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002897 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2898 if (status < 0)
2899 goto error;
2900 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2901 if (status < 0)
2902 goto error;
2903 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2904 if (status < 0)
2905 goto error;
2906 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2907 if (status < 0)
2908 goto error;
2909 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2910 if (status < 0)
2911 goto error;
2912 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2913 if (status < 0)
2914 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002915
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002916 end = jiffies + msecs_to_jiffies(timeOut);
2917 do {
2918 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2919 if (status < 0)
2920 goto error;
2921 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2922 if (blStatus == 0x1) {
2923 printk(KERN_ERR "drxk: SIO not ready\n");
2924 status = -EINVAL;
2925 goto error2;
2926 }
2927error:
2928 if (status < 0)
2929 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2930error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002931 mutex_unlock(&state->mutex);
2932 return status;
2933
2934}
2935
Oliver Endrissebc7de22011-07-03 13:49:44 -03002936static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002937{
2938 u16 data = 0;
2939 int status;
2940
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002941 dprintk(1, "\n");
2942
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002943 /* Start measurement */
2944 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2945 if (status < 0)
2946 goto error;
2947 status = write16(state, IQM_AF_START_LOCK__A, 1);
2948 if (status < 0)
2949 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002950
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002951 *count = 0;
2952 status = read16(state, IQM_AF_PHASE0__A, &data);
2953 if (status < 0)
2954 goto error;
2955 if (data == 127)
2956 *count = *count + 1;
2957 status = read16(state, IQM_AF_PHASE1__A, &data);
2958 if (status < 0)
2959 goto error;
2960 if (data == 127)
2961 *count = *count + 1;
2962 status = read16(state, IQM_AF_PHASE2__A, &data);
2963 if (status < 0)
2964 goto error;
2965 if (data == 127)
2966 *count = *count + 1;
2967
2968error:
2969 if (status < 0)
2970 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002971 return status;
2972}
2973
2974static int ADCSynchronization(struct drxk_state *state)
2975{
2976 u16 count = 0;
2977 int status;
2978
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002979 dprintk(1, "\n");
2980
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002981 status = ADCSyncMeasurement(state, &count);
2982 if (status < 0)
2983 goto error;
2984
2985 if (count == 1) {
2986 /* Try sampling on a diffrent edge */
2987 u16 clkNeg = 0;
2988
2989 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2990 if (status < 0)
2991 goto error;
Dan Carpenter22a09b42012-06-26 04:40:38 -03002992 if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002993 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2994 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2995 clkNeg |=
2996 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2997 } else {
2998 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2999 clkNeg |=
3000 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
3001 }
3002 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
3003 if (status < 0)
3004 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003005 status = ADCSyncMeasurement(state, &count);
3006 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003007 goto error;
3008 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003010 if (count < 2)
3011 status = -EINVAL;
3012error:
3013 if (status < 0)
3014 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003015 return status;
3016}
3017
3018static int SetFrequencyShifter(struct drxk_state *state,
3019 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003020 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003021{
3022 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003023 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024 u32 fmFrequencyShift = 0;
3025 bool tunerMirror = !state->m_bMirrorFreqSpect;
3026 u32 adcFreq;
3027 bool adcFlip;
3028 int status;
3029 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003030 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003031 u32 frequencyShift;
3032 bool imageToSelect;
3033
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003034 dprintk(1, "\n");
3035
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003037 Program frequency shifter
3038 No need to account for mirroring on RF
3039 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003040 if (isDTV) {
3041 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3042 (state->m_OperationMode == OM_QAM_ITU_C) ||
3043 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003044 selectPosImage = true;
3045 else
3046 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003047 }
3048 if (tunerMirror)
3049 /* tuner doesn't mirror */
3050 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003051 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003052 else
3053 /* tuner mirrors */
3054 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003055 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003056 if (ifFreqActual > samplingFrequency / 2) {
3057 /* adc mirrors */
3058 adcFreq = samplingFrequency - ifFreqActual;
3059 adcFlip = true;
3060 } else {
3061 /* adc doesn't mirror */
3062 adcFreq = ifFreqActual;
3063 adcFlip = false;
3064 }
3065
3066 frequencyShift = adcFreq;
3067 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003068 adcFlip ^ selectPosImage;
3069 state->m_IqmFsRateOfs =
3070 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003071
3072 if (imageToSelect)
3073 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3074
3075 /* Program frequency shifter with tuner offset compensation */
3076 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003077 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3078 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003079 if (status < 0)
3080 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003081 return status;
3082}
3083
3084static int InitAGC(struct drxk_state *state, bool isDTV)
3085{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003086 u16 ingainTgt = 0;
3087 u16 ingainTgtMin = 0;
3088 u16 ingainTgtMax = 0;
3089 u16 clpCyclen = 0;
3090 u16 clpSumMin = 0;
3091 u16 clpDirTo = 0;
3092 u16 snsSumMin = 0;
3093 u16 snsSumMax = 0;
3094 u16 clpSumMax = 0;
3095 u16 snsDirTo = 0;
3096 u16 kiInnergainMin = 0;
3097 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003098 u16 ifIaccuHiTgtMin = 0;
3099 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003100 u16 data = 0;
3101 u16 fastClpCtrlDelay = 0;
3102 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003103 int status = 0;
3104
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003105 dprintk(1, "\n");
3106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003107 /* Common settings */
3108 snsSumMax = 1023;
3109 ifIaccuHiTgtMin = 2047;
3110 clpCyclen = 500;
3111 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003112
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003113 /* AGCInit() not available for DVBT; init done in microcode */
3114 if (!IsQAM(state)) {
3115 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3116 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003117 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003118
3119 /* FIXME: Analog TV AGC require different settings */
3120
3121 /* Standard specific settings */
3122 clpSumMin = 8;
3123 clpDirTo = (u16) -9;
3124 clpCtrlMode = 0;
3125 snsSumMin = 8;
3126 snsDirTo = (u16) -9;
3127 kiInnergainMin = (u16) -1030;
3128 ifIaccuHiTgtMax = 0x2380;
3129 ifIaccuHiTgt = 0x2380;
3130 ingainTgtMin = 0x0511;
3131 ingainTgt = 0x0511;
3132 ingainTgtMax = 5119;
3133 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003135 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3136 if (status < 0)
3137 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003138
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003139 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3173 if (status < 0)
3174 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003176 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3183 if (status < 0)
3184 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003185
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003186 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3187 if (status < 0)
3188 goto error;
3189 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3190 if (status < 0)
3191 goto error;
3192 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3193 if (status < 0)
3194 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003195
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003196 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3197 if (status < 0)
3198 goto error;
3199 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3200 if (status < 0)
3201 goto error;
3202 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3203 if (status < 0)
3204 goto error;
3205 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3206 if (status < 0)
3207 goto error;
3208 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3209 if (status < 0)
3210 goto error;
3211 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3233 if (status < 0)
3234 goto error;
3235 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3236 if (status < 0)
3237 goto error;
3238 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3239 if (status < 0)
3240 goto error;
3241 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3242 if (status < 0)
3243 goto error;
3244 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3245 if (status < 0)
3246 goto error;
3247 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3248 if (status < 0)
3249 goto error;
3250 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3251 if (status < 0)
3252 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003254 /* Initialize inner-loop KI gain factors */
3255 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3256 if (status < 0)
3257 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003258
3259 data = 0x0657;
3260 data &= ~SCU_RAM_AGC_KI_RF__M;
3261 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3262 data &= ~SCU_RAM_AGC_KI_IF__M;
3263 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3264
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003265 status = write16(state, SCU_RAM_AGC_KI__A, data);
3266error:
3267 if (status < 0)
3268 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003269 return status;
3270}
3271
Oliver Endrissebc7de22011-07-03 13:49:44 -03003272static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273{
3274 int status;
3275
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003276 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003277 if (packetErr == NULL)
3278 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3279 else
3280 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3281 if (status < 0)
3282 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 return status;
3284}
3285
3286static int DVBTScCommand(struct drxk_state *state,
3287 u16 cmd, u16 subcmd,
3288 u16 param0, u16 param1, u16 param2,
3289 u16 param3, u16 param4)
3290{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003291 u16 curCmd = 0;
3292 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003293 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003294 u16 scExec = 0;
3295 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003297 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003298 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299 if (scExec != 1) {
3300 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003301 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003302 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003303 if (status < 0)
3304 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305
3306 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003307 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308 do {
3309 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003310 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311 retryCnt++;
3312 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003313 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3314 goto error;
3315
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003316 /* Write sub-command */
3317 switch (cmd) {
3318 /* All commands using sub-cmd */
3319 case OFDM_SC_RA_RAM_CMD_PROC_START:
3320 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3321 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003322 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3323 if (status < 0)
3324 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003325 break;
3326 default:
3327 /* Do nothing */
3328 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003329 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330
3331 /* Write needed parameters and the command */
3332 switch (cmd) {
3333 /* All commands using 5 parameters */
3334 /* All commands using 4 parameters */
3335 /* All commands using 3 parameters */
3336 /* All commands using 2 parameters */
3337 case OFDM_SC_RA_RAM_CMD_PROC_START:
3338 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3339 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003340 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 /* All commands using 1 parameters */
3342 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3343 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003344 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345 /* All commands using 0 parameters */
3346 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3347 case OFDM_SC_RA_RAM_CMD_NULL:
3348 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003349 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003350 break;
3351 default:
3352 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003353 status = -EINVAL;
3354 }
3355 if (status < 0)
3356 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357
3358 /* Wait until sc is ready processing command */
3359 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003360 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003362 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003363 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003364 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003365 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3366 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003367
3368 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003369 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003370 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003372 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003373 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003374 if (status < 0)
3375 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376
3377 /* Retreive results parameters from SC */
3378 switch (cmd) {
3379 /* All commands yielding 5 results */
3380 /* All commands yielding 4 results */
3381 /* All commands yielding 3 results */
3382 /* All commands yielding 2 results */
3383 /* All commands yielding 1 result */
3384 case OFDM_SC_RA_RAM_CMD_USER_IO:
3385 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003386 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003387 /* All commands yielding 0 results */
3388 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3389 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3390 case OFDM_SC_RA_RAM_CMD_PROC_START:
3391 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3392 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3393 case OFDM_SC_RA_RAM_CMD_NULL:
3394 break;
3395 default:
3396 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003397 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003398 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003399 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003400error:
3401 if (status < 0)
3402 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403 return status;
3404}
3405
Oliver Endrissebc7de22011-07-03 13:49:44 -03003406static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003407{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003408 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003409 int status;
3410
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003411 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003412 status = CtrlPowerMode(state, &powerMode);
3413 if (status < 0)
3414 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003415 return status;
3416}
3417
Oliver Endrissebc7de22011-07-03 13:49:44 -03003418static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003419{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003420 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003422 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003424 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003426 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003427 if (status < 0)
3428 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429 return status;
3430}
3431
3432#define DEFAULT_FR_THRES_8K 4000
3433static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3434{
3435
3436 int status;
3437
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003438 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003439 if (*enabled == true) {
3440 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003441 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003442 DEFAULT_FR_THRES_8K);
3443 } else {
3444 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003445 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003446 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003447 if (status < 0)
3448 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003449
3450 return status;
3451}
3452
3453static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3454 struct DRXKCfgDvbtEchoThres_t *echoThres)
3455{
3456 u16 data = 0;
3457 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003458
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003459 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003460 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3461 if (status < 0)
3462 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003463
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003464 switch (echoThres->fftMode) {
3465 case DRX_FFTMODE_2K:
3466 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3467 data |= ((echoThres->threshold <<
3468 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3469 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003470 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003471 case DRX_FFTMODE_8K:
3472 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3473 data |= ((echoThres->threshold <<
3474 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3475 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003476 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003477 default:
3478 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003479 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003480
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003481 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3482error:
3483 if (status < 0)
3484 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003485 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003486}
3487
3488static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003489 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003490{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003491 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003492
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003493 dprintk(1, "\n");
3494
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003495 switch (*speed) {
3496 case DRXK_DVBT_SQI_SPEED_FAST:
3497 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3498 case DRXK_DVBT_SQI_SPEED_SLOW:
3499 break;
3500 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003501 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003502 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003503 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003504 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003505error:
3506 if (status < 0)
3507 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508 return status;
3509}
3510
3511/*============================================================================*/
3512
3513/**
3514* \brief Activate DVBT specific presets
3515* \param demod instance of demodulator.
3516* \return DRXStatus_t.
3517*
3518* Called in DVBTSetStandard
3519*
3520*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003521static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003522{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003523 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003524 bool setincenable = false;
3525 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003526
Oliver Endrissebc7de22011-07-03 13:49:44 -03003527 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3528 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003529
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003530 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003531 status = DVBTCtrlSetIncEnable(state, &setincenable);
3532 if (status < 0)
3533 goto error;
3534 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3535 if (status < 0)
3536 goto error;
3537 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3538 if (status < 0)
3539 goto error;
3540 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3541 if (status < 0)
3542 goto error;
3543 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3544error:
3545 if (status < 0)
3546 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003547 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003549
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003550/*============================================================================*/
3551
3552/**
3553* \brief Initialize channelswitch-independent settings for DVBT.
3554* \param demod instance of demodulator.
3555* \return DRXStatus_t.
3556*
3557* For ROM code channel filter taps are loaded from the bootloader. For microcode
3558* the DVB-T taps from the drxk_filters.h are used.
3559*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003560static int SetDVBTStandard(struct drxk_state *state,
3561 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003562{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003563 u16 cmdResult = 0;
3564 u16 data = 0;
3565 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003566
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003567 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003568
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003569 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003570 /* added antenna switch */
3571 SwitchAntennaToDVBT(state);
3572 /* send OFDM reset command */
3573 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 -03003574 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003575 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003576
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003577 /* send OFDM setenv command */
3578 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3579 if (status < 0)
3580 goto error;
3581
3582 /* reset datapath for OFDM, processors first */
3583 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3584 if (status < 0)
3585 goto error;
3586 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3587 if (status < 0)
3588 goto error;
3589 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3590 if (status < 0)
3591 goto error;
3592
3593 /* IQM setup */
3594 /* synchronize on ofdstate->m_festart */
3595 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3596 if (status < 0)
3597 goto error;
3598 /* window size for clipping ADC detection */
3599 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3600 if (status < 0)
3601 goto error;
3602 /* window size for for sense pre-SAW detection */
3603 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3604 if (status < 0)
3605 goto error;
3606 /* sense threshold for sense pre-SAW detection */
3607 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3608 if (status < 0)
3609 goto error;
3610 status = SetIqmAf(state, true);
3611 if (status < 0)
3612 goto error;
3613
3614 status = write16(state, IQM_AF_AGC_RF__A, 0);
3615 if (status < 0)
3616 goto error;
3617
3618 /* Impulse noise cruncher setup */
3619 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3620 if (status < 0)
3621 goto error;
3622 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3623 if (status < 0)
3624 goto error;
3625 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3626 if (status < 0)
3627 goto error;
3628
3629 status = write16(state, IQM_RC_STRETCH__A, 16);
3630 if (status < 0)
3631 goto error;
3632 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3636 if (status < 0)
3637 goto error;
3638 status = write16(state, IQM_CF_SCALE__A, 1600);
3639 if (status < 0)
3640 goto error;
3641 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3642 if (status < 0)
3643 goto error;
3644
3645 /* virtual clipping threshold for clipping ADC detection */
3646 status = write16(state, IQM_AF_CLP_TH__A, 448);
3647 if (status < 0)
3648 goto error;
3649 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3650 if (status < 0)
3651 goto error;
3652
3653 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3654 if (status < 0)
3655 goto error;
3656
3657 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3658 if (status < 0)
3659 goto error;
3660 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3661 if (status < 0)
3662 goto error;
3663 /* enable power measurement interrupt */
3664 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3665 if (status < 0)
3666 goto error;
3667 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3668 if (status < 0)
3669 goto error;
3670
3671 /* IQM will not be reset from here, sync ADC and update/init AGC */
3672 status = ADCSynchronization(state);
3673 if (status < 0)
3674 goto error;
3675 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3676 if (status < 0)
3677 goto error;
3678
3679 /* Halt SCU to enable safe non-atomic accesses */
3680 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3681 if (status < 0)
3682 goto error;
3683
3684 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3685 if (status < 0)
3686 goto error;
3687 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3688 if (status < 0)
3689 goto error;
3690
3691 /* Set Noise Estimation notch width and enable DC fix */
3692 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3693 if (status < 0)
3694 goto error;
3695 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3696 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3697 if (status < 0)
3698 goto error;
3699
3700 /* Activate SCU to enable SCU commands */
3701 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3702 if (status < 0)
3703 goto error;
3704
3705 if (!state->m_DRXK_A3_ROM_CODE) {
3706 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3707 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3708 if (status < 0)
3709 goto error;
3710 }
3711
3712 /* OFDM_SC setup */
3713#ifdef COMPILE_FOR_NONRT
3714 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3715 if (status < 0)
3716 goto error;
3717 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3718 if (status < 0)
3719 goto error;
3720#endif
3721
3722 /* FEC setup */
3723 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3724 if (status < 0)
3725 goto error;
3726
3727
3728#ifdef COMPILE_FOR_NONRT
3729 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3730 if (status < 0)
3731 goto error;
3732#else
3733 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3734 if (status < 0)
3735 goto error;
3736#endif
3737 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3738 if (status < 0)
3739 goto error;
3740
3741 /* Setup MPEG bus */
3742 status = MPEGTSDtoSetup(state, OM_DVBT);
3743 if (status < 0)
3744 goto error;
3745 /* Set DVBT Presets */
3746 status = DVBTActivatePresets(state);
3747 if (status < 0)
3748 goto error;
3749
3750error:
3751 if (status < 0)
3752 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003753 return status;
3754}
3755
3756/*============================================================================*/
3757/**
3758* \brief Start dvbt demodulating for channel.
3759* \param demod instance of demodulator.
3760* \return DRXStatus_t.
3761*/
3762static int DVBTStart(struct drxk_state *state)
3763{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003764 u16 param1;
3765 int status;
3766 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003767
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003768 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003769 /* Start correct processes to get in lock */
3770 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003771 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3772 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3773 if (status < 0)
3774 goto error;
3775 /* Start FEC OC */
3776 status = MPEGTSStart(state);
3777 if (status < 0)
3778 goto error;
3779 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3780 if (status < 0)
3781 goto error;
3782error:
3783 if (status < 0)
3784 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003785 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786}
3787
3788
3789/*============================================================================*/
3790
3791/**
3792* \brief Set up dvbt demodulator for channel.
3793* \param demod instance of demodulator.
3794* \return DRXStatus_t.
3795* // original DVBTSetChannel()
3796*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003797static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3798 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003800 u16 cmdResult = 0;
3801 u16 transmissionParams = 0;
3802 u16 operationMode = 0;
3803 u32 iqmRcRateOfs = 0;
3804 u32 bandwidth = 0;
3805 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003806 int status;
3807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003808 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003809
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003810 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3811 if (status < 0)
3812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003814 /* Halt SCU to enable safe non-atomic accesses */
3815 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3816 if (status < 0)
3817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /* Stop processors */
3820 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3821 if (status < 0)
3822 goto error;
3823 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3824 if (status < 0)
3825 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003826
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 /* Mandatory fix, always stop CP, required to set spl offset back to
3828 hardware default (is set to 0 by ucode during pilot detection */
3829 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3830 if (status < 0)
3831 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003832
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003834
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003836 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003837 case TRANSMISSION_MODE_AUTO:
3838 default:
3839 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3840 /* fall through , try first guess DRX_FFTMODE_8K */
3841 case TRANSMISSION_MODE_8K:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003843 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 case TRANSMISSION_MODE_2K:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003846 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003847 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003848
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003850 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003851 default:
3852 case GUARD_INTERVAL_AUTO:
3853 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3854 /* fall through , try first guess DRX_GUARD_1DIV4 */
3855 case GUARD_INTERVAL_1_4:
3856 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003857 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003858 case GUARD_INTERVAL_1_32:
3859 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003860 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003861 case GUARD_INTERVAL_1_16:
3862 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003863 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003864 case GUARD_INTERVAL_1_8:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003866 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003867 }
3868
3869 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003870 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003871 case HIERARCHY_AUTO:
3872 case HIERARCHY_NONE:
3873 default:
3874 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3875 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3876 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3877 /* break; */
3878 case HIERARCHY_1:
3879 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3880 break;
3881 case HIERARCHY_2:
3882 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3883 break;
3884 case HIERARCHY_4:
3885 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3886 break;
3887 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003888
3889
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003890 /* modulation */
3891 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 case QAM_AUTO:
3893 default:
3894 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3895 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3896 case QAM_64:
3897 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3898 break;
3899 case QPSK:
3900 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3901 break;
3902 case QAM_16:
3903 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3904 break;
3905 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003906#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003907 /* No hierachical channels support in BDA */
3908 /* Priority (only for hierarchical channels) */
3909 switch (channel->priority) {
3910 case DRX_PRIORITY_LOW:
3911 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3912 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3913 OFDM_EC_SB_PRIOR_LO);
3914 break;
3915 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003916 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003917 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3918 OFDM_EC_SB_PRIOR_HI));
3919 break;
3920 case DRX_PRIORITY_UNKNOWN: /* fall through */
3921 default:
3922 status = -EINVAL;
3923 goto error;
3924 }
3925#else
3926 /* Set Priorty high */
3927 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3928 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3929 if (status < 0)
3930 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003931#endif
3932
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003933 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003934 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003935 case FEC_AUTO:
3936 default:
3937 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3938 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3939 case FEC_2_3:
3940 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3941 break;
3942 case FEC_1_2:
3943 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3944 break;
3945 case FEC_3_4:
3946 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3947 break;
3948 case FEC_5_6:
3949 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3950 break;
3951 case FEC_7_8:
3952 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3953 break;
3954 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003956 /* SAW filter selection: normaly not necesarry, but if wanted
3957 the application can select a SAW filter via the driver by using UIOs */
3958 /* First determine real bandwidth (Hz) */
3959 /* Also set delay for impulse noise cruncher */
3960 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3961 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3962 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003963 switch (state->props.bandwidth_hz) {
3964 case 0:
3965 state->props.bandwidth_hz = 8000000;
3966 /* fall though */
3967 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003968 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3969 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003970 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003971 goto error;
3972 /* cochannel protection for PAL 8 MHz */
3973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3974 if (status < 0)
3975 goto error;
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3977 if (status < 0)
3978 goto error;
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3980 if (status < 0)
3981 goto error;
3982 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3983 if (status < 0)
3984 goto error;
3985 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003986 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003987 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3988 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3989 if (status < 0)
3990 goto error;
3991 /* cochannel protection for PAL 7 MHz */
3992 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3993 if (status < 0)
3994 goto error;
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3996 if (status < 0)
3997 goto error;
3998 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3999 if (status < 0)
4000 goto error;
4001 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4002 if (status < 0)
4003 goto error;
4004 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004005 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004006 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
4007 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
4008 if (status < 0)
4009 goto error;
4010 /* cochannel protection for NTSC 6 MHz */
4011 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
4012 if (status < 0)
4013 goto error;
4014 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4015 if (status < 0)
4016 goto error;
4017 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4018 if (status < 0)
4019 goto error;
4020 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4021 if (status < 0)
4022 goto error;
4023 break;
4024 default:
4025 status = -EINVAL;
4026 goto error;
4027 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004028
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004029 if (iqmRcRateOfs == 0) {
4030 /* Now compute IQM_RC_RATE_OFS
4031 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4032 =>
4033 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4034 */
4035 /* (SysFreq / BandWidth) * (2^28) */
4036 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4037 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4038 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4039 iqmRcRateOfs = Frac28a((u32)
4040 ((state->m_sysClockFreq *
4041 1000) / 3), bandwidth);
4042 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4043 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4044 iqmRcRateOfs += 0x80L;
4045 iqmRcRateOfs = iqmRcRateOfs >> 7;
4046 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4047 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4048 }
4049
4050 iqmRcRateOfs &=
4051 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4052 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4053 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4054 if (status < 0)
4055 goto error;
4056
4057 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004058
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004059#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004060 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4061 if (status < 0)
4062 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004063#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004064 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4065 if (status < 0)
4066 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004067
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004068 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004069
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004070 /* Activate SCU to enable SCU commands */
4071 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4072 if (status < 0)
4073 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004074
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004075 /* Enable SC after setting all other parameters */
4076 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4077 if (status < 0)
4078 goto error;
4079 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4080 if (status < 0)
4081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
4083
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004084 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4085 if (status < 0)
4086 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004088 /* Write SC parameter registers, set all AUTO flags in operation mode */
4089 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4090 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4091 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4092 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4093 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4094 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4095 0, transmissionParams, param1, 0, 0, 0);
4096 if (status < 0)
4097 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004098
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004099 if (!state->m_DRXK_A3_ROM_CODE)
4100 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4101error:
4102 if (status < 0)
4103 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004104
4105 return status;
4106}
4107
4108
4109/*============================================================================*/
4110
4111/**
4112* \brief Retreive lock status .
4113* \param demod Pointer to demodulator instance.
4114* \param lockStat Pointer to lock status structure.
4115* \return DRXStatus_t.
4116*
4117*/
4118static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4119{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004120 int status;
4121 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4122 OFDM_SC_RA_RAM_LOCK_FEC__M);
4123 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4124 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125
Oliver Endrissebc7de22011-07-03 13:49:44 -03004126 u16 ScRaRamLock = 0;
4127 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004128
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004129 dprintk(1, "\n");
4130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004131 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004132 /* driver 0.9.0 */
4133 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004134 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004135 if (status < 0)
4136 goto end;
4137 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4138 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004139
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004140 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004141 if (status < 0)
4142 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143
Oliver Endrissebc7de22011-07-03 13:49:44 -03004144 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4145 *pLockStatus = MPEG_LOCK;
4146 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4147 *pLockStatus = FEC_LOCK;
4148 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4149 *pLockStatus = DEMOD_LOCK;
4150 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4151 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004152end:
4153 if (status < 0)
4154 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004155
Oliver Endrissebc7de22011-07-03 13:49:44 -03004156 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004157}
4158
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004160{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004161 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004162 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004163
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004164 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004165 status = CtrlPowerMode(state, &powerMode);
4166 if (status < 0)
4167 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004168
Oliver Endrissebc7de22011-07-03 13:49:44 -03004169 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004170}
4171
4172
Oliver Endrissebc7de22011-07-03 13:49:44 -03004173/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004174static int PowerDownQAM(struct drxk_state *state)
4175{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004176 u16 data = 0;
4177 u16 cmdResult;
4178 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004179
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004180 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004181 status = read16(state, SCU_COMM_EXEC__A, &data);
4182 if (status < 0)
4183 goto error;
4184 if (data == SCU_COMM_EXEC_ACTIVE) {
4185 /*
4186 STOP demodulator
4187 QAM and HW blocks
4188 */
4189 /* stop all comstate->m_exec */
4190 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004191 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004192 goto error;
4193 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 -03004194 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004195 goto error;
4196 }
4197 /* powerdown AFE */
4198 status = SetIqmAf(state, false);
4199
4200error:
4201 if (status < 0)
4202 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004203
Oliver Endrissebc7de22011-07-03 13:49:44 -03004204 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004205}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004206
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004207/*============================================================================*/
4208
4209/**
4210* \brief Setup of the QAM Measurement intervals for signal quality
4211* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004212* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004213* \return DRXStatus_t.
4214*
4215* NOTE:
4216* Take into account that for certain settings the errorcounters can overflow.
4217* The implementation does not check this.
4218*
4219*/
4220static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004221 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004222 u32 symbolRate)
4223{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004224 u32 fecBitsDesired = 0; /* BER accounting period */
4225 u32 fecRsPeriodTotal = 0; /* Total period */
4226 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4227 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004228 int status = 0;
4229
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004230 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004231
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004232 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004233 /* fecBitsDesired = symbolRate [kHz] *
4234 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004235 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004236 SyncLoss (== 1) *
4237 ViterbiLoss (==1)
4238 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004239 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004240 case DRX_CONSTELLATION_QAM16:
4241 fecBitsDesired = 4 * symbolRate;
4242 break;
4243 case DRX_CONSTELLATION_QAM32:
4244 fecBitsDesired = 5 * symbolRate;
4245 break;
4246 case DRX_CONSTELLATION_QAM64:
4247 fecBitsDesired = 6 * symbolRate;
4248 break;
4249 case DRX_CONSTELLATION_QAM128:
4250 fecBitsDesired = 7 * symbolRate;
4251 break;
4252 case DRX_CONSTELLATION_QAM256:
4253 fecBitsDesired = 8 * symbolRate;
4254 break;
4255 default:
4256 status = -EINVAL;
4257 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004258 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004259 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004261 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4262 fecBitsDesired *= 500; /* meas. period [ms] */
4263
4264 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4265 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4266 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4267
4268 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4269 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4270 if (fecRsPrescale == 0) {
4271 /* Divide by zero (though impossible) */
4272 status = -EINVAL;
4273 if (status < 0)
4274 goto error;
4275 }
4276 fecRsPeriod =
4277 ((u16) fecRsPeriodTotal +
4278 (fecRsPrescale >> 1)) / fecRsPrescale;
4279
4280 /* write corresponding registers */
4281 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4288error:
4289 if (status < 0)
4290 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004291 return status;
4292}
4293
Oliver Endrissebc7de22011-07-03 13:49:44 -03004294static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004295{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004296 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004297
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004298 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004299 /* QAM Equalizer Setup */
4300 /* Equalizer */
4301 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4314 if (status < 0)
4315 goto error;
4316 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4317 if (status < 0)
4318 goto error;
4319 /* Decision Feedback Equalizer */
4320 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4324 if (status < 0)
4325 goto error;
4326 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4327 if (status < 0)
4328 goto error;
4329 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4330 if (status < 0)
4331 goto error;
4332 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4333 if (status < 0)
4334 goto error;
4335 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4336 if (status < 0)
4337 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004339 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
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 Slicer Settings */
4350 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4351 if (status < 0)
4352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004354 /* QAM Loop Controller Coeficients */
4355 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4356 if (status < 0)
4357 goto error;
4358 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4377 if (status < 0)
4378 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004379
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004380 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4387 if (status < 0)
4388 goto error;
4389 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4390 if (status < 0)
4391 goto error;
4392 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4393 if (status < 0)
4394 goto error;
4395 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4414 if (status < 0)
4415 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004416
4417
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004418 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004419
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004420 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4424 if (status < 0)
4425 goto error;
4426 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4427 if (status < 0)
4428 goto error;
4429 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4430 if (status < 0)
4431 goto error;
4432 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4433 if (status < 0)
4434 goto error;
4435 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4436 if (status < 0)
4437 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004438
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004439 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4446 if (status < 0)
4447 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004448
4449
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004450 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004451
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004452 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4453 if (status < 0)
4454 goto error;
4455 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4456 if (status < 0)
4457 goto error;
4458 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4459 if (status < 0)
4460 goto error;
4461 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4462 if (status < 0)
4463 goto error;
4464 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4465 if (status < 0)
4466 goto error;
4467 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4468 if (status < 0)
4469 goto error;
4470 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4471 if (status < 0)
4472 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004473
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004474error:
4475 if (status < 0)
4476 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004477 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004478}
4479
4480/*============================================================================*/
4481
4482/**
4483* \brief QAM32 specific setup
4484* \param demod instance of demod.
4485* \return DRXStatus_t.
4486*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004487static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004488{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004489 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004490
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004491 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004492
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004493 /* QAM Equalizer Setup */
4494 /* Equalizer */
4495 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4496 if (status < 0)
4497 goto error;
4498 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4511 if (status < 0)
4512 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004513
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004514 /* Decision Feedback Equalizer */
4515 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4516 if (status < 0)
4517 goto error;
4518 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4519 if (status < 0)
4520 goto error;
4521 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4522 if (status < 0)
4523 goto error;
4524 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4525 if (status < 0)
4526 goto error;
4527 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4528 if (status < 0)
4529 goto error;
4530 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4531 if (status < 0)
4532 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004533
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004534 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4541 if (status < 0)
4542 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004544 /* QAM Slicer Settings */
4545
4546 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4547 if (status < 0)
4548 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004549
4550
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004551 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004552
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004553 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4554 if (status < 0)
4555 goto error;
4556 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4575 if (status < 0)
4576 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004577
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004578 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4585 if (status < 0)
4586 goto error;
4587 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4588 if (status < 0)
4589 goto error;
4590 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4612 if (status < 0)
4613 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004614
4615
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004616 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004618 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4622 if (status < 0)
4623 goto error;
4624 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4625 if (status < 0)
4626 goto error;
4627 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4628 if (status < 0)
4629 goto error;
4630 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4634 if (status < 0)
4635 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004636
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004637 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4644 if (status < 0)
4645 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004646
4647
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004648 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004649
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004650 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4651 if (status < 0)
4652 goto error;
4653 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4654 if (status < 0)
4655 goto error;
4656 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4657 if (status < 0)
4658 goto error;
4659 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4660 if (status < 0)
4661 goto error;
4662 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4663 if (status < 0)
4664 goto error;
4665 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4666 if (status < 0)
4667 goto error;
4668 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4669error:
4670 if (status < 0)
4671 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004672 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004673}
4674
4675/*============================================================================*/
4676
4677/**
4678* \brief QAM64 specific setup
4679* \param demod instance of demod.
4680* \return DRXStatus_t.
4681*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004682static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004683{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004684 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004685
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004686 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004687 /* QAM Equalizer Setup */
4688 /* Equalizer */
4689 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4705 if (status < 0)
4706 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004708 /* Decision Feedback Equalizer */
4709 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4710 if (status < 0)
4711 goto error;
4712 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4713 if (status < 0)
4714 goto error;
4715 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4716 if (status < 0)
4717 goto error;
4718 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4719 if (status < 0)
4720 goto error;
4721 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4722 if (status < 0)
4723 goto error;
4724 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4725 if (status < 0)
4726 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004727
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004728 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4729 if (status < 0)
4730 goto error;
4731 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4732 if (status < 0)
4733 goto error;
4734 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4735 if (status < 0)
4736 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004737
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004738 /* QAM Slicer Settings */
4739 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4740 if (status < 0)
4741 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004742
4743
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004744 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004745
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004746 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4768 if (status < 0)
4769 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004770
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004771 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4772 if (status < 0)
4773 goto error;
4774 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4775 if (status < 0)
4776 goto error;
4777 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4778 if (status < 0)
4779 goto error;
4780 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4781 if (status < 0)
4782 goto error;
4783 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4805 if (status < 0)
4806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
4808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004809 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004811 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4815 if (status < 0)
4816 goto error;
4817 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4818 if (status < 0)
4819 goto error;
4820 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4821 if (status < 0)
4822 goto error;
4823 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4824 if (status < 0)
4825 goto error;
4826 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4827 if (status < 0)
4828 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004829
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004830 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4837 if (status < 0)
4838 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004839
4840
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004841 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004842
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004843 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4844 if (status < 0)
4845 goto error;
4846 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4847 if (status < 0)
4848 goto error;
4849 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4850 if (status < 0)
4851 goto error;
4852 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4853 if (status < 0)
4854 goto error;
4855 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4856 if (status < 0)
4857 goto error;
4858 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4859 if (status < 0)
4860 goto error;
4861 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4862error:
4863 if (status < 0)
4864 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004865
Oliver Endrissebc7de22011-07-03 13:49:44 -03004866 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004867}
4868
4869/*============================================================================*/
4870
4871/**
4872* \brief QAM128 specific setup
4873* \param demod: instance of demod.
4874* \return DRXStatus_t.
4875*/
4876static int SetQAM128(struct drxk_state *state)
4877{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004878 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004879
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004880 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004881 /* QAM Equalizer Setup */
4882 /* Equalizer */
4883 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4884 if (status < 0)
4885 goto error;
4886 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4887 if (status < 0)
4888 goto error;
4889 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4890 if (status < 0)
4891 goto error;
4892 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4893 if (status < 0)
4894 goto error;
4895 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4896 if (status < 0)
4897 goto error;
4898 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4899 if (status < 0)
4900 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004901
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004902 /* Decision Feedback Equalizer */
4903 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4907 if (status < 0)
4908 goto error;
4909 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4910 if (status < 0)
4911 goto error;
4912 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4913 if (status < 0)
4914 goto error;
4915 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4916 if (status < 0)
4917 goto error;
4918 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4919 if (status < 0)
4920 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004921
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004922 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4929 if (status < 0)
4930 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004931
4932
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004933 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004935 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4936 if (status < 0)
4937 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004938
4939
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004940 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004941
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004942 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4943 if (status < 0)
4944 goto error;
4945 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4964 if (status < 0)
4965 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004966
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004967 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4974 if (status < 0)
4975 goto error;
4976 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
5001 if (status < 0)
5002 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005003
5004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005005 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005006
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005007 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5008 if (status < 0)
5009 goto error;
5010 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5011 if (status < 0)
5012 goto error;
5013 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5014 if (status < 0)
5015 goto error;
5016 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5017 if (status < 0)
5018 goto error;
5019 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5020 if (status < 0)
5021 goto error;
5022 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5023 if (status < 0)
5024 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005025
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005026 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5030 if (status < 0)
5031 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005032
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005033 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5034 if (status < 0)
5035 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005036
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005037 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005038
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005039 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5040 if (status < 0)
5041 goto error;
5042 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5043 if (status < 0)
5044 goto error;
5045 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5046 if (status < 0)
5047 goto error;
5048 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5049 if (status < 0)
5050 goto error;
5051 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5052 if (status < 0)
5053 goto error;
5054 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5058error:
5059 if (status < 0)
5060 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005061
Oliver Endrissebc7de22011-07-03 13:49:44 -03005062 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005063}
5064
5065/*============================================================================*/
5066
5067/**
5068* \brief QAM256 specific setup
5069* \param demod: instance of demod.
5070* \return DRXStatus_t.
5071*/
5072static int SetQAM256(struct drxk_state *state)
5073{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005074 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005075
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005076 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005077 /* QAM Equalizer Setup */
5078 /* Equalizer */
5079 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5080 if (status < 0)
5081 goto error;
5082 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5095 if (status < 0)
5096 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005097
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005098 /* Decision Feedback Equalizer */
5099 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5100 if (status < 0)
5101 goto error;
5102 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5103 if (status < 0)
5104 goto error;
5105 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5106 if (status < 0)
5107 goto error;
5108 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5109 if (status < 0)
5110 goto error;
5111 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5112 if (status < 0)
5113 goto error;
5114 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5115 if (status < 0)
5116 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005117
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005118 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5125 if (status < 0)
5126 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005127
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005128 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005129
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005130 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5131 if (status < 0)
5132 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005133
5134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005135 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005136
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005137 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5138 if (status < 0)
5139 goto error;
5140 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5159 if (status < 0)
5160 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005161
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005162 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5163 if (status < 0)
5164 goto error;
5165 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5166 if (status < 0)
5167 goto error;
5168 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5169 if (status < 0)
5170 goto error;
5171 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5172 if (status < 0)
5173 goto error;
5174 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5175 if (status < 0)
5176 goto error;
5177 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5196 if (status < 0)
5197 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005198
5199
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005200 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005201
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005202 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5206 if (status < 0)
5207 goto error;
5208 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5209 if (status < 0)
5210 goto error;
5211 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5212 if (status < 0)
5213 goto error;
5214 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5215 if (status < 0)
5216 goto error;
5217 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5218 if (status < 0)
5219 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005220
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005221 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5228 if (status < 0)
5229 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005230
5231
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005232 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005234 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5235 if (status < 0)
5236 goto error;
5237 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5238 if (status < 0)
5239 goto error;
5240 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5241 if (status < 0)
5242 goto error;
5243 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5244 if (status < 0)
5245 goto error;
5246 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5247 if (status < 0)
5248 goto error;
5249 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5250 if (status < 0)
5251 goto error;
5252 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5253error:
5254 if (status < 0)
5255 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005256 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005257}
5258
5259
5260/*============================================================================*/
5261/**
5262* \brief Reset QAM block.
5263* \param demod: instance of demod.
5264* \param channel: pointer to channel data.
5265* \return DRXStatus_t.
5266*/
5267static int QAMResetQAM(struct drxk_state *state)
5268{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005269 int status;
5270 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005271
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005272 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005273 /* Stop QAM comstate->m_exec */
5274 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5275 if (status < 0)
5276 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005277
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005278 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5279error:
5280 if (status < 0)
5281 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005282 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005283}
5284
5285/*============================================================================*/
5286
5287/**
5288* \brief Set QAM symbolrate.
5289* \param demod: instance of demod.
5290* \param channel: pointer to channel data.
5291* \return DRXStatus_t.
5292*/
5293static int QAMSetSymbolrate(struct drxk_state *state)
5294{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005295 u32 adcFrequency = 0;
5296 u32 symbFreq = 0;
5297 u32 iqmRcRate = 0;
5298 u16 ratesel = 0;
5299 u32 lcSymbRate = 0;
5300 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005301
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005302 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005303 /* Select & calculate correct IQM rate */
5304 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5305 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005306 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5307 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005308 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005309 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005310 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005311 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005312 ratesel = 1;
5313 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5314 if (status < 0)
5315 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005316
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005317 /*
5318 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5319 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005320 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005321 if (symbFreq == 0) {
5322 /* Divide by zero */
5323 status = -EINVAL;
5324 goto error;
5325 }
5326 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5327 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5328 (1 << 23);
5329 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5330 if (status < 0)
5331 goto error;
5332 state->m_iqmRcRate = iqmRcRate;
5333 /*
5334 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5335 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005336 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005337 if (adcFrequency == 0) {
5338 /* Divide by zero */
5339 status = -EINVAL;
5340 goto error;
5341 }
5342 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5343 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5344 16);
5345 if (lcSymbRate > 511)
5346 lcSymbRate = 511;
5347 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005348
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005349error:
5350 if (status < 0)
5351 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005352 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005353}
5354
5355/*============================================================================*/
5356
5357/**
5358* \brief Get QAM lock status.
5359* \param demod: instance of demod.
5360* \param channel: pointer to channel data.
5361* \return DRXStatus_t.
5362*/
5363
5364static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5365{
5366 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005368
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005369 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005370 *pLockStatus = NOT_LOCKED;
5371 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005372 SCU_RAM_COMMAND_STANDARD_QAM |
5373 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5374 Result);
5375 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005376 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005377
5378 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005379 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005380 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005381 /* 0x4000 DEMOD LOCKED */
5382 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005383 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005384 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5385 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005386 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005387 /* 0xC000 NEVER LOCKED */
5388 /* (system will never be able to lock to the signal) */
5389 /* TODO: check this, intermediate & standard specific lock states are not
5390 taken into account here */
5391 *pLockStatus = NEVER_LOCK;
5392 }
5393 return status;
5394}
5395
5396#define QAM_MIRROR__M 0x03
5397#define QAM_MIRROR_NORMAL 0x00
5398#define QAM_MIRRORED 0x01
5399#define QAM_MIRROR_AUTO_ON 0x02
5400#define QAM_LOCKRANGE__M 0x10
5401#define QAM_LOCKRANGE_NORMAL 0x10
5402
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005403static int QAMDemodulatorCommand(struct drxk_state *state,
5404 int numberOfParameters)
5405{
5406 int status;
5407 u16 cmdResult;
5408 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5409
5410 setParamParameters[0] = state->m_Constellation; /* modulation */
5411 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5412
5413 if (numberOfParameters == 2) {
5414 u16 setEnvParameters[1] = { 0 };
5415
5416 if (state->m_OperationMode == OM_QAM_ITU_C)
5417 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5418 else
5419 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5420
5421 status = scu_command(state,
5422 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5423 1, setEnvParameters, 1, &cmdResult);
5424 if (status < 0)
5425 goto error;
5426
5427 status = scu_command(state,
5428 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5429 numberOfParameters, setParamParameters,
5430 1, &cmdResult);
5431 } else if (numberOfParameters == 4) {
5432 if (state->m_OperationMode == OM_QAM_ITU_C)
5433 setParamParameters[2] = QAM_TOP_ANNEX_C;
5434 else
5435 setParamParameters[2] = QAM_TOP_ANNEX_A;
5436
5437 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5438 /* Env parameters */
5439 /* check for LOCKRANGE Extented */
5440 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5441
5442 status = scu_command(state,
5443 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5444 numberOfParameters, setParamParameters,
5445 1, &cmdResult);
5446 } else {
5447 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5448 "count %d\n", numberOfParameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005449 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005450 }
5451
5452error:
5453 if (status < 0)
5454 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5455 status, __func__);
5456 return status;
5457}
5458
Oliver Endrissebc7de22011-07-03 13:49:44 -03005459static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5460 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005461{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005462 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005463 u16 cmdResult;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005464 int qamDemodParamCount = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005465
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005466 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005467 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005468 * STEP 1: reset demodulator
5469 * resets FEC DI and FEC RS
5470 * resets QAM block
5471 * resets SCU variables
5472 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005473 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005474 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005475 goto error;
5476 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5477 if (status < 0)
5478 goto error;
5479 status = QAMResetQAM(state);
5480 if (status < 0)
5481 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005482
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005483 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005484 * STEP 2: configure demodulator
5485 * -set params; resets IQM,QAM,FEC HW; initializes some
5486 * SCU variables
5487 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005488 status = QAMSetSymbolrate(state);
5489 if (status < 0)
5490 goto error;
5491
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005492 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005493 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005494 case QAM_256:
5495 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5496 break;
5497 case QAM_AUTO:
5498 case QAM_64:
5499 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5500 break;
5501 case QAM_16:
5502 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5503 break;
5504 case QAM_32:
5505 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5506 break;
5507 case QAM_128:
5508 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5509 break;
5510 default:
5511 status = -EINVAL;
5512 break;
5513 }
5514 if (status < 0)
5515 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005516
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005517 /* Use the 4-parameter if it's requested or we're probing for
5518 * the correct command. */
5519 if (state->qam_demod_parameter_count == 4
5520 || !state->qam_demod_parameter_count) {
5521 qamDemodParamCount = 4;
5522 status = QAMDemodulatorCommand(state, qamDemodParamCount);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005523 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005524
5525 /* Use the 2-parameter command if it was requested or if we're
5526 * probing for the correct command and the 4-parameter command
5527 * failed. */
5528 if (state->qam_demod_parameter_count == 2
5529 || (!state->qam_demod_parameter_count && status < 0)) {
5530 qamDemodParamCount = 2;
5531 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5532 }
5533
5534 if (status < 0) {
5535 dprintk(1, "Could not set demodulator parameters. Make "
5536 "sure qam_demod_parameter_count (%d) is correct for "
5537 "your firmware (%s).\n",
5538 state->qam_demod_parameter_count,
5539 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005540 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005541 } else if (!state->qam_demod_parameter_count) {
5542 dprintk(1, "Auto-probing the correct QAM demodulator command "
5543 "parameters was successful - using %d parameters.\n",
5544 qamDemodParamCount);
5545
Mauro Carvalho Chehab7eaf71882012-07-06 14:53:51 -03005546 /*
5547 * One of our commands was successful. We don't need to
5548 * auto-probe anymore, now that we got the correct command.
5549 */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005550 state->qam_demod_parameter_count = qamDemodParamCount;
5551 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005552
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005553 /*
5554 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005555 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005556 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005557#if 0
5558 status = SetFrequency(channel, tunerFreqOffset));
5559 if (status < 0)
5560 goto error;
5561#endif
5562 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5563 if (status < 0)
5564 goto error;
5565
5566 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005567 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005568 if (status < 0)
5569 goto error;
5570
5571 /* Reset default values */
5572 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5573 if (status < 0)
5574 goto error;
5575 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5576 if (status < 0)
5577 goto error;
5578
5579 /* Reset default LC values */
5580 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5581 if (status < 0)
5582 goto error;
5583 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5584 if (status < 0)
5585 goto error;
5586 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5587 if (status < 0)
5588 goto error;
5589 status = write16(state, QAM_LC_MODE__A, 7);
5590 if (status < 0)
5591 goto error;
5592
5593 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5594 if (status < 0)
5595 goto error;
5596 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5597 if (status < 0)
5598 goto error;
5599 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5600 if (status < 0)
5601 goto error;
5602 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5603 if (status < 0)
5604 goto error;
5605 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5606 if (status < 0)
5607 goto error;
5608 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5618 if (status < 0)
5619 goto error;
5620 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5621 if (status < 0)
5622 goto error;
5623 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5624 if (status < 0)
5625 goto error;
5626 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5627 if (status < 0)
5628 goto error;
5629 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5630 if (status < 0)
5631 goto error;
5632 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5633 if (status < 0)
5634 goto error;
5635 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5636 if (status < 0)
5637 goto error;
5638
5639 /* Mirroring, QAM-block starting point not inverted */
5640 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5641 if (status < 0)
5642 goto error;
5643
5644 /* Halt SCU to enable safe non-atomic accesses */
5645 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5646 if (status < 0)
5647 goto error;
5648
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005649 /* STEP 4: modulation specific setup */
5650 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005651 case QAM_16:
5652 status = SetQAM16(state);
5653 break;
5654 case QAM_32:
5655 status = SetQAM32(state);
5656 break;
5657 case QAM_AUTO:
5658 case QAM_64:
5659 status = SetQAM64(state);
5660 break;
5661 case QAM_128:
5662 status = SetQAM128(state);
5663 break;
5664 case QAM_256:
5665 status = SetQAM256(state);
5666 break;
5667 default:
5668 status = -EINVAL;
5669 break;
5670 }
5671 if (status < 0)
5672 goto error;
5673
5674 /* Activate SCU to enable SCU commands */
5675 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5676 if (status < 0)
5677 goto error;
5678
5679 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005680 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005681 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5682 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5683 if (status < 0)
5684 goto error;
5685
5686 /* Start processes */
5687 status = MPEGTSStart(state);
5688 if (status < 0)
5689 goto error;
5690 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5691 if (status < 0)
5692 goto error;
5693 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5694 if (status < 0)
5695 goto error;
5696 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5697 if (status < 0)
5698 goto error;
5699
5700 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5701 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5702 if (status < 0)
5703 goto error;
5704
5705 /* update global DRXK data container */
5706/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5707
5708error:
5709 if (status < 0)
5710 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005711 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005712}
5713
Oliver Endrissebc7de22011-07-03 13:49:44 -03005714static int SetQAMStandard(struct drxk_state *state,
5715 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005716{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005717 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005718#ifdef DRXK_QAM_TAPS
5719#define DRXK_QAMA_TAPS_SELECT
5720#include "drxk_filters.h"
5721#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005722#endif
5723
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005724 dprintk(1, "\n");
5725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005726 /* added antenna switch */
5727 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005729 /* Ensure correct power-up mode */
5730 status = PowerUpQAM(state);
5731 if (status < 0)
5732 goto error;
5733 /* Reset QAM block */
5734 status = QAMResetQAM(state);
5735 if (status < 0)
5736 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005737
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005738 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005740 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5741 if (status < 0)
5742 goto error;
5743 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5744 if (status < 0)
5745 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005746
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005747 /* Upload IQM Channel Filter settings by
5748 boot loader from ROM table */
5749 switch (oMode) {
5750 case OM_QAM_ITU_A:
5751 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5752 break;
5753 case OM_QAM_ITU_C:
5754 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 -03005755 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005756 goto error;
5757 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5758 break;
5759 default:
5760 status = -EINVAL;
5761 }
5762 if (status < 0)
5763 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005764
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005765 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5766 if (status < 0)
5767 goto error;
5768 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5769 if (status < 0)
5770 goto error;
5771 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5772 if (status < 0)
5773 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005774
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005775 status = write16(state, IQM_RC_STRETCH__A, 21);
5776 if (status < 0)
5777 goto error;
5778 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5779 if (status < 0)
5780 goto error;
5781 status = write16(state, IQM_AF_CLP_TH__A, 448);
5782 if (status < 0)
5783 goto error;
5784 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5785 if (status < 0)
5786 goto error;
5787 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5788 if (status < 0)
5789 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005791 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5792 if (status < 0)
5793 goto error;
5794 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5795 if (status < 0)
5796 goto error;
5797 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5798 if (status < 0)
5799 goto error;
5800 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5801 if (status < 0)
5802 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005804 /* IQM Impulse Noise Processing Unit */
5805 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5806 if (status < 0)
5807 goto error;
5808 status = write16(state, IQM_CF_DATATH__A, 1000);
5809 if (status < 0)
5810 goto error;
5811 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5812 if (status < 0)
5813 goto error;
5814 status = write16(state, IQM_CF_DET_LCT__A, 0);
5815 if (status < 0)
5816 goto error;
5817 status = write16(state, IQM_CF_WND_LEN__A, 1);
5818 if (status < 0)
5819 goto error;
5820 status = write16(state, IQM_CF_PKDTH__A, 1);
5821 if (status < 0)
5822 goto error;
5823 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5824 if (status < 0)
5825 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005826
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005827 /* turn on IQMAF. Must be done before setAgc**() */
5828 status = SetIqmAf(state, true);
5829 if (status < 0)
5830 goto error;
5831 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5832 if (status < 0)
5833 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005834
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005835 /* IQM will not be reset from here, sync ADC and update/init AGC */
5836 status = ADCSynchronization(state);
5837 if (status < 0)
5838 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005839
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005840 /* Set the FSM step period */
5841 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5842 if (status < 0)
5843 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005844
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005845 /* Halt SCU to enable safe non-atomic accesses */
5846 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5847 if (status < 0)
5848 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005849
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005850 /* No more resets of the IQM, current standard correctly set =>
5851 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005852
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005853 status = InitAGC(state, true);
5854 if (status < 0)
5855 goto error;
5856 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5857 if (status < 0)
5858 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005859
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005860 /* Configure AGC's */
5861 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5862 if (status < 0)
5863 goto error;
5864 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5865 if (status < 0)
5866 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005867
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005868 /* Activate SCU to enable SCU commands */
5869 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5870error:
5871 if (status < 0)
5872 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005873 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005874}
5875
5876static int WriteGPIO(struct drxk_state *state)
5877{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005878 int status;
5879 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005880
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005881 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005882 /* stop lock indicator process */
5883 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5884 if (status < 0)
5885 goto error;
5886
5887 /* Write magic word to enable pdr reg write */
5888 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5889 if (status < 0)
5890 goto error;
5891
5892 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005893 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5894 /* write to io pad configuration register - output mode */
5895 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5896 if (status < 0)
5897 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005898
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005899 /* use corresponding bit in io data output registar */
5900 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5901 if (status < 0)
5902 goto error;
5903 if ((state->m_GPIO & 0x0001) == 0)
5904 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5905 else
5906 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5907 /* write back to io data output register */
5908 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5909 if (status < 0)
5910 goto error;
5911 }
5912 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5913 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005914 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005915 if (status < 0)
5916 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005917
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005918 /* use corresponding bit in io data output registar */
5919 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5920 if (status < 0)
5921 goto error;
5922 if ((state->m_GPIO & 0x0002) == 0)
5923 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5924 else
5925 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5926 /* write back to io data output register */
5927 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5928 if (status < 0)
5929 goto error;
5930 }
5931 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5932 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005933 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005934 if (status < 0)
5935 goto error;
5936
5937 /* use corresponding bit in io data output registar */
5938 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5939 if (status < 0)
5940 goto error;
5941 if ((state->m_GPIO & 0x0004) == 0)
5942 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5943 else
5944 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5945 /* write back to io data output register */
5946 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5947 if (status < 0)
5948 goto error;
5949 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005950 }
5951 /* Write magic word to disable pdr reg write */
5952 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5953error:
5954 if (status < 0)
5955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005956 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005957}
5958
5959static int SwitchAntennaToQAM(struct drxk_state *state)
5960{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005961 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005962 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005963
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005964 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005965
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005966 if (!state->antenna_gpio)
5967 return 0;
5968
5969 gpio_state = state->m_GPIO & state->antenna_gpio;
5970
5971 if (state->antenna_dvbt ^ gpio_state) {
5972 /* Antenna is on DVB-T mode. Switch */
5973 if (state->antenna_dvbt)
5974 state->m_GPIO &= ~state->antenna_gpio;
5975 else
5976 state->m_GPIO |= state->antenna_gpio;
5977 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005978 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005979 if (status < 0)
5980 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005981 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982}
5983
5984static int SwitchAntennaToDVBT(struct drxk_state *state)
5985{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005986 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005987 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005988
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005989 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005990
5991 if (!state->antenna_gpio)
5992 return 0;
5993
5994 gpio_state = state->m_GPIO & state->antenna_gpio;
5995
5996 if (!(state->antenna_dvbt ^ gpio_state)) {
5997 /* Antenna is on DVB-C mode. Switch */
5998 if (state->antenna_dvbt)
5999 state->m_GPIO |= state->antenna_gpio;
6000 else
6001 state->m_GPIO &= ~state->antenna_gpio;
6002 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006003 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006004 if (status < 0)
6005 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006006 return status;
6007}
6008
6009
6010static int PowerDownDevice(struct drxk_state *state)
6011{
6012 /* Power down to requested mode */
6013 /* Backup some register settings */
6014 /* Set pins with possible pull-ups connected to them in input mode */
6015 /* Analog power down */
6016 /* ADC power down */
6017 /* Power down device */
6018 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006019
6020 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006021 if (state->m_bPDownOpenBridge) {
6022 /* Open I2C bridge before power down of DRXK */
6023 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006024 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 goto error;
6026 }
6027 /* driver 0.9.0 */
6028 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006029 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006031
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006032 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
6033 if (status < 0)
6034 goto error;
6035 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6036 if (status < 0)
6037 goto error;
6038 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6039 status = HI_CfgCommand(state);
6040error:
6041 if (status < 0)
6042 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6043
6044 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006045}
6046
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047static int init_drxk(struct drxk_state *state)
6048{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006049 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006050 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051 u16 driverVersion;
6052
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006053 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006054 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006055 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006056 status = PowerUpDevice(state);
6057 if (status < 0)
6058 goto error;
6059 status = DRXX_Open(state);
6060 if (status < 0)
6061 goto error;
6062 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6063 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);
6064 if (status < 0)
6065 goto error;
6066 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6067 if (status < 0)
6068 goto error;
6069 /* TODO is this needed, if yes how much delay in worst case scenario */
6070 msleep(1);
6071 state->m_DRXK_A3_PATCH_CODE = true;
6072 status = GetDeviceCapabilities(state);
6073 if (status < 0)
6074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 /* Bridge delay, uses oscilator clock */
6077 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6078 /* SDA brdige delay */
6079 state->m_HICfgBridgeDelay =
6080 (u16) ((state->m_oscClockFreq / 1000) *
6081 HI_I2C_BRIDGE_DELAY) / 1000;
6082 /* Clipping */
6083 if (state->m_HICfgBridgeDelay >
6084 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006085 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006086 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6087 }
6088 /* SCL bridge delay, same as SDA for now */
6089 state->m_HICfgBridgeDelay +=
6090 state->m_HICfgBridgeDelay <<
6091 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 status = InitHI(state);
6094 if (status < 0)
6095 goto error;
6096 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006097#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006098 if (!(state->m_DRXK_A1_ROM_CODE)
6099 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006100#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006101 {
6102 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6103 if (status < 0)
6104 goto error;
6105 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006107 /* disable MPEG port */
6108 status = MPEGTSDisable(state);
6109 if (status < 0)
6110 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006112 /* Stop AUD and SCU */
6113 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6114 if (status < 0)
6115 goto error;
6116 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6117 if (status < 0)
6118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 /* enable token-ring bus through OFDM block for possible ucode upload */
6121 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6122 if (status < 0)
6123 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* include boot loader section */
6126 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6127 if (status < 0)
6128 goto error;
6129 status = BLChainCmd(state, 0, 6, 100);
6130 if (status < 0)
6131 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006132
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006133 if (state->fw) {
6134 status = DownloadMicrocode(state, state->fw->data,
6135 state->fw->size);
6136 if (status < 0)
6137 goto error;
6138 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006139
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006140 /* disable token-ring bus through OFDM block for possible ucode upload */
6141 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6142 if (status < 0)
6143 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006145 /* Run SCU for a little while to initialize microcode version numbers */
6146 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6147 if (status < 0)
6148 goto error;
6149 status = DRXX_Open(state);
6150 if (status < 0)
6151 goto error;
6152 /* added for test */
6153 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006155 powerMode = DRXK_POWER_DOWN_OFDM;
6156 status = CtrlPowerMode(state, &powerMode);
6157 if (status < 0)
6158 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006160 /* Stamp driver version number in SCU data RAM in BCD code
6161 Done to enable field application engineers to retreive drxdriver version
6162 via I2C from SCU RAM.
6163 Not using SCU command interface for SCU register access since no
6164 microcode may be present.
6165 */
6166 driverVersion =
6167 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6168 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6169 ((DRXK_VERSION_MAJOR % 10) << 4) +
6170 (DRXK_VERSION_MINOR % 10);
6171 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6172 if (status < 0)
6173 goto error;
6174 driverVersion =
6175 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6176 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6177 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6178 (DRXK_VERSION_PATCH % 10);
6179 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6180 if (status < 0)
6181 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006183 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6184 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6185 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006187 /* Dirty fix of default values for ROM/PATCH microcode
6188 Dirty because this fix makes it impossible to setup suitable values
6189 before calling DRX_Open. This solution requires changes to RF AGC speed
6190 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006192 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006194 /* Reset driver debug flags to 0 */
6195 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6196 if (status < 0)
6197 goto error;
6198 /* driver 0.9.0 */
6199 /* Setup FEC OC:
6200 NOTE: No more full FEC resets allowed afterwards!! */
6201 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6202 if (status < 0)
6203 goto error;
6204 /* MPEGTS functions are still the same */
6205 status = MPEGTSDtoInit(state);
6206 if (status < 0)
6207 goto error;
6208 status = MPEGTSStop(state);
6209 if (status < 0)
6210 goto error;
6211 status = MPEGTSConfigurePolarity(state);
6212 if (status < 0)
6213 goto error;
6214 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6215 if (status < 0)
6216 goto error;
6217 /* added: configure GPIO */
6218 status = WriteGPIO(state);
6219 if (status < 0)
6220 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006222 state->m_DrxkState = DRXK_STOPPED;
6223
6224 if (state->m_bPowerDown) {
6225 status = PowerDownDevice(state);
6226 if (status < 0)
6227 goto error;
6228 state->m_DrxkState = DRXK_POWERED_DOWN;
6229 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006230 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006231
6232 /* Initialize the supported delivery systems */
6233 n = 0;
6234 if (state->m_hasDVBC) {
6235 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6236 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6237 strlcat(state->frontend.ops.info.name, " DVB-C",
6238 sizeof(state->frontend.ops.info.name));
6239 }
6240 if (state->m_hasDVBT) {
6241 state->frontend.ops.delsys[n++] = SYS_DVBT;
6242 strlcat(state->frontend.ops.info.name, " DVB-T",
6243 sizeof(state->frontend.ops.info.name));
6244 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006245 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006246 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006247error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006248 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006249 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006250 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006251 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006252 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006254 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006255}
6256
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006257static void load_firmware_cb(const struct firmware *fw,
6258 void *context)
6259{
6260 struct drxk_state *state = context;
6261
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006262 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006263 if (!fw) {
6264 printk(KERN_ERR
6265 "drxk: Could not load firmware file %s.\n",
6266 state->microcode_name);
6267 printk(KERN_INFO
6268 "drxk: Copy %s to your hotplug directory!\n",
6269 state->microcode_name);
6270 state->microcode_name = NULL;
6271
6272 /*
6273 * As firmware is now load asynchronous, it is not possible
6274 * anymore to fail at frontend attach. We might silently
6275 * return here, and hope that the driver won't crash.
6276 * We might also change all DVB callbacks to return -ENODEV
6277 * if the device is not initialized.
6278 * As the DRX-K devices have their own internal firmware,
6279 * let's just hope that it will match a firmware revision
6280 * compatible with this driver and proceed.
6281 */
6282 }
6283 state->fw = fw;
6284
6285 init_drxk(state);
6286}
6287
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006288static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006290 struct drxk_state *state = fe->demodulator_priv;
6291
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006292 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006293 if (state->fw)
6294 release_firmware(state->fw);
6295
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006296 kfree(state);
6297}
6298
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006299static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006301 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006302
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006303 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006304
6305 if (state->m_DrxkState == DRXK_NO_DEV)
6306 return -ENODEV;
6307 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6308 return 0;
6309
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006310 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 return 0;
6312}
6313
Oliver Endrissebc7de22011-07-03 13:49:44 -03006314static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315{
6316 struct drxk_state *state = fe->demodulator_priv;
6317
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006318 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006319
6320 if (state->m_DrxkState == DRXK_NO_DEV)
6321 return -ENODEV;
6322
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006323 return ConfigureI2CBridge(state, enable ? true : false);
6324}
6325
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006326static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006327{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006328 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006329 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006330 struct drxk_state *state = fe->demodulator_priv;
6331 u32 IF;
6332
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006333 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006334
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006335 if (state->m_DrxkState == DRXK_NO_DEV)
6336 return -ENODEV;
6337
6338 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6339 return -EAGAIN;
6340
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006341 if (!fe->ops.tuner_ops.get_if_frequency) {
6342 printk(KERN_ERR
6343 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6344 return -EINVAL;
6345 }
6346
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006347 if (fe->ops.i2c_gate_ctrl)
6348 fe->ops.i2c_gate_ctrl(fe, 1);
6349 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006350 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006351 if (fe->ops.i2c_gate_ctrl)
6352 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006353
6354 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006355 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006356
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006357 if (old_delsys != delsys) {
6358 ShutDown(state);
6359 switch (delsys) {
6360 case SYS_DVBC_ANNEX_A:
6361 case SYS_DVBC_ANNEX_C:
6362 if (!state->m_hasDVBC)
6363 return -EINVAL;
6364 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6365 if (state->m_itut_annex_c)
6366 SetOperationMode(state, OM_QAM_ITU_C);
6367 else
6368 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006369 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006370 case SYS_DVBT:
6371 if (!state->m_hasDVBT)
6372 return -EINVAL;
6373 SetOperationMode(state, OM_DVBT);
6374 break;
6375 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006376 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006377 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006378 }
6379
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006380 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381 Start(state, 0, IF);
6382
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006383 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006384
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006385 return 0;
6386}
6387
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006388static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6389{
6390 struct drxk_state *state = fe->demodulator_priv;
6391 u32 stat;
6392
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006393 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006394
6395 if (state->m_DrxkState == DRXK_NO_DEV)
6396 return -ENODEV;
6397 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6398 return -EAGAIN;
6399
Oliver Endrissebc7de22011-07-03 13:49:44 -03006400 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006401 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006402 if (stat == MPEG_LOCK)
6403 *status |= 0x1f;
6404 if (stat == FEC_LOCK)
6405 *status |= 0x0f;
6406 if (stat == DEMOD_LOCK)
6407 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006408 return 0;
6409}
6410
Oliver Endrissebc7de22011-07-03 13:49:44 -03006411static int drxk_read_signal_strength(struct dvb_frontend *fe,
6412 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006413{
6414 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006415 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006417 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006418
6419 if (state->m_DrxkState == DRXK_NO_DEV)
6420 return -ENODEV;
6421 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6422 return -EAGAIN;
6423
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006424 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006425 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006426 return 0;
6427}
6428
6429static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6430{
6431 struct drxk_state *state = fe->demodulator_priv;
6432 s32 snr2;
6433
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006434 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006435
6436 if (state->m_DrxkState == DRXK_NO_DEV)
6437 return -ENODEV;
6438 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6439 return -EAGAIN;
6440
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006441 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006442 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006443 return 0;
6444}
6445
6446static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6447{
6448 struct drxk_state *state = fe->demodulator_priv;
6449 u16 err;
6450
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006451 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006452
6453 if (state->m_DrxkState == DRXK_NO_DEV)
6454 return -ENODEV;
6455 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6456 return -EAGAIN;
6457
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006458 DVBTQAMGetAccPktErr(state, &err);
6459 *ucblocks = (u32) err;
6460 return 0;
6461}
6462
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006463static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006464 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006465{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006466 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006467 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006468
6469 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006470
6471 if (state->m_DrxkState == DRXK_NO_DEV)
6472 return -ENODEV;
6473 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6474 return -EAGAIN;
6475
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006476 switch (p->delivery_system) {
6477 case SYS_DVBC_ANNEX_A:
6478 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006479 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006480 sets->min_delay_ms = 3000;
6481 sets->max_drift = 0;
6482 sets->step_size = 0;
6483 return 0;
6484 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006485 return -EINVAL;
6486 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006487}
6488
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006489static struct dvb_frontend_ops drxk_ops = {
6490 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006491 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006492 .name = "DRXK",
6493 .frequency_min = 47000000,
6494 .frequency_max = 865000000,
6495 /* For DVB-C */
6496 .symbol_rate_min = 870000,
6497 .symbol_rate_max = 11700000,
6498 /* For DVB-T */
6499 .frequency_stepsize = 166667,
6500
6501 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6502 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6503 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6504 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6505 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6506 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6507 },
6508
6509 .release = drxk_release,
6510 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006511 .i2c_gate_ctrl = drxk_gate_ctrl,
6512
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006513 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006514 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006515
6516 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006517 .read_signal_strength = drxk_read_signal_strength,
6518 .read_snr = drxk_read_snr,
6519 .read_ucblocks = drxk_read_ucblocks,
6520};
6521
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006522struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006523 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006524{
6525 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006526 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006527 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006528
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006529 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006530 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006531 if (!state)
6532 return NULL;
6533
Oliver Endrissebc7de22011-07-03 13:49:44 -03006534 state->i2c = i2c;
6535 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006536 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006537 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006538 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006539 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006540 state->antenna_gpio = config->antenna_gpio;
6541 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006542 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006543 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006544
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006545 if (config->dynamic_clk) {
6546 state->m_DVBTStaticCLK = 0;
6547 state->m_DVBCStaticCLK = 0;
6548 } else {
6549 state->m_DVBTStaticCLK = 1;
6550 state->m_DVBCStaticCLK = 1;
6551 }
6552
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006553
6554 if (config->mpeg_out_clk_strength)
6555 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6556 else
6557 state->m_TSClockkStrength = 0x06;
6558
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006559 if (config->parallel_ts)
6560 state->m_enableParallel = true;
6561 else
6562 state->m_enableParallel = false;
6563
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006564 /* NOTE: as more UIO bits will be used, add them to the mask */
6565 state->UIO_mask = config->antenna_gpio;
6566
6567 /* Default gpio to DVB-C */
6568 if (!state->antenna_dvbt && state->antenna_gpio)
6569 state->m_GPIO |= state->antenna_gpio;
6570 else
6571 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006572
6573 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006574
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006575 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6576 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006577
6578 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006579
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006580 /* Load firmware and initialize DRX-K */
6581 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006582 if (config->load_firmware_sync) {
6583 const struct firmware *fw = NULL;
6584
6585 status = request_firmware(&fw, state->microcode_name,
6586 state->i2c->dev.parent);
6587 if (status < 0)
6588 fw = NULL;
6589 load_firmware_cb(fw, state);
6590 } else {
6591 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006592 state->microcode_name,
6593 state->i2c->dev.parent,
6594 GFP_KERNEL,
6595 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006596 if (status < 0) {
6597 printk(KERN_ERR
6598 "drxk: failed to request a firmware\n");
6599 return NULL;
6600 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006601 }
6602 } else if (init_drxk(state) < 0)
6603 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006604
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006605 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006606 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006607
6608error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006609 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006610 kfree(state);
6611 return NULL;
6612}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006613EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006614
6615MODULE_DESCRIPTION("DRX-K driver");
6616MODULE_AUTHOR("Ralph Metzler");
6617MODULE_LICENSE("GPL");