blob: 8fa28bb470880a12a562f742f25d53dfd748038f [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
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
Ralph Metzler43dd07f2011-07-03 13:42:18 -030080#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
Ralph Metzler43dd07f2011-07-03 13:42:18 -030094#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
95#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
96
97#ifndef DRXK_KI_RAGC_ATV
98#define DRXK_KI_RAGC_ATV 4
99#endif
100#ifndef DRXK_KI_IAGC_ATV
101#define DRXK_KI_IAGC_ATV 6
102#endif
103#ifndef DRXK_KI_DAGC_ATV
104#define DRXK_KI_DAGC_ATV 7
105#endif
106
107#ifndef DRXK_KI_RAGC_QAM
108#define DRXK_KI_RAGC_QAM 3
109#endif
110#ifndef DRXK_KI_IAGC_QAM
111#define DRXK_KI_IAGC_QAM 4
112#endif
113#ifndef DRXK_KI_DAGC_QAM
114#define DRXK_KI_DAGC_QAM 7
115#endif
116#ifndef DRXK_KI_RAGC_DVBT
117#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
118#endif
119#ifndef DRXK_KI_IAGC_DVBT
120#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
121#endif
122#ifndef DRXK_KI_DAGC_DVBT
123#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
124#endif
125
126#ifndef DRXK_AGC_DAC_OFFSET
127#define DRXK_AGC_DAC_OFFSET (0x800)
128#endif
129
130#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
131#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
132#endif
133
134#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
135#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
139#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
140#endif
141
142#ifndef DRXK_QAM_SYMBOLRATE_MAX
143#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
144#endif
145
146#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
147#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
148#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
149#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
150#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
151#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
152#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
153#define DRXK_BL_ROM_OFFSET_UCODE 0
154
155#define DRXK_BLC_TIMEOUT 100
156
157#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
158#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
159
160#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
161
162#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
163#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
164#endif
165
166#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
167#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
168#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
169#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
170#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
171
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300172static unsigned int debug;
173module_param(debug, int, 0644);
174MODULE_PARM_DESC(debug, "enable debug messages");
175
176#define dprintk(level, fmt, arg...) do { \
177if (debug >= level) \
178 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
179} while (0)
180
181
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300182static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300183{
184 u64 tmp64;
185
Oliver Endrissebc7de22011-07-03 13:49:44 -0300186 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300187 do_div(tmp64, c);
188
189 return (u32) tmp64;
190}
191
192inline u32 Frac28a(u32 a, u32 c)
193{
194 int i = 0;
195 u32 Q1 = 0;
196 u32 R0 = 0;
197
Oliver Endrissebc7de22011-07-03 13:49:44 -0300198 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
199 Q1 = a / c; /* integer part, only the 4 least significant bits
200 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300201
202 /* division using radix 16, 7 nibbles in the result */
203 for (i = 0; i < 7; i++) {
204 Q1 = (Q1 << 4) | (R0 / c);
205 R0 = (R0 % c) << 4;
206 }
207 /* rounding */
208 if ((R0 >> 3) >= c)
209 Q1++;
210
211 return Q1;
212}
213
214static u32 Log10Times100(u32 x)
215{
216 static const u8 scale = 15;
217 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300218 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300219 u32 y = 0;
220 u32 d = 0;
221 u32 k = 0;
222 u32 r = 0;
223 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300224 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
225 0 <= n < ((1<<INDEXWIDTH)+1)
226 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300227
228 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300229 0, /* 0.000000 */
230 290941, /* 290941.300628 */
231 573196, /* 573196.476418 */
232 847269, /* 847269.179851 */
233 1113620, /* 1113620.489452 */
234 1372674, /* 1372673.576986 */
235 1624818, /* 1624817.752104 */
236 1870412, /* 1870411.981536 */
237 2109788, /* 2109787.962654 */
238 2343253, /* 2343252.817465 */
239 2571091, /* 2571091.461923 */
240 2793569, /* 2793568.696416 */
241 3010931, /* 3010931.055901 */
242 3223408, /* 3223408.452106 */
243 3431216, /* 3431215.635215 */
244 3634553, /* 3634553.498355 */
245 3833610, /* 3833610.244726 */
246 4028562, /* 4028562.434393 */
247 4219576, /* 4219575.925308 */
248 4406807, /* 4406806.721144 */
249 4590402, /* 4590401.736809 */
250 4770499, /* 4770499.491025 */
251 4947231, /* 4947230.734179 */
252 5120719, /* 5120719.018555 */
253 5291081, /* 5291081.217197 */
254 5458428, /* 5458427.996830 */
255 5622864, /* 5622864.249668 */
256 5784489, /* 5784489.488298 */
257 5943398, /* 5943398.207380 */
258 6099680, /* 6099680.215452 */
259 6253421, /* 6253420.939751 */
260 6404702, /* 6404701.706649 */
261 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300262 };
263
264
265 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300266 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300267
268 /* Scale x (normalize) */
269 /* computing y in log(x/y) = log(x) - log(y) */
270 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
271 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300272 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300273 break;
274 x <<= 1;
275 }
276 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300277 for (k = scale; k < 31; k++) {
278 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300279 break;
280 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300282 }
283 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300284 Now x has binary point between bit[scale] and bit[scale-1]
285 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300286
287 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300288 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300289
290 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300291 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300292 /* get index */
293 i = (u8) (x >> (scale - indexWidth));
294 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300295 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 /* compute log, multiplication (d* (..)) must be within range ! */
297 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300298 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300299 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300300 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300301 r = (y >> 1);
302 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300303 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300304 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300305 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300306}
307
308/****************************************************************************/
309/* I2C **********************************************************************/
310/****************************************************************************/
311
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300312static int drxk_i2c_lock(struct drxk_state *state)
313{
314 i2c_lock_adapter(state->i2c);
315 state->drxk_i2c_exclusive_lock = true;
316
317 return 0;
318}
319
320static void drxk_i2c_unlock(struct drxk_state *state)
321{
322 if (!state->drxk_i2c_exclusive_lock)
323 return;
324
325 i2c_unlock_adapter(state->i2c);
326 state->drxk_i2c_exclusive_lock = false;
327}
328
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300329static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
330 unsigned len)
331{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300332 if (state->drxk_i2c_exclusive_lock)
333 return __i2c_transfer(state->i2c, msgs, len);
334 else
335 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300336}
337
338static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300339{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300340 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
341 .buf = val, .len = 1}
342 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300343
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300344 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300345}
346
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300347static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300348{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300349 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300350 struct i2c_msg msg = {
351 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300352
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300353 dprintk(3, ":");
354 if (debug > 2) {
355 int i;
356 for (i = 0; i < len; i++)
357 printk(KERN_CONT " %02x", data[i]);
358 printk(KERN_CONT "\n");
359 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300360 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300361 if (status >= 0 && status != 1)
362 status = -EIO;
363
364 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300365 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300366
367 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300368}
369
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300370static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300371 u8 adr, u8 *msg, int len, u8 *answ, int alen)
372{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300373 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300374 struct i2c_msg msgs[2] = {
375 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300376 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300377 {.addr = adr, .flags = I2C_M_RD,
378 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300379 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300380
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300381 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300382 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300383 if (debug > 2)
384 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300385 if (status >= 0)
386 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300387
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300388 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300389 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300390 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300391 if (debug > 2) {
392 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300393 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300394 for (i = 0; i < len; i++)
395 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300396 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300397 for (i = 0; i < alen; i++)
398 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300399 printk(KERN_CONT "\n");
400 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300401 return 0;
402}
403
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300404static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300406 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300407 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300408
409 if (state->single_master)
410 flags |= 0xC0;
411
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
413 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
414 mm1[1] = ((reg >> 16) & 0xFF);
415 mm1[2] = ((reg >> 24) & 0xFF) | flags;
416 mm1[3] = ((reg >> 7) & 0xFF);
417 len = 4;
418 } else {
419 mm1[0] = ((reg << 1) & 0xFF);
420 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
421 len = 2;
422 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300423 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300424 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300425 if (status < 0)
426 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300427 if (data)
428 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300429
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300430 return 0;
431}
432
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300433static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300434{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300435 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300436}
437
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300438static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300440 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300441 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300442
443 if (state->single_master)
444 flags |= 0xC0;
445
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300446 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
447 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
448 mm1[1] = ((reg >> 16) & 0xFF);
449 mm1[2] = ((reg >> 24) & 0xFF) | flags;
450 mm1[3] = ((reg >> 7) & 0xFF);
451 len = 4;
452 } else {
453 mm1[0] = ((reg << 1) & 0xFF);
454 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
455 len = 2;
456 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300457 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300458 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300459 if (status < 0)
460 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300461 if (data)
462 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300463 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300464
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300465 return 0;
466}
467
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300468static int read32(struct drxk_state *state, u32 reg, u32 *data)
469{
470 return read32_flags(state, reg, data, 0);
471}
472
473static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300474{
475 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300476
477 if (state->single_master)
478 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
480 mm[0] = (((reg << 1) & 0xFF) | 0x01);
481 mm[1] = ((reg >> 16) & 0xFF);
482 mm[2] = ((reg >> 24) & 0xFF) | flags;
483 mm[3] = ((reg >> 7) & 0xFF);
484 len = 4;
485 } else {
486 mm[0] = ((reg << 1) & 0xFF);
487 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
488 len = 2;
489 }
490 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300491 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300492
493 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300494 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300495}
496
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300497static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300498{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300499 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300500}
501
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300502static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300503{
504 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300505
506 if (state->single_master)
507 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300508 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
509 mm[0] = (((reg << 1) & 0xFF) | 0x01);
510 mm[1] = ((reg >> 16) & 0xFF);
511 mm[2] = ((reg >> 24) & 0xFF) | flags;
512 mm[3] = ((reg >> 7) & 0xFF);
513 len = 4;
514 } else {
515 mm[0] = ((reg << 1) & 0xFF);
516 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
517 len = 2;
518 }
519 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300520 mm[len + 1] = (data >> 8) & 0xff;
521 mm[len + 2] = (data >> 16) & 0xff;
522 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300523 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300524
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300525 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526}
527
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300528static int write32(struct drxk_state *state, u32 reg, u32 data)
529{
530 return write32_flags(state, reg, data, 0);
531}
532
533static int write_block(struct drxk_state *state, u32 Address,
534 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300535{
536 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300537 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300538
539 if (state->single_master)
540 Flags |= 0xC0;
541
Oliver Endrissebc7de22011-07-03 13:49:44 -0300542 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300543 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300544 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300545 u8 *AdrBuf = &state->Chunk[0];
546 u32 AdrLength = 0;
547
Oliver Endrissebc7de22011-07-03 13:49:44 -0300548 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
549 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
550 AdrBuf[1] = ((Address >> 16) & 0xFF);
551 AdrBuf[2] = ((Address >> 24) & 0xFF);
552 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300553 AdrBuf[2] |= Flags;
554 AdrLength = 4;
555 if (Chunk == state->m_ChunkSize)
556 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300557 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300558 AdrBuf[0] = ((Address << 1) & 0xFF);
559 AdrBuf[1] = (((Address >> 16) & 0x0F) |
560 ((Address >> 18) & 0xF0));
561 AdrLength = 2;
562 }
563 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300564 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
565 if (debug > 1) {
566 int i;
567 if (pBlock)
568 for (i = 0; i < Chunk; i++)
569 printk(KERN_CONT " %02x", pBlock[i]);
570 printk(KERN_CONT "\n");
571 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300572 status = i2c_write(state, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300573 &state->Chunk[0], Chunk + AdrLength);
574 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300575 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
576 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 break;
578 }
579 pBlock += Chunk;
580 Address += (Chunk >> 1);
581 BlkSize -= Chunk;
582 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300583 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300584}
585
586#ifndef DRXK_MAX_RETRIES_POWERUP
587#define DRXK_MAX_RETRIES_POWERUP 20
588#endif
589
590int PowerUpDevice(struct drxk_state *state)
591{
592 int status;
593 u8 data = 0;
594 u16 retryCount = 0;
595
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300596 dprintk(1, "\n");
597
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300598 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300599 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300600 do {
601 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300602 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300603 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300604 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300605 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300606 if (status < 0)
607 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300608 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300609 &data);
610 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300611 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300612 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
613 goto error;
614 }
615
616 /* Make sure all clk domains are active */
617 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
618 if (status < 0)
619 goto error;
620 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
621 if (status < 0)
622 goto error;
623 /* Enable pll lock tests */
624 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
625 if (status < 0)
626 goto error;
627
628 state->m_currentPowerMode = DRX_POWER_UP;
629
630error:
631 if (status < 0)
632 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
633
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300634 return status;
635}
636
637
638static int init_state(struct drxk_state *state)
639{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300640 /*
641 * FIXME: most (all?) of the values bellow should be moved into
642 * struct drxk_config, as they are probably board-specific
643 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300644 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
645 u32 ulVSBIfAgcOutputLevel = 0;
646 u32 ulVSBIfAgcMinLevel = 0;
647 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
648 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300649
Oliver Endrissebc7de22011-07-03 13:49:44 -0300650 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
651 u32 ulVSBRfAgcOutputLevel = 0;
652 u32 ulVSBRfAgcMinLevel = 0;
653 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
654 u32 ulVSBRfAgcSpeed = 3;
655 u32 ulVSBRfAgcTop = 9500;
656 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300657
Oliver Endrissebc7de22011-07-03 13:49:44 -0300658 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
659 u32 ulATVIfAgcOutputLevel = 0;
660 u32 ulATVIfAgcMinLevel = 0;
661 u32 ulATVIfAgcMaxLevel = 0;
662 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300663
Oliver Endrissebc7de22011-07-03 13:49:44 -0300664 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
665 u32 ulATVRfAgcOutputLevel = 0;
666 u32 ulATVRfAgcMinLevel = 0;
667 u32 ulATVRfAgcMaxLevel = 0;
668 u32 ulATVRfAgcTop = 9500;
669 u32 ulATVRfAgcCutOffCurrent = 4000;
670 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300671
672 u32 ulQual83 = DEFAULT_MER_83;
673 u32 ulQual93 = DEFAULT_MER_93;
674
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300675 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
676 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
677
678 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
679 /* io_pad_cfg_mode output mode is drive always */
680 /* io_pad_cfg_drive is set to power 2 (23 mA) */
681 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300682 u32 ulInvertTSClock = 0;
683 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300684 u32 ulDVBTBitrate = 50000000;
685 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
686
687 u32 ulInsertRSByte = 0;
688
689 u32 ulRfMirror = 1;
690 u32 ulPowerDown = 0;
691
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300692 dprintk(1, "\n");
693
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300694 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_hasDVBT = false;
696 state->m_hasDVBC = false;
697 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300698 state->m_hasOOB = false;
699 state->m_hasAudio = false;
700
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300701 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200702 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300703
704 state->m_oscClockFreq = 0;
705 state->m_smartAntInverted = false;
706 state->m_bPDownOpenBridge = false;
707
708 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300709 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300710 /* Timing div, 250ns/Psys */
711 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
712 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
713 HI_I2C_DELAY) / 1000;
714 /* Clipping */
715 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
716 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
717 state->m_HICfgWakeUpKey = (state->demod_address << 1);
718 /* port/bridge/power down ctrl */
719 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
720
721 state->m_bPowerDown = (ulPowerDown != 0);
722
723 state->m_DRXK_A1_PATCH_CODE = false;
724 state->m_DRXK_A1_ROM_CODE = false;
725 state->m_DRXK_A2_ROM_CODE = false;
726 state->m_DRXK_A3_ROM_CODE = false;
727 state->m_DRXK_A2_PATCH_CODE = false;
728 state->m_DRXK_A3_PATCH_CODE = false;
729
730 /* Init AGC and PGA parameters */
731 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300732 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
733 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
734 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
735 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
736 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300737 state->m_vsbPgaCfg = 140;
738
739 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300740 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
741 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
742 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
743 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
744 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
745 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
746 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
747 state->m_vsbPreSawCfg.reference = 0x07;
748 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300749
750 state->m_Quality83percent = DEFAULT_MER_83;
751 state->m_Quality93percent = DEFAULT_MER_93;
752 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
753 state->m_Quality83percent = ulQual83;
754 state->m_Quality93percent = ulQual93;
755 }
756
757 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300758 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
759 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
760 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
761 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
762 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300763
764 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300765 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
766 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
767 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
768 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
769 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
770 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
771 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
772 state->m_atvPreSawCfg.reference = 0x04;
773 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300774
775
776 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300777 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
778 state->m_dvbtRfAgcCfg.outputLevel = 0;
779 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
780 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
781 state->m_dvbtRfAgcCfg.top = 0x2100;
782 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
783 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300784
785
786 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300787 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
788 state->m_dvbtIfAgcCfg.outputLevel = 0;
789 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
790 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
791 state->m_dvbtIfAgcCfg.top = 13424;
792 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
793 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300794 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300795 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
796 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300797
Oliver Endrissebc7de22011-07-03 13:49:44 -0300798 state->m_dvbtPreSawCfg.reference = 4;
799 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300800
801 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300802 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
803 state->m_qamRfAgcCfg.outputLevel = 0;
804 state->m_qamRfAgcCfg.minOutputLevel = 6023;
805 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
806 state->m_qamRfAgcCfg.top = 0x2380;
807 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
808 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300809
810 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300811 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
812 state->m_qamIfAgcCfg.outputLevel = 0;
813 state->m_qamIfAgcCfg.minOutputLevel = 0;
814 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
815 state->m_qamIfAgcCfg.top = 0x0511;
816 state->m_qamIfAgcCfg.cutOffCurrent = 0;
817 state->m_qamIfAgcCfg.speed = 3;
818 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300819 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
820
Oliver Endrissebc7de22011-07-03 13:49:44 -0300821 state->m_qamPgaCfg = 140;
822 state->m_qamPreSawCfg.reference = 4;
823 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300824
825 state->m_OperationMode = OM_NONE;
826 state->m_DrxkState = DRXK_UNINITIALIZED;
827
828 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300829 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
830 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300831 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
832 state->m_invertERR = false; /* If TRUE; invert ERR signal */
833 state->m_invertSTR = false; /* If TRUE; invert STR signals */
834 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
835 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300836
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300837 /* If TRUE; static MPEG clockrate will be used;
838 otherwise clockrate will adapt to the bitrate of the TS */
839
840 state->m_DVBTBitrate = ulDVBTBitrate;
841 state->m_DVBCBitrate = ulDVBCBitrate;
842
843 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300844
845 /* Maximum bitrate in b/s in case static clockrate is selected */
846 state->m_mpegTsStaticBitrate = 19392658;
847 state->m_disableTEIhandling = false;
848
849 if (ulInsertRSByte)
850 state->m_insertRSByte = true;
851
852 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
853 if (ulMpegLockTimeOut < 10000)
854 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
855 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
856 if (ulDemodLockTimeOut < 10000)
857 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
858
Oliver Endrissebc7de22011-07-03 13:49:44 -0300859 /* QAM defaults */
860 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300861 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300862 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
863 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300864
865 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
866 state->m_agcFastClipCtrlDelay = 0;
867
868 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300869
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300870 state->m_bPowerDown = false;
871 state->m_currentPowerMode = DRX_POWER_DOWN;
872
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300873 state->m_rfmirror = (ulRfMirror == 0);
874 state->m_IfAgcPol = false;
875 return 0;
876}
877
878static int DRXX_Open(struct drxk_state *state)
879{
880 int status = 0;
881 u32 jtag = 0;
882 u16 bid = 0;
883 u16 key = 0;
884
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300885 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300886 /* stop lock indicator process */
887 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
888 if (status < 0)
889 goto error;
890 /* Check device id */
891 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
892 if (status < 0)
893 goto error;
894 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
895 if (status < 0)
896 goto error;
897 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
898 if (status < 0)
899 goto error;
900 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
901 if (status < 0)
902 goto error;
903 status = write16(state, SIO_TOP_COMM_KEY__A, key);
904error:
905 if (status < 0)
906 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300907 return status;
908}
909
910static int GetDeviceCapabilities(struct drxk_state *state)
911{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300912 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300913 u32 sioTopJtagidLo = 0;
914 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300915 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300916
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300917 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300919 /* driver 0.9.0 */
920 /* stop lock indicator process */
921 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
922 if (status < 0)
923 goto error;
924 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
925 if (status < 0)
926 goto error;
927 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
928 if (status < 0)
929 goto error;
930 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
931 if (status < 0)
932 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300933
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300934 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
935 case 0:
936 /* ignore (bypass ?) */
937 break;
938 case 1:
939 /* 27 MHz */
940 state->m_oscClockFreq = 27000;
941 break;
942 case 2:
943 /* 20.25 MHz */
944 state->m_oscClockFreq = 20250;
945 break;
946 case 3:
947 /* 4 MHz */
948 state->m_oscClockFreq = 20250;
949 break;
950 default:
951 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
952 return -EINVAL;
953 }
954 /*
955 Determine device capabilities
956 Based on pinning v14
957 */
958 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
959 if (status < 0)
960 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300961
962printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
963
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300964 /* driver 0.9.0 */
965 switch ((sioTopJtagidLo >> 29) & 0xF) {
966 case 0:
967 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300968 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300969 break;
970 case 2:
971 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300972 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300973 break;
974 case 3:
975 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300976 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300977 break;
978 default:
979 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
980 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300981 printk(KERN_ERR "drxk: Spin %d unknown\n",
982 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300983 goto error2;
984 }
985 switch ((sioTopJtagidLo >> 12) & 0xFF) {
986 case 0x13:
987 /* typeId = DRX3913K_TYPE_ID */
988 state->m_hasLNA = false;
989 state->m_hasOOB = false;
990 state->m_hasATV = false;
991 state->m_hasAudio = false;
992 state->m_hasDVBT = true;
993 state->m_hasDVBC = true;
994 state->m_hasSAWSW = true;
995 state->m_hasGPIO2 = false;
996 state->m_hasGPIO1 = false;
997 state->m_hasIRQN = false;
998 break;
999 case 0x15:
1000 /* typeId = DRX3915K_TYPE_ID */
1001 state->m_hasLNA = false;
1002 state->m_hasOOB = false;
1003 state->m_hasATV = true;
1004 state->m_hasAudio = false;
1005 state->m_hasDVBT = true;
1006 state->m_hasDVBC = false;
1007 state->m_hasSAWSW = true;
1008 state->m_hasGPIO2 = true;
1009 state->m_hasGPIO1 = true;
1010 state->m_hasIRQN = false;
1011 break;
1012 case 0x16:
1013 /* typeId = DRX3916K_TYPE_ID */
1014 state->m_hasLNA = false;
1015 state->m_hasOOB = false;
1016 state->m_hasATV = true;
1017 state->m_hasAudio = false;
1018 state->m_hasDVBT = true;
1019 state->m_hasDVBC = false;
1020 state->m_hasSAWSW = true;
1021 state->m_hasGPIO2 = true;
1022 state->m_hasGPIO1 = true;
1023 state->m_hasIRQN = false;
1024 break;
1025 case 0x18:
1026 /* typeId = DRX3918K_TYPE_ID */
1027 state->m_hasLNA = false;
1028 state->m_hasOOB = false;
1029 state->m_hasATV = true;
1030 state->m_hasAudio = true;
1031 state->m_hasDVBT = true;
1032 state->m_hasDVBC = false;
1033 state->m_hasSAWSW = true;
1034 state->m_hasGPIO2 = true;
1035 state->m_hasGPIO1 = true;
1036 state->m_hasIRQN = false;
1037 break;
1038 case 0x21:
1039 /* typeId = DRX3921K_TYPE_ID */
1040 state->m_hasLNA = false;
1041 state->m_hasOOB = false;
1042 state->m_hasATV = true;
1043 state->m_hasAudio = true;
1044 state->m_hasDVBT = true;
1045 state->m_hasDVBC = true;
1046 state->m_hasSAWSW = true;
1047 state->m_hasGPIO2 = true;
1048 state->m_hasGPIO1 = true;
1049 state->m_hasIRQN = false;
1050 break;
1051 case 0x23:
1052 /* typeId = DRX3923K_TYPE_ID */
1053 state->m_hasLNA = false;
1054 state->m_hasOOB = false;
1055 state->m_hasATV = true;
1056 state->m_hasAudio = true;
1057 state->m_hasDVBT = true;
1058 state->m_hasDVBC = true;
1059 state->m_hasSAWSW = true;
1060 state->m_hasGPIO2 = true;
1061 state->m_hasGPIO1 = true;
1062 state->m_hasIRQN = false;
1063 break;
1064 case 0x25:
1065 /* typeId = DRX3925K_TYPE_ID */
1066 state->m_hasLNA = false;
1067 state->m_hasOOB = false;
1068 state->m_hasATV = true;
1069 state->m_hasAudio = true;
1070 state->m_hasDVBT = true;
1071 state->m_hasDVBC = true;
1072 state->m_hasSAWSW = true;
1073 state->m_hasGPIO2 = true;
1074 state->m_hasGPIO1 = true;
1075 state->m_hasIRQN = false;
1076 break;
1077 case 0x26:
1078 /* typeId = DRX3926K_TYPE_ID */
1079 state->m_hasLNA = false;
1080 state->m_hasOOB = false;
1081 state->m_hasATV = true;
1082 state->m_hasAudio = false;
1083 state->m_hasDVBT = true;
1084 state->m_hasDVBC = true;
1085 state->m_hasSAWSW = true;
1086 state->m_hasGPIO2 = true;
1087 state->m_hasGPIO1 = true;
1088 state->m_hasIRQN = false;
1089 break;
1090 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001091 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001092 ((sioTopJtagidLo >> 12) & 0xFF));
1093 status = -EINVAL;
1094 goto error2;
1095 }
1096
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001097 printk(KERN_INFO
1098 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1099 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1100 state->m_oscClockFreq / 1000,
1101 state->m_oscClockFreq % 1000);
1102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001103error:
1104 if (status < 0)
1105 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1106
1107error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001108 return status;
1109}
1110
1111static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1112{
1113 int status;
1114 bool powerdown_cmd;
1115
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001116 dprintk(1, "\n");
1117
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001118 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001119 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001120 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001121 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001122 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1123 msleep(1);
1124
1125 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001126 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1127 ((state->m_HICfgCtrl) &
1128 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1129 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001130 if (powerdown_cmd == false) {
1131 /* Wait until command rdy */
1132 u32 retryCount = 0;
1133 u16 waitCmd;
1134
1135 do {
1136 msleep(1);
1137 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001138 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1139 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001140 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1141 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001142 if (status < 0)
1143 goto error;
1144 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001145 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001146error:
1147 if (status < 0)
1148 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1149
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001150 return status;
1151}
1152
1153static int HI_CfgCommand(struct drxk_state *state)
1154{
1155 int status;
1156
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001157 dprintk(1, "\n");
1158
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001159 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001160
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001161 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1162 if (status < 0)
1163 goto error;
1164 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1165 if (status < 0)
1166 goto error;
1167 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1168 if (status < 0)
1169 goto error;
1170 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1171 if (status < 0)
1172 goto error;
1173 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1174 if (status < 0)
1175 goto error;
1176 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1177 if (status < 0)
1178 goto error;
1179 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1180 if (status < 0)
1181 goto error;
1182
1183 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1184error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001185 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001186 if (status < 0)
1187 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001188 return status;
1189}
1190
1191static int InitHI(struct drxk_state *state)
1192{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001193 dprintk(1, "\n");
1194
Oliver Endrissebc7de22011-07-03 13:49:44 -03001195 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001196 state->m_HICfgTimeout = 0x96FF;
1197 /* port/bridge/power down ctrl */
1198 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001199
Oliver Endrissebc7de22011-07-03 13:49:44 -03001200 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001201}
1202
1203static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1204{
1205 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001206 u16 sioPdrMclkCfg = 0;
1207 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001208 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001209
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001210 dprintk(1, ": mpeg %s, %s mode\n",
1211 mpegEnable ? "enable" : "disable",
1212 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001213
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001214 /* stop lock indicator process */
1215 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1216 if (status < 0)
1217 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001218
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001219 /* MPEG TS pad configuration */
1220 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1221 if (status < 0)
1222 goto error;
1223
1224 if (mpegEnable == false) {
1225 /* Set MPEG TS pads to inputmode */
1226 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1236 if (status < 0)
1237 goto error;
1238 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1239 if (status < 0)
1240 goto error;
1241 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1242 if (status < 0)
1243 goto error;
1244 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1245 if (status < 0)
1246 goto error;
1247 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1248 if (status < 0)
1249 goto error;
1250 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1251 if (status < 0)
1252 goto error;
1253 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1254 if (status < 0)
1255 goto error;
1256 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1257 if (status < 0)
1258 goto error;
1259 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1260 if (status < 0)
1261 goto error;
1262 } else {
1263 /* Enable MPEG output */
1264 sioPdrMdxCfg =
1265 ((state->m_TSDataStrength <<
1266 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1267 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1268 SIO_PDR_MCLK_CFG_DRIVE__B) |
1269 0x0003);
1270
1271 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1272 if (status < 0)
1273 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001274
1275 if (state->enable_merr_cfg)
1276 err_cfg = sioPdrMdxCfg;
1277
1278 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001279 if (status < 0)
1280 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001281 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001282 if (status < 0)
1283 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001284
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001285 if (state->m_enableParallel == true) {
1286 /* paralel -> enable MD1 to MD7 */
1287 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001288 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001289 goto error;
1290 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001291 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001292 goto error;
1293 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001294 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001295 goto error;
1296 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001297 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001298 goto error;
1299 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001300 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001301 goto error;
1302 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1303 if (status < 0)
1304 goto error;
1305 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1306 if (status < 0)
1307 goto error;
1308 } else {
1309 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1310 SIO_PDR_MD0_CFG_DRIVE__B)
1311 | 0x0003);
1312 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001313 status = write16(state, SIO_PDR_MD1_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_MD2_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;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001319 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001320 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001321 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001322 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001323 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001324 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001325 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001326 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001327 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001328 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001329 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001330 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001331 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001332 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001333 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001334 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001335 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001336 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001337 goto error;
1338 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001339 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001340 goto error;
1341 }
1342 /* Enable MB output over MPEG pads and ctl input */
1343 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1344 if (status < 0)
1345 goto error;
1346 /* Write nomagic word to enable pdr reg write */
1347 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1348error:
1349 if (status < 0)
1350 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001351 return status;
1352}
1353
1354static int MPEGTSDisable(struct drxk_state *state)
1355{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001356 dprintk(1, "\n");
1357
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001358 return MPEGTSConfigurePins(state, false);
1359}
1360
1361static int BLChainCmd(struct drxk_state *state,
1362 u16 romOffset, u16 nrOfElements, u32 timeOut)
1363{
1364 u16 blStatus = 0;
1365 int status;
1366 unsigned long end;
1367
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001368 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001369 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001370 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1371 if (status < 0)
1372 goto error;
1373 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1374 if (status < 0)
1375 goto error;
1376 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1377 if (status < 0)
1378 goto error;
1379 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1380 if (status < 0)
1381 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001382
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001383 end = jiffies + msecs_to_jiffies(timeOut);
1384 do {
1385 msleep(1);
1386 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1387 if (status < 0)
1388 goto error;
1389 } while ((blStatus == 0x1) &&
1390 ((time_is_after_jiffies(end))));
1391
1392 if (blStatus == 0x1) {
1393 printk(KERN_ERR "drxk: SIO not ready\n");
1394 status = -EINVAL;
1395 goto error2;
1396 }
1397error:
1398 if (status < 0)
1399 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1400error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001401 mutex_unlock(&state->mutex);
1402 return status;
1403}
1404
1405
1406static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001407 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001408{
1409 const u8 *pSrc = pMCImage;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001410 u32 Address;
1411 u16 nBlocks;
1412 u16 BlockSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001413 u32 offset = 0;
1414 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001415 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001416
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001417 dprintk(1, "\n");
1418
Hans Verkuil5becbc52012-05-14 10:22:58 -03001419 /* down the drain (we don't care about MAGIC_WORD) */
1420#if 0
1421 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422 Drain = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001423#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001424 pSrc += sizeof(u16);
1425 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001426 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001427 pSrc += sizeof(u16);
1428 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001429
1430 for (i = 0; i < nBlocks; i += 1) {
1431 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001432 (pSrc[2] << 8) | pSrc[3];
1433 pSrc += sizeof(u32);
1434 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435
1436 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001437 pSrc += sizeof(u16);
1438 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001439
Hans Verkuil5becbc52012-05-14 10:22:58 -03001440#if 0
1441 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001442 Flags = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001443#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001444 pSrc += sizeof(u16);
1445 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001446
Hans Verkuil5becbc52012-05-14 10:22:58 -03001447#if 0
1448 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001450#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001451 pSrc += sizeof(u16);
1452 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001453
1454 if (offset + BlockSize > Length) {
1455 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1456 return -EINVAL;
1457 }
1458
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001459 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001460 if (status < 0) {
1461 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001462 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001463 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001464 pSrc += BlockSize;
1465 offset += BlockSize;
1466 }
1467 return status;
1468}
1469
1470static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1471{
1472 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001473 u16 data = 0;
1474 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001475 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1476 unsigned long end;
1477
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001478 dprintk(1, "\n");
1479
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001480 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001481 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001482 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1483 }
1484
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001485 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1486 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001487 /* tokenring already has correct status */
1488 return status;
1489 }
1490 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001491 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001492
Oliver Endrissebc7de22011-07-03 13:49:44 -03001493 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001494 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001495 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001496 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001497 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001498 msleep(1);
1499 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001500 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001501 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001502 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001503 }
1504 return status;
1505}
1506
1507static int MPEGTSStop(struct drxk_state *state)
1508{
1509 int status = 0;
1510 u16 fecOcSncMode = 0;
1511 u16 fecOcIprMode = 0;
1512
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001513 dprintk(1, "\n");
1514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001515 /* Gracefull shutdown (byte boundaries) */
1516 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1517 if (status < 0)
1518 goto error;
1519 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1520 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1521 if (status < 0)
1522 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001523
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001524 /* Suppress MCLK during absence of data */
1525 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1526 if (status < 0)
1527 goto error;
1528 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1529 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1530
1531error:
1532 if (status < 0)
1533 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1534
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001535 return status;
1536}
1537
1538static int scu_command(struct drxk_state *state,
1539 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001540 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001541{
1542#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1543#error DRXK register mapping no longer compatible with this routine!
1544#endif
1545 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001546 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001547 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001548 u8 buffer[34];
1549 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001550 const char *p;
1551 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001553 dprintk(1, "\n");
1554
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001555 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001556 ((resultLen > 0) && (result == NULL))) {
1557 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1558 return status;
1559 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001560
1561 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001562
1563 /* assume that the command register is ready
1564 since it is checked afterwards */
1565 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1566 buffer[cnt++] = (parameter[ii] & 0xFF);
1567 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1568 }
1569 buffer[cnt++] = (cmd & 0xFF);
1570 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1571
1572 write_block(state, SCU_RAM_PARAM_0__A -
1573 (parameterLen - 1), cnt, buffer);
1574 /* Wait until SCU has processed command */
1575 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001577 msleep(1);
1578 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1579 if (status < 0)
1580 goto error;
1581 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1582 if (curCmd != DRX_SCU_READY) {
1583 printk(KERN_ERR "drxk: SCU not ready\n");
1584 status = -EIO;
1585 goto error2;
1586 }
1587 /* read results */
1588 if ((resultLen > 0) && (result != NULL)) {
1589 s16 err;
1590 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001591
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001592 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1593 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001594 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001597
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001598 /* Check if an error was reported by SCU */
1599 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001600 if (err >= 0)
1601 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001602
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001603 /* check for the known error codes */
1604 switch (err) {
1605 case SCU_RESULT_UNKCMD:
1606 p = "SCU_RESULT_UNKCMD";
1607 break;
1608 case SCU_RESULT_UNKSTD:
1609 p = "SCU_RESULT_UNKSTD";
1610 break;
1611 case SCU_RESULT_SIZE:
1612 p = "SCU_RESULT_SIZE";
1613 break;
1614 case SCU_RESULT_INVPAR:
1615 p = "SCU_RESULT_INVPAR";
1616 break;
1617 default: /* Other negative values are errors */
1618 sprintf(errname, "ERROR: %d\n", err);
1619 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001620 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001621 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1622 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1623 status = -EINVAL;
1624 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001625 }
1626
1627error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001628 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001629 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001630error2:
1631 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001632 return status;
1633}
1634
1635static int SetIqmAf(struct drxk_state *state, bool active)
1636{
1637 u16 data = 0;
1638 int status;
1639
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001640 dprintk(1, "\n");
1641
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001642 /* Configure IQM */
1643 status = read16(state, IQM_AF_STDBY__A, &data);
1644 if (status < 0)
1645 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001646
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001647 if (!active) {
1648 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1649 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1650 | IQM_AF_STDBY_STDBY_PD_STANDBY
1651 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1652 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1653 } else {
1654 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1655 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1656 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1657 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1658 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1659 );
1660 }
1661 status = write16(state, IQM_AF_STDBY__A, data);
1662
1663error:
1664 if (status < 0)
1665 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001666 return status;
1667}
1668
Oliver Endrissebc7de22011-07-03 13:49:44 -03001669static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670{
1671 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001672 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001673
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001674 dprintk(1, "\n");
1675
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001676 /* Check arguments */
1677 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001678 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001679
1680 switch (*mode) {
1681 case DRX_POWER_UP:
1682 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1683 break;
1684 case DRXK_POWER_DOWN_OFDM:
1685 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1686 break;
1687 case DRXK_POWER_DOWN_CORE:
1688 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1689 break;
1690 case DRXK_POWER_DOWN_PLL:
1691 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1692 break;
1693 case DRX_POWER_DOWN:
1694 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1695 break;
1696 default:
1697 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001698 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001699 }
1700
1701 /* If already in requested power mode, do nothing */
1702 if (state->m_currentPowerMode == *mode)
1703 return 0;
1704
1705 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001706 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001707 status = PowerUpDevice(state);
1708 if (status < 0)
1709 goto error;
1710 status = DVBTEnableOFDMTokenRing(state, true);
1711 if (status < 0)
1712 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001713 }
1714
1715 if (*mode == DRX_POWER_UP) {
1716 /* Restore analog & pin configuartion */
1717 } else {
1718 /* Power down to requested mode */
1719 /* Backup some register settings */
1720 /* Set pins with possible pull-ups connected
1721 to them in input mode */
1722 /* Analog power down */
1723 /* ADC power down */
1724 /* Power down device */
1725 /* stop all comm_exec */
1726 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001727 switch (state->m_OperationMode) {
1728 case OM_DVBT:
1729 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001730 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001731 goto error;
1732 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001733 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001734 goto error;
1735 break;
1736 case OM_QAM_ITU_A:
1737 case OM_QAM_ITU_C:
1738 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001739 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001740 goto error;
1741 status = PowerDownQAM(state);
1742 if (status < 0)
1743 goto error;
1744 break;
1745 default:
1746 break;
1747 }
1748 status = DVBTEnableOFDMTokenRing(state, false);
1749 if (status < 0)
1750 goto error;
1751 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1752 if (status < 0)
1753 goto error;
1754 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1755 if (status < 0)
1756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001757
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001758 if (*mode != DRXK_POWER_DOWN_OFDM) {
1759 state->m_HICfgCtrl |=
1760 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1761 status = HI_CfgCommand(state);
1762 if (status < 0)
1763 goto error;
1764 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001765 }
1766 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001767
1768error:
1769 if (status < 0)
1770 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1771
Oliver Endrissebc7de22011-07-03 13:49:44 -03001772 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001773}
1774
1775static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1776{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001777 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001778 u16 cmdResult = 0;
1779 u16 data = 0;
1780 int status;
1781
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001782 dprintk(1, "\n");
1783
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001784 status = read16(state, SCU_COMM_EXEC__A, &data);
1785 if (status < 0)
1786 goto error;
1787 if (data == SCU_COMM_EXEC_ACTIVE) {
1788 /* Send OFDM stop command */
1789 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 -03001790 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001791 goto error;
1792 /* Send OFDM reset command */
1793 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1794 if (status < 0)
1795 goto error;
1796 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001797
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001798 /* Reset datapath for OFDM, processors first */
1799 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1800 if (status < 0)
1801 goto error;
1802 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1803 if (status < 0)
1804 goto error;
1805 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1806 if (status < 0)
1807 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001809 /* powerdown AFE */
1810 status = SetIqmAf(state, false);
1811 if (status < 0)
1812 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001814 /* powerdown to OFDM mode */
1815 if (setPowerMode) {
1816 status = CtrlPowerMode(state, &powerMode);
1817 if (status < 0)
1818 goto error;
1819 }
1820error:
1821 if (status < 0)
1822 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001823 return status;
1824}
1825
Oliver Endrissebc7de22011-07-03 13:49:44 -03001826static int SetOperationMode(struct drxk_state *state,
1827 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001828{
1829 int status = 0;
1830
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001831 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001832 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001833 Stop and power down previous standard
1834 TODO investigate total power down instead of partial
1835 power down depending on "previous" standard.
1836 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001837
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001838 /* disable HW lock indicator */
1839 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1840 if (status < 0)
1841 goto error;
1842
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001843 /* Device is already at the required mode */
1844 if (state->m_OperationMode == oMode)
1845 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001846
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001847 switch (state->m_OperationMode) {
1848 /* OM_NONE was added for start up */
1849 case OM_NONE:
1850 break;
1851 case OM_DVBT:
1852 status = MPEGTSStop(state);
1853 if (status < 0)
1854 goto error;
1855 status = PowerDownDVBT(state, true);
1856 if (status < 0)
1857 goto error;
1858 state->m_OperationMode = OM_NONE;
1859 break;
1860 case OM_QAM_ITU_A: /* fallthrough */
1861 case OM_QAM_ITU_C:
1862 status = MPEGTSStop(state);
1863 if (status < 0)
1864 goto error;
1865 status = PowerDownQAM(state);
1866 if (status < 0)
1867 goto error;
1868 state->m_OperationMode = OM_NONE;
1869 break;
1870 case OM_QAM_ITU_B:
1871 default:
1872 status = -EINVAL;
1873 goto error;
1874 }
1875
1876 /*
1877 Power up new standard
1878 */
1879 switch (oMode) {
1880 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001881 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001882 state->m_OperationMode = oMode;
1883 status = SetDVBTStandard(state, oMode);
1884 if (status < 0)
1885 goto error;
1886 break;
1887 case OM_QAM_ITU_A: /* fallthrough */
1888 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001889 dprintk(1, ": DVB-C Annex %c\n",
1890 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001891 state->m_OperationMode = oMode;
1892 status = SetQAMStandard(state, oMode);
1893 if (status < 0)
1894 goto error;
1895 break;
1896 case OM_QAM_ITU_B:
1897 default:
1898 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001899 }
1900error:
1901 if (status < 0)
1902 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1903 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001904}
1905
1906static int Start(struct drxk_state *state, s32 offsetFreq,
1907 s32 IntermediateFrequency)
1908{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001909 int status = -EINVAL;
1910
1911 u16 IFreqkHz;
1912 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001913
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001914 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001915 if (state->m_DrxkState != DRXK_STOPPED &&
1916 state->m_DrxkState != DRXK_DTV_STARTED)
1917 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001918
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001919 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001921 if (IntermediateFrequency < 0) {
1922 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1923 IntermediateFrequency = -IntermediateFrequency;
1924 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001926 switch (state->m_OperationMode) {
1927 case OM_QAM_ITU_A:
1928 case OM_QAM_ITU_C:
1929 IFreqkHz = (IntermediateFrequency / 1000);
1930 status = SetQAM(state, IFreqkHz, OffsetkHz);
1931 if (status < 0)
1932 goto error;
1933 state->m_DrxkState = DRXK_DTV_STARTED;
1934 break;
1935 case OM_DVBT:
1936 IFreqkHz = (IntermediateFrequency / 1000);
1937 status = MPEGTSStop(state);
1938 if (status < 0)
1939 goto error;
1940 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1941 if (status < 0)
1942 goto error;
1943 status = DVBTStart(state);
1944 if (status < 0)
1945 goto error;
1946 state->m_DrxkState = DRXK_DTV_STARTED;
1947 break;
1948 default:
1949 break;
1950 }
1951error:
1952 if (status < 0)
1953 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001954 return status;
1955}
1956
1957static int ShutDown(struct drxk_state *state)
1958{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001959 dprintk(1, "\n");
1960
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001961 MPEGTSStop(state);
1962 return 0;
1963}
1964
Oliver Endrissebc7de22011-07-03 13:49:44 -03001965static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1966 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001967{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001968 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001969
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001970 dprintk(1, "\n");
1971
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001972 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001973 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001974
1975 *pLockStatus = NOT_LOCKED;
1976
1977 /* define the SCU command code */
1978 switch (state->m_OperationMode) {
1979 case OM_QAM_ITU_A:
1980 case OM_QAM_ITU_B:
1981 case OM_QAM_ITU_C:
1982 status = GetQAMLockStatus(state, pLockStatus);
1983 break;
1984 case OM_DVBT:
1985 status = GetDVBTLockStatus(state, pLockStatus);
1986 break;
1987 default:
1988 break;
1989 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001990error:
1991 if (status < 0)
1992 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001993 return status;
1994}
1995
1996static int MPEGTSStart(struct drxk_state *state)
1997{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001998 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001999
2000 u16 fecOcSncMode = 0;
2001
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002002 /* Allow OC to sync again */
2003 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
2004 if (status < 0)
2005 goto error;
2006 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
2007 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
2011error:
2012 if (status < 0)
2013 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002014 return status;
2015}
2016
2017static int MPEGTSDtoInit(struct drxk_state *state)
2018{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002019 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002020
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002021 dprintk(1, "\n");
2022
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002023 /* Rate integration settings */
2024 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
2025 if (status < 0)
2026 goto error;
2027 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
2028 if (status < 0)
2029 goto error;
2030 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2031 if (status < 0)
2032 goto error;
2033 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2034 if (status < 0)
2035 goto error;
2036 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2037 if (status < 0)
2038 goto error;
2039 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2040 if (status < 0)
2041 goto error;
2042 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2043 if (status < 0)
2044 goto error;
2045 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2046 if (status < 0)
2047 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002048
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002049 /* Additional configuration */
2050 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2051 if (status < 0)
2052 goto error;
2053 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2054 if (status < 0)
2055 goto error;
2056 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2057error:
2058 if (status < 0)
2059 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2060
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061 return status;
2062}
2063
Oliver Endrissebc7de22011-07-03 13:49:44 -03002064static int MPEGTSDtoSetup(struct drxk_state *state,
2065 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002066{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002067 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002068
Oliver Endrissebc7de22011-07-03 13:49:44 -03002069 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2070 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2071 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2072 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2073 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2074 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2075 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002076 u16 fecOcTmdMode = 0;
2077 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002078 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002079 bool staticCLK = false;
2080
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002081 dprintk(1, "\n");
2082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002083 /* Check insertion of the Reed-Solomon parity bytes */
2084 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2085 if (status < 0)
2086 goto error;
2087 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2088 if (status < 0)
2089 goto error;
2090 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2091 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2092 if (state->m_insertRSByte == true) {
2093 /* enable parity symbol forward */
2094 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2095 /* MVAL disable during parity bytes */
2096 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2097 /* TS burst length to 204 */
2098 fecOcDtoBurstLen = 204;
2099 }
2100
2101 /* Check serial or parrallel output */
2102 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2103 if (state->m_enableParallel == false) {
2104 /* MPEG data output is serial -> set ipr_mode[0] */
2105 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2106 }
2107
2108 switch (oMode) {
2109 case OM_DVBT:
2110 maxBitRate = state->m_DVBTBitrate;
2111 fecOcTmdMode = 3;
2112 fecOcRcnCtlRate = 0xC00000;
2113 staticCLK = state->m_DVBTStaticCLK;
2114 break;
2115 case OM_QAM_ITU_A: /* fallthrough */
2116 case OM_QAM_ITU_C:
2117 fecOcTmdMode = 0x0004;
2118 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2119 maxBitRate = state->m_DVBCBitrate;
2120 staticCLK = state->m_DVBCStaticCLK;
2121 break;
2122 default:
2123 status = -EINVAL;
2124 } /* switch (standard) */
2125 if (status < 0)
2126 goto error;
2127
2128 /* Configure DTO's */
2129 if (staticCLK) {
2130 u32 bitRate = 0;
2131
2132 /* Rational DTO for MCLK source (static MCLK rate),
2133 Dynamic DTO for optimal grouping
2134 (avoid intra-packet gaps),
2135 DTO offset enable to sync TS burst with MSTRT */
2136 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2137 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2138 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2139 FEC_OC_FCT_MODE_VIRT_ENA__M);
2140
2141 /* Check user defined bitrate */
2142 bitRate = maxBitRate;
2143 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2144 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002145 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002146 /* Rational DTO period:
2147 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002148
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002149 Result should be floored,
2150 to make sure >= requested bitrate
2151 */
2152 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2153 * 1000) / bitRate);
2154 if (fecOcDtoPeriod <= 2)
2155 fecOcDtoPeriod = 0;
2156 else
2157 fecOcDtoPeriod -= 2;
2158 fecOcTmdIntUpdRate = 8;
2159 } else {
2160 /* (commonAttr->staticCLK == false) => dynamic mode */
2161 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2162 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2163 fecOcTmdIntUpdRate = 5;
2164 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002165
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002166 /* Write appropriate registers with requested configuration */
2167 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2168 if (status < 0)
2169 goto error;
2170 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2171 if (status < 0)
2172 goto error;
2173 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2174 if (status < 0)
2175 goto error;
2176 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2177 if (status < 0)
2178 goto error;
2179 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2180 if (status < 0)
2181 goto error;
2182 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2183 if (status < 0)
2184 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002185
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002186 /* Rate integration settings */
2187 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2188 if (status < 0)
2189 goto error;
2190 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2191 if (status < 0)
2192 goto error;
2193 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2194error:
2195 if (status < 0)
2196 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002197 return status;
2198}
2199
2200static int MPEGTSConfigurePolarity(struct drxk_state *state)
2201{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002202 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002203
2204 /* Data mask for the output data byte */
2205 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002206 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2207 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2208 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2209 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002210
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002211 dprintk(1, "\n");
2212
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002213 /* Control selective inversion of output bits */
2214 fecOcRegIprInvert &= (~(InvertDataMask));
2215 if (state->m_invertDATA == true)
2216 fecOcRegIprInvert |= InvertDataMask;
2217 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2218 if (state->m_invertERR == true)
2219 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2220 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2221 if (state->m_invertSTR == true)
2222 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2223 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2224 if (state->m_invertVAL == true)
2225 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2226 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2227 if (state->m_invertCLK == true)
2228 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002229
2230 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002231}
2232
2233#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2234
2235static int SetAgcRf(struct drxk_state *state,
2236 struct SCfgAgc *pAgcCfg, bool isDTV)
2237{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002238 int status = -EINVAL;
2239 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002240 struct SCfgAgc *pIfAgcSettings;
2241
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002242 dprintk(1, "\n");
2243
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002244 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002245 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002246
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002247 switch (pAgcCfg->ctrlMode) {
2248 case DRXK_AGC_CTRL_AUTO:
2249 /* Enable RF AGC DAC */
2250 status = read16(state, IQM_AF_STDBY__A, &data);
2251 if (status < 0)
2252 goto error;
2253 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2254 status = write16(state, IQM_AF_STDBY__A, data);
2255 if (status < 0)
2256 goto error;
2257 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2258 if (status < 0)
2259 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002261 /* Enable SCU RF AGC loop */
2262 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002263
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002264 /* Polarity */
2265 if (state->m_RfAgcPol)
2266 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2267 else
2268 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2269 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2270 if (status < 0)
2271 goto error;
2272
2273 /* Set speed (using complementary reduction value) */
2274 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2275 if (status < 0)
2276 goto error;
2277
2278 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2279 data |= (~(pAgcCfg->speed <<
2280 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2281 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2282
2283 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2284 if (status < 0)
2285 goto error;
2286
2287 if (IsDVBT(state))
2288 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2289 else if (IsQAM(state))
2290 pIfAgcSettings = &state->m_qamIfAgcCfg;
2291 else
2292 pIfAgcSettings = &state->m_atvIfAgcCfg;
2293 if (pIfAgcSettings == NULL) {
2294 status = -EINVAL;
2295 goto error;
2296 }
2297
2298 /* Set TOP, only if IF-AGC is in AUTO mode */
2299 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2300 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002301 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002302 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002303
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002304 /* Cut-Off current */
2305 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2306 if (status < 0)
2307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002308
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002309 /* Max. output level */
2310 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2311 if (status < 0)
2312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002314 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002315
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002316 case DRXK_AGC_CTRL_USER:
2317 /* Enable RF AGC DAC */
2318 status = read16(state, IQM_AF_STDBY__A, &data);
2319 if (status < 0)
2320 goto error;
2321 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2322 status = write16(state, IQM_AF_STDBY__A, data);
2323 if (status < 0)
2324 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002325
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002326 /* Disable SCU RF AGC loop */
2327 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2328 if (status < 0)
2329 goto error;
2330 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2331 if (state->m_RfAgcPol)
2332 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2333 else
2334 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2335 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2336 if (status < 0)
2337 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002338
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002339 /* SCU c.o.c. to 0, enabling full control range */
2340 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2341 if (status < 0)
2342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002344 /* Write value to output pin */
2345 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2346 if (status < 0)
2347 goto error;
2348 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002349
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002350 case DRXK_AGC_CTRL_OFF:
2351 /* Disable RF AGC DAC */
2352 status = read16(state, IQM_AF_STDBY__A, &data);
2353 if (status < 0)
2354 goto error;
2355 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2356 status = write16(state, IQM_AF_STDBY__A, data);
2357 if (status < 0)
2358 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002359
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 /* Disable SCU RF AGC loop */
2361 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2362 if (status < 0)
2363 goto error;
2364 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2365 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2366 if (status < 0)
2367 goto error;
2368 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002369
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002370 default:
2371 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002373 }
2374error:
2375 if (status < 0)
2376 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002377 return status;
2378}
2379
2380#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2381
Oliver Endrissebc7de22011-07-03 13:49:44 -03002382static int SetAgcIf(struct drxk_state *state,
2383 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002384{
2385 u16 data = 0;
2386 int status = 0;
2387 struct SCfgAgc *pRfAgcSettings;
2388
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002389 dprintk(1, "\n");
2390
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002391 switch (pAgcCfg->ctrlMode) {
2392 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002393
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002394 /* Enable IF AGC DAC */
2395 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002396 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002397 goto error;
2398 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2399 status = write16(state, IQM_AF_STDBY__A, data);
2400 if (status < 0)
2401 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002402
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002403 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2404 if (status < 0)
2405 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002406
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002407 /* Enable SCU IF AGC loop */
2408 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2409
2410 /* Polarity */
2411 if (state->m_IfAgcPol)
2412 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2413 else
2414 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2415 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2416 if (status < 0)
2417 goto error;
2418
2419 /* Set speed (using complementary reduction value) */
2420 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2421 if (status < 0)
2422 goto error;
2423 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2424 data |= (~(pAgcCfg->speed <<
2425 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2426 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2427
2428 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2429 if (status < 0)
2430 goto error;
2431
2432 if (IsQAM(state))
2433 pRfAgcSettings = &state->m_qamRfAgcCfg;
2434 else
2435 pRfAgcSettings = &state->m_atvRfAgcCfg;
2436 if (pRfAgcSettings == NULL)
2437 return -1;
2438 /* Restore TOP */
2439 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2440 if (status < 0)
2441 goto error;
2442 break;
2443
2444 case DRXK_AGC_CTRL_USER:
2445
2446 /* Enable IF AGC DAC */
2447 status = read16(state, IQM_AF_STDBY__A, &data);
2448 if (status < 0)
2449 goto error;
2450 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2451 status = write16(state, IQM_AF_STDBY__A, data);
2452 if (status < 0)
2453 goto error;
2454
2455 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2456 if (status < 0)
2457 goto error;
2458
2459 /* Disable SCU IF AGC loop */
2460 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2461
2462 /* Polarity */
2463 if (state->m_IfAgcPol)
2464 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2465 else
2466 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2467 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2468 if (status < 0)
2469 goto error;
2470
2471 /* Write value to output pin */
2472 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2473 if (status < 0)
2474 goto error;
2475 break;
2476
2477 case DRXK_AGC_CTRL_OFF:
2478
2479 /* Disable If AGC DAC */
2480 status = read16(state, IQM_AF_STDBY__A, &data);
2481 if (status < 0)
2482 goto error;
2483 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2484 status = write16(state, IQM_AF_STDBY__A, data);
2485 if (status < 0)
2486 goto error;
2487
2488 /* Disable SCU IF AGC loop */
2489 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2490 if (status < 0)
2491 goto error;
2492 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2493 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2494 if (status < 0)
2495 goto error;
2496 break;
2497 } /* switch (agcSettingsIf->ctrlMode) */
2498
2499 /* always set the top to support
2500 configurations without if-loop */
2501 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2502error:
2503 if (status < 0)
2504 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002505 return status;
2506}
2507
2508static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2509{
2510 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002511 int status;
2512 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002513
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002514 dprintk(1, "\n");
2515
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002516 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2517 if (status < 0) {
2518 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2519 return status;
2520 }
2521
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002522 *pValue = 0;
2523
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002524 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2525 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2526 if (Level < 14000)
2527 *pValue = (14000 - Level) / 4;
2528 else
2529 *pValue = 0;
2530
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002531 return status;
2532}
2533
Oliver Endrissebc7de22011-07-03 13:49:44 -03002534static int GetQAMSignalToNoise(struct drxk_state *state,
2535 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002536{
2537 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002538 u16 qamSlErrPower = 0; /* accum. error between
2539 raw and sliced symbols */
2540 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002541 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002542 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002544 dprintk(1, "\n");
2545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002546 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002547
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002548 /* get the register value needed for MER */
2549 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2550 if (status < 0) {
2551 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2552 return -EINVAL;
2553 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002554
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002555 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002556 case QAM_16:
2557 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2558 break;
2559 case QAM_32:
2560 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2561 break;
2562 case QAM_64:
2563 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2564 break;
2565 case QAM_128:
2566 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2567 break;
2568 default:
2569 case QAM_256:
2570 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2571 break;
2572 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002573
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002574 if (qamSlErrPower > 0) {
2575 qamSlMer = Log10Times100(qamSlSigPower) -
2576 Log10Times100((u32) qamSlErrPower);
2577 }
2578 *pSignalToNoise = qamSlMer;
2579
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002580 return status;
2581}
2582
Oliver Endrissebc7de22011-07-03 13:49:44 -03002583static int GetDVBTSignalToNoise(struct drxk_state *state,
2584 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002585{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002586 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002587 u16 regData = 0;
2588 u32 EqRegTdSqrErrI = 0;
2589 u32 EqRegTdSqrErrQ = 0;
2590 u16 EqRegTdSqrErrExp = 0;
2591 u16 EqRegTdTpsPwrOfs = 0;
2592 u16 EqRegTdReqSmbCnt = 0;
2593 u32 tpsCnt = 0;
2594 u32 SqrErrIQ = 0;
2595 u32 a = 0;
2596 u32 b = 0;
2597 u32 c = 0;
2598 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002599 u16 transmissionParams = 0;
2600
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002601 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002602
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002603 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2604 if (status < 0)
2605 goto error;
2606 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2607 if (status < 0)
2608 goto error;
2609 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2610 if (status < 0)
2611 goto error;
2612 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2613 if (status < 0)
2614 goto error;
2615 /* Extend SQR_ERR_I operational range */
2616 EqRegTdSqrErrI = (u32) regData;
2617 if ((EqRegTdSqrErrExp > 11) &&
2618 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2619 EqRegTdSqrErrI += 0x00010000UL;
2620 }
2621 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2622 if (status < 0)
2623 goto error;
2624 /* Extend SQR_ERR_Q operational range */
2625 EqRegTdSqrErrQ = (u32) regData;
2626 if ((EqRegTdSqrErrExp > 11) &&
2627 (EqRegTdSqrErrQ < 0x00000FFFUL))
2628 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002629
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002630 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2631 if (status < 0)
2632 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002633
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002634 /* Check input data for MER */
2635
2636 /* MER calculation (in 0.1 dB) without math.h */
2637 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2638 iMER = 0;
2639 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2640 /* No error at all, this must be the HW reset value
2641 * Apparently no first measurement yet
2642 * Set MER to 0.0 */
2643 iMER = 0;
2644 } else {
2645 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2646 EqRegTdSqrErrExp;
2647 if ((transmissionParams &
2648 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2649 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2650 tpsCnt = 17;
2651 else
2652 tpsCnt = 68;
2653
2654 /* IMER = 100 * log10 (x)
2655 where x = (EqRegTdTpsPwrOfs^2 *
2656 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2657
2658 => IMER = a + b -c
2659 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2660 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2661 c = 100 * log10 (SqrErrIQ)
2662 */
2663
2664 /* log(x) x = 9bits * 9bits->18 bits */
2665 a = Log10Times100(EqRegTdTpsPwrOfs *
2666 EqRegTdTpsPwrOfs);
2667 /* log(x) x = 16bits * 7bits->23 bits */
2668 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2669 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2670 c = Log10Times100(SqrErrIQ);
2671
2672 iMER = a + b;
2673 /* No negative MER, clip to zero */
2674 if (iMER > c)
2675 iMER -= c;
2676 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002677 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002678 }
2679 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002680
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002681error:
2682 if (status < 0)
2683 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002684 return status;
2685}
2686
2687static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2688{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002689 dprintk(1, "\n");
2690
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002691 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002692 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002693 case OM_DVBT:
2694 return GetDVBTSignalToNoise(state, pSignalToNoise);
2695 case OM_QAM_ITU_A:
2696 case OM_QAM_ITU_C:
2697 return GetQAMSignalToNoise(state, pSignalToNoise);
2698 default:
2699 break;
2700 }
2701 return 0;
2702}
2703
2704#if 0
2705static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2706{
2707 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2708 int status = 0;
2709
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002710 dprintk(1, "\n");
2711
Oliver Endrissebc7de22011-07-03 13:49:44 -03002712 static s32 QE_SN[] = {
2713 51, /* QPSK 1/2 */
2714 69, /* QPSK 2/3 */
2715 79, /* QPSK 3/4 */
2716 89, /* QPSK 5/6 */
2717 97, /* QPSK 7/8 */
2718 108, /* 16-QAM 1/2 */
2719 131, /* 16-QAM 2/3 */
2720 146, /* 16-QAM 3/4 */
2721 156, /* 16-QAM 5/6 */
2722 160, /* 16-QAM 7/8 */
2723 165, /* 64-QAM 1/2 */
2724 187, /* 64-QAM 2/3 */
2725 202, /* 64-QAM 3/4 */
2726 216, /* 64-QAM 5/6 */
2727 225, /* 64-QAM 7/8 */
2728 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002729
2730 *pQuality = 0;
2731
2732 do {
2733 s32 SignalToNoise = 0;
2734 u16 Constellation = 0;
2735 u16 CodeRate = 0;
2736 u32 SignalToNoiseRel;
2737 u32 BERQuality;
2738
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002739 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2740 if (status < 0)
2741 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002742 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002743 if (status < 0)
2744 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002745 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2746
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002747 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002748 if (status < 0)
2749 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002750 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2751
2752 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2753 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2754 break;
2755 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002756 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757 BERQuality = 100;
2758
Oliver Endrissebc7de22011-07-03 13:49:44 -03002759 if (SignalToNoiseRel < -70)
2760 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002761 else if (SignalToNoiseRel < 30)
2762 *pQuality = ((SignalToNoiseRel + 70) *
2763 BERQuality) / 100;
2764 else
2765 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002766 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767 return 0;
2768};
2769
Oliver Endrissebc7de22011-07-03 13:49:44 -03002770static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002771{
2772 int status = 0;
2773 *pQuality = 0;
2774
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002775 dprintk(1, "\n");
2776
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002777 do {
2778 u32 SignalToNoise = 0;
2779 u32 BERQuality = 100;
2780 u32 SignalToNoiseRel = 0;
2781
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002782 status = GetQAMSignalToNoise(state, &SignalToNoise);
2783 if (status < 0)
2784 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002785
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002786 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002787 case QAM_16:
2788 SignalToNoiseRel = SignalToNoise - 200;
2789 break;
2790 case QAM_32:
2791 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002793 case QAM_64:
2794 SignalToNoiseRel = SignalToNoise - 260;
2795 break;
2796 case QAM_128:
2797 SignalToNoiseRel = SignalToNoise - 290;
2798 break;
2799 default:
2800 case QAM_256:
2801 SignalToNoiseRel = SignalToNoise - 320;
2802 break;
2803 }
2804
2805 if (SignalToNoiseRel < -70)
2806 *pQuality = 0;
2807 else if (SignalToNoiseRel < 30)
2808 *pQuality = ((SignalToNoiseRel + 70) *
2809 BERQuality) / 100;
2810 else
2811 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002812 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002813
2814 return status;
2815}
2816
2817static int GetQuality(struct drxk_state *state, s32 *pQuality)
2818{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002819 dprintk(1, "\n");
2820
Oliver Endrissebc7de22011-07-03 13:49:44 -03002821 switch (state->m_OperationMode) {
2822 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002823 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002824 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002825 return GetDVBCQuality(state, pQuality);
2826 default:
2827 break;
2828 }
2829
2830 return 0;
2831}
2832#endif
2833
2834/* Free data ram in SIO HI */
2835#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2836#define SIO_HI_RA_RAM_USR_END__A 0x420060
2837
2838#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2839#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2840#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2841#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2842
2843#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2844#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2845#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2846
2847static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2848{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002849 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002850
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002851 dprintk(1, "\n");
2852
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002853 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002854 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002856 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002858 if (state->no_i2c_bridge)
2859 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002860
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002861 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2862 if (status < 0)
2863 goto error;
2864 if (bEnableBridge) {
2865 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 -03002866 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002867 goto error;
2868 } else {
2869 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2870 if (status < 0)
2871 goto error;
2872 }
2873
2874 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2875
2876error:
2877 if (status < 0)
2878 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002879 return status;
2880}
2881
Oliver Endrissebc7de22011-07-03 13:49:44 -03002882static int SetPreSaw(struct drxk_state *state,
2883 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002884{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002885 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002886
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002887 dprintk(1, "\n");
2888
Oliver Endrissebc7de22011-07-03 13:49:44 -03002889 if ((pPreSawCfg == NULL)
2890 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002891 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002892
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002893 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002894error:
2895 if (status < 0)
2896 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002897 return status;
2898}
2899
2900static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002901 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002902{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002903 u16 blStatus = 0;
2904 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2905 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2906 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002907 unsigned long end;
2908
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002909 dprintk(1, "\n");
2910
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002911 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002912 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2913 if (status < 0)
2914 goto error;
2915 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2916 if (status < 0)
2917 goto error;
2918 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2919 if (status < 0)
2920 goto error;
2921 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2922 if (status < 0)
2923 goto error;
2924 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2925 if (status < 0)
2926 goto error;
2927 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2928 if (status < 0)
2929 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002930
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002931 end = jiffies + msecs_to_jiffies(timeOut);
2932 do {
2933 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2934 if (status < 0)
2935 goto error;
2936 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2937 if (blStatus == 0x1) {
2938 printk(KERN_ERR "drxk: SIO not ready\n");
2939 status = -EINVAL;
2940 goto error2;
2941 }
2942error:
2943 if (status < 0)
2944 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2945error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002946 mutex_unlock(&state->mutex);
2947 return status;
2948
2949}
2950
Oliver Endrissebc7de22011-07-03 13:49:44 -03002951static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002952{
2953 u16 data = 0;
2954 int status;
2955
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002956 dprintk(1, "\n");
2957
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002958 /* Start measurement */
2959 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2960 if (status < 0)
2961 goto error;
2962 status = write16(state, IQM_AF_START_LOCK__A, 1);
2963 if (status < 0)
2964 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002965
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002966 *count = 0;
2967 status = read16(state, IQM_AF_PHASE0__A, &data);
2968 if (status < 0)
2969 goto error;
2970 if (data == 127)
2971 *count = *count + 1;
2972 status = read16(state, IQM_AF_PHASE1__A, &data);
2973 if (status < 0)
2974 goto error;
2975 if (data == 127)
2976 *count = *count + 1;
2977 status = read16(state, IQM_AF_PHASE2__A, &data);
2978 if (status < 0)
2979 goto error;
2980 if (data == 127)
2981 *count = *count + 1;
2982
2983error:
2984 if (status < 0)
2985 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002986 return status;
2987}
2988
2989static int ADCSynchronization(struct drxk_state *state)
2990{
2991 u16 count = 0;
2992 int status;
2993
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002994 dprintk(1, "\n");
2995
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002996 status = ADCSyncMeasurement(state, &count);
2997 if (status < 0)
2998 goto error;
2999
3000 if (count == 1) {
3001 /* Try sampling on a diffrent edge */
3002 u16 clkNeg = 0;
3003
3004 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
3005 if (status < 0)
3006 goto error;
3007 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
3008 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
3009 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
3010 clkNeg |=
3011 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
3012 } else {
3013 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
3014 clkNeg |=
3015 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
3016 }
3017 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
3018 if (status < 0)
3019 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003020 status = ADCSyncMeasurement(state, &count);
3021 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003022 goto error;
3023 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003024
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003025 if (count < 2)
3026 status = -EINVAL;
3027error:
3028 if (status < 0)
3029 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003030 return status;
3031}
3032
3033static int SetFrequencyShifter(struct drxk_state *state,
3034 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003035 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003036{
3037 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003038 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003039 u32 fmFrequencyShift = 0;
3040 bool tunerMirror = !state->m_bMirrorFreqSpect;
3041 u32 adcFreq;
3042 bool adcFlip;
3043 int status;
3044 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003045 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003046 u32 frequencyShift;
3047 bool imageToSelect;
3048
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003049 dprintk(1, "\n");
3050
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003051 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003052 Program frequency shifter
3053 No need to account for mirroring on RF
3054 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055 if (isDTV) {
3056 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3057 (state->m_OperationMode == OM_QAM_ITU_C) ||
3058 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003059 selectPosImage = true;
3060 else
3061 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003062 }
3063 if (tunerMirror)
3064 /* tuner doesn't mirror */
3065 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003066 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003067 else
3068 /* tuner mirrors */
3069 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003070 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003071 if (ifFreqActual > samplingFrequency / 2) {
3072 /* adc mirrors */
3073 adcFreq = samplingFrequency - ifFreqActual;
3074 adcFlip = true;
3075 } else {
3076 /* adc doesn't mirror */
3077 adcFreq = ifFreqActual;
3078 adcFlip = false;
3079 }
3080
3081 frequencyShift = adcFreq;
3082 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003083 adcFlip ^ selectPosImage;
3084 state->m_IqmFsRateOfs =
3085 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003086
3087 if (imageToSelect)
3088 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3089
3090 /* Program frequency shifter with tuner offset compensation */
3091 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003092 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3093 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003094 if (status < 0)
3095 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003096 return status;
3097}
3098
3099static int InitAGC(struct drxk_state *state, bool isDTV)
3100{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003101 u16 ingainTgt = 0;
3102 u16 ingainTgtMin = 0;
3103 u16 ingainTgtMax = 0;
3104 u16 clpCyclen = 0;
3105 u16 clpSumMin = 0;
3106 u16 clpDirTo = 0;
3107 u16 snsSumMin = 0;
3108 u16 snsSumMax = 0;
3109 u16 clpSumMax = 0;
3110 u16 snsDirTo = 0;
3111 u16 kiInnergainMin = 0;
3112 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003113 u16 ifIaccuHiTgtMin = 0;
3114 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003115 u16 data = 0;
3116 u16 fastClpCtrlDelay = 0;
3117 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003118 int status = 0;
3119
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003120 dprintk(1, "\n");
3121
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003122 /* Common settings */
3123 snsSumMax = 1023;
3124 ifIaccuHiTgtMin = 2047;
3125 clpCyclen = 500;
3126 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003127
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003128 /* AGCInit() not available for DVBT; init done in microcode */
3129 if (!IsQAM(state)) {
3130 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3131 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003132 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003133
3134 /* FIXME: Analog TV AGC require different settings */
3135
3136 /* Standard specific settings */
3137 clpSumMin = 8;
3138 clpDirTo = (u16) -9;
3139 clpCtrlMode = 0;
3140 snsSumMin = 8;
3141 snsDirTo = (u16) -9;
3142 kiInnergainMin = (u16) -1030;
3143 ifIaccuHiTgtMax = 0x2380;
3144 ifIaccuHiTgt = 0x2380;
3145 ingainTgtMin = 0x0511;
3146 ingainTgt = 0x0511;
3147 ingainTgtMax = 5119;
3148 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003150 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3151 if (status < 0)
3152 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003154 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3173 if (status < 0)
3174 goto error;
3175 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3176 if (status < 0)
3177 goto error;
3178 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3179 if (status < 0)
3180 goto error;
3181 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3182 if (status < 0)
3183 goto error;
3184 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3185 if (status < 0)
3186 goto error;
3187 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3188 if (status < 0)
3189 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003190
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003191 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3198 if (status < 0)
3199 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003200
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003201 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3202 if (status < 0)
3203 goto error;
3204 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3205 if (status < 0)
3206 goto error;
3207 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3208 if (status < 0)
3209 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003211 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3212 if (status < 0)
3213 goto error;
3214 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3215 if (status < 0)
3216 goto error;
3217 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3218 if (status < 0)
3219 goto error;
3220 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3221 if (status < 0)
3222 goto error;
3223 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3224 if (status < 0)
3225 goto error;
3226 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3227 if (status < 0)
3228 goto error;
3229 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3230 if (status < 0)
3231 goto error;
3232 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3233 if (status < 0)
3234 goto error;
3235 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3236 if (status < 0)
3237 goto error;
3238 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3239 if (status < 0)
3240 goto error;
3241 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3242 if (status < 0)
3243 goto error;
3244 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3245 if (status < 0)
3246 goto error;
3247 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3248 if (status < 0)
3249 goto error;
3250 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3251 if (status < 0)
3252 goto error;
3253 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3254 if (status < 0)
3255 goto error;
3256 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3257 if (status < 0)
3258 goto error;
3259 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3260 if (status < 0)
3261 goto error;
3262 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3263 if (status < 0)
3264 goto error;
3265 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3266 if (status < 0)
3267 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003269 /* Initialize inner-loop KI gain factors */
3270 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3271 if (status < 0)
3272 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003273
3274 data = 0x0657;
3275 data &= ~SCU_RAM_AGC_KI_RF__M;
3276 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3277 data &= ~SCU_RAM_AGC_KI_IF__M;
3278 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3279
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003280 status = write16(state, SCU_RAM_AGC_KI__A, data);
3281error:
3282 if (status < 0)
3283 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 return status;
3285}
3286
Oliver Endrissebc7de22011-07-03 13:49:44 -03003287static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288{
3289 int status;
3290
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003291 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003292 if (packetErr == NULL)
3293 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3294 else
3295 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3296 if (status < 0)
3297 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003298 return status;
3299}
3300
3301static int DVBTScCommand(struct drxk_state *state,
3302 u16 cmd, u16 subcmd,
3303 u16 param0, u16 param1, u16 param2,
3304 u16 param3, u16 param4)
3305{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003306 u16 curCmd = 0;
3307 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003309 u16 scExec = 0;
3310 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003312 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003313 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003314 if (scExec != 1) {
3315 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003316 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003317 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003318 if (status < 0)
3319 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003320
3321 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003322 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003323 do {
3324 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003325 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003326 retryCnt++;
3327 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3329 goto error;
3330
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331 /* Write sub-command */
3332 switch (cmd) {
3333 /* All commands using sub-cmd */
3334 case OFDM_SC_RA_RAM_CMD_PROC_START:
3335 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3336 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003337 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3338 if (status < 0)
3339 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003340 break;
3341 default:
3342 /* Do nothing */
3343 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003344 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003345
3346 /* Write needed parameters and the command */
3347 switch (cmd) {
3348 /* All commands using 5 parameters */
3349 /* All commands using 4 parameters */
3350 /* All commands using 3 parameters */
3351 /* All commands using 2 parameters */
3352 case OFDM_SC_RA_RAM_CMD_PROC_START:
3353 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3354 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003356 /* All commands using 1 parameters */
3357 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3358 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360 /* All commands using 0 parameters */
3361 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3362 case OFDM_SC_RA_RAM_CMD_NULL:
3363 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003364 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003365 break;
3366 default:
3367 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003368 status = -EINVAL;
3369 }
3370 if (status < 0)
3371 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372
3373 /* Wait until sc is ready processing command */
3374 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003375 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003377 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003378 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003379 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003380 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3381 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382
3383 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003384 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003385 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003386 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003387 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003389 if (status < 0)
3390 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003391
3392 /* Retreive results parameters from SC */
3393 switch (cmd) {
3394 /* All commands yielding 5 results */
3395 /* All commands yielding 4 results */
3396 /* All commands yielding 3 results */
3397 /* All commands yielding 2 results */
3398 /* All commands yielding 1 result */
3399 case OFDM_SC_RA_RAM_CMD_USER_IO:
3400 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003401 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402 /* All commands yielding 0 results */
3403 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3404 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3405 case OFDM_SC_RA_RAM_CMD_PROC_START:
3406 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3407 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3408 case OFDM_SC_RA_RAM_CMD_NULL:
3409 break;
3410 default:
3411 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003412 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003413 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003414 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003415error:
3416 if (status < 0)
3417 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003418 return status;
3419}
3420
Oliver Endrissebc7de22011-07-03 13:49:44 -03003421static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003422{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003423 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003424 int status;
3425
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003426 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003427 status = CtrlPowerMode(state, &powerMode);
3428 if (status < 0)
3429 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003430 return status;
3431}
3432
Oliver Endrissebc7de22011-07-03 13:49:44 -03003433static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003434{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003435 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003436
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003437 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003438 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003439 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003440 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003441 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003442 if (status < 0)
3443 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003444 return status;
3445}
3446
3447#define DEFAULT_FR_THRES_8K 4000
3448static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3449{
3450
3451 int status;
3452
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003453 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003454 if (*enabled == true) {
3455 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003456 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003457 DEFAULT_FR_THRES_8K);
3458 } else {
3459 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003460 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003461 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003462 if (status < 0)
3463 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003464
3465 return status;
3466}
3467
3468static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3469 struct DRXKCfgDvbtEchoThres_t *echoThres)
3470{
3471 u16 data = 0;
3472 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003473
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003474 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003475 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3476 if (status < 0)
3477 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003479 switch (echoThres->fftMode) {
3480 case DRX_FFTMODE_2K:
3481 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3482 data |= ((echoThres->threshold <<
3483 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3484 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003485 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003486 case DRX_FFTMODE_8K:
3487 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3488 data |= ((echoThres->threshold <<
3489 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3490 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003491 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003492 default:
3493 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003494 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003495
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003496 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3497error:
3498 if (status < 0)
3499 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003500 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501}
3502
3503static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003504 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003505{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003506 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003507
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003508 dprintk(1, "\n");
3509
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003510 switch (*speed) {
3511 case DRXK_DVBT_SQI_SPEED_FAST:
3512 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3513 case DRXK_DVBT_SQI_SPEED_SLOW:
3514 break;
3515 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003516 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003517 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003518 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003519 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003520error:
3521 if (status < 0)
3522 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003523 return status;
3524}
3525
3526/*============================================================================*/
3527
3528/**
3529* \brief Activate DVBT specific presets
3530* \param demod instance of demodulator.
3531* \return DRXStatus_t.
3532*
3533* Called in DVBTSetStandard
3534*
3535*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003536static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003537{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003538 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003539 bool setincenable = false;
3540 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003541
Oliver Endrissebc7de22011-07-03 13:49:44 -03003542 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3543 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003544
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003545 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003546 status = DVBTCtrlSetIncEnable(state, &setincenable);
3547 if (status < 0)
3548 goto error;
3549 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3550 if (status < 0)
3551 goto error;
3552 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3553 if (status < 0)
3554 goto error;
3555 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3556 if (status < 0)
3557 goto error;
3558 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3559error:
3560 if (status < 0)
3561 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003562 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003563}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003564
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003565/*============================================================================*/
3566
3567/**
3568* \brief Initialize channelswitch-independent settings for DVBT.
3569* \param demod instance of demodulator.
3570* \return DRXStatus_t.
3571*
3572* For ROM code channel filter taps are loaded from the bootloader. For microcode
3573* the DVB-T taps from the drxk_filters.h are used.
3574*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003575static int SetDVBTStandard(struct drxk_state *state,
3576 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003577{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003578 u16 cmdResult = 0;
3579 u16 data = 0;
3580 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003581
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003582 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003583
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003584 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003585 /* added antenna switch */
3586 SwitchAntennaToDVBT(state);
3587 /* send OFDM reset command */
3588 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 -03003589 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003590 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003591
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003592 /* send OFDM setenv command */
3593 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3594 if (status < 0)
3595 goto error;
3596
3597 /* reset datapath for OFDM, processors first */
3598 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3599 if (status < 0)
3600 goto error;
3601 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3602 if (status < 0)
3603 goto error;
3604 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3605 if (status < 0)
3606 goto error;
3607
3608 /* IQM setup */
3609 /* synchronize on ofdstate->m_festart */
3610 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3611 if (status < 0)
3612 goto error;
3613 /* window size for clipping ADC detection */
3614 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3615 if (status < 0)
3616 goto error;
3617 /* window size for for sense pre-SAW detection */
3618 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3619 if (status < 0)
3620 goto error;
3621 /* sense threshold for sense pre-SAW detection */
3622 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3623 if (status < 0)
3624 goto error;
3625 status = SetIqmAf(state, true);
3626 if (status < 0)
3627 goto error;
3628
3629 status = write16(state, IQM_AF_AGC_RF__A, 0);
3630 if (status < 0)
3631 goto error;
3632
3633 /* Impulse noise cruncher setup */
3634 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3635 if (status < 0)
3636 goto error;
3637 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3638 if (status < 0)
3639 goto error;
3640 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3641 if (status < 0)
3642 goto error;
3643
3644 status = write16(state, IQM_RC_STRETCH__A, 16);
3645 if (status < 0)
3646 goto error;
3647 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3648 if (status < 0)
3649 goto error;
3650 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3651 if (status < 0)
3652 goto error;
3653 status = write16(state, IQM_CF_SCALE__A, 1600);
3654 if (status < 0)
3655 goto error;
3656 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3657 if (status < 0)
3658 goto error;
3659
3660 /* virtual clipping threshold for clipping ADC detection */
3661 status = write16(state, IQM_AF_CLP_TH__A, 448);
3662 if (status < 0)
3663 goto error;
3664 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3665 if (status < 0)
3666 goto error;
3667
3668 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3669 if (status < 0)
3670 goto error;
3671
3672 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3673 if (status < 0)
3674 goto error;
3675 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3676 if (status < 0)
3677 goto error;
3678 /* enable power measurement interrupt */
3679 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3680 if (status < 0)
3681 goto error;
3682 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3683 if (status < 0)
3684 goto error;
3685
3686 /* IQM will not be reset from here, sync ADC and update/init AGC */
3687 status = ADCSynchronization(state);
3688 if (status < 0)
3689 goto error;
3690 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3691 if (status < 0)
3692 goto error;
3693
3694 /* Halt SCU to enable safe non-atomic accesses */
3695 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3696 if (status < 0)
3697 goto error;
3698
3699 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3700 if (status < 0)
3701 goto error;
3702 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3703 if (status < 0)
3704 goto error;
3705
3706 /* Set Noise Estimation notch width and enable DC fix */
3707 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3708 if (status < 0)
3709 goto error;
3710 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3711 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3712 if (status < 0)
3713 goto error;
3714
3715 /* Activate SCU to enable SCU commands */
3716 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3717 if (status < 0)
3718 goto error;
3719
3720 if (!state->m_DRXK_A3_ROM_CODE) {
3721 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3722 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3723 if (status < 0)
3724 goto error;
3725 }
3726
3727 /* OFDM_SC setup */
3728#ifdef COMPILE_FOR_NONRT
3729 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3730 if (status < 0)
3731 goto error;
3732 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3733 if (status < 0)
3734 goto error;
3735#endif
3736
3737 /* FEC setup */
3738 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3739 if (status < 0)
3740 goto error;
3741
3742
3743#ifdef COMPILE_FOR_NONRT
3744 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3745 if (status < 0)
3746 goto error;
3747#else
3748 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3749 if (status < 0)
3750 goto error;
3751#endif
3752 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3753 if (status < 0)
3754 goto error;
3755
3756 /* Setup MPEG bus */
3757 status = MPEGTSDtoSetup(state, OM_DVBT);
3758 if (status < 0)
3759 goto error;
3760 /* Set DVBT Presets */
3761 status = DVBTActivatePresets(state);
3762 if (status < 0)
3763 goto error;
3764
3765error:
3766 if (status < 0)
3767 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768 return status;
3769}
3770
3771/*============================================================================*/
3772/**
3773* \brief Start dvbt demodulating for channel.
3774* \param demod instance of demodulator.
3775* \return DRXStatus_t.
3776*/
3777static int DVBTStart(struct drxk_state *state)
3778{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003779 u16 param1;
3780 int status;
3781 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003782
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003783 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003784 /* Start correct processes to get in lock */
3785 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003786 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3787 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3788 if (status < 0)
3789 goto error;
3790 /* Start FEC OC */
3791 status = MPEGTSStart(state);
3792 if (status < 0)
3793 goto error;
3794 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3795 if (status < 0)
3796 goto error;
3797error:
3798 if (status < 0)
3799 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003800 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003801}
3802
3803
3804/*============================================================================*/
3805
3806/**
3807* \brief Set up dvbt demodulator for channel.
3808* \param demod instance of demodulator.
3809* \return DRXStatus_t.
3810* // original DVBTSetChannel()
3811*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003812static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3813 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003814{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003815 u16 cmdResult = 0;
3816 u16 transmissionParams = 0;
3817 u16 operationMode = 0;
3818 u32 iqmRcRateOfs = 0;
3819 u32 bandwidth = 0;
3820 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003821 int status;
3822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003823 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003824
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003825 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3826 if (status < 0)
3827 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003829 /* Halt SCU to enable safe non-atomic accesses */
3830 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3831 if (status < 0)
3832 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003833
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003834 /* Stop processors */
3835 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3836 if (status < 0)
3837 goto error;
3838 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3839 if (status < 0)
3840 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003841
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003842 /* Mandatory fix, always stop CP, required to set spl offset back to
3843 hardware default (is set to 0 by ucode during pilot detection */
3844 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3845 if (status < 0)
3846 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003847
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003848 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003849
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003850 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003851 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 case TRANSMISSION_MODE_AUTO:
3853 default:
3854 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3855 /* fall through , try first guess DRX_FFTMODE_8K */
3856 case TRANSMISSION_MODE_8K:
3857 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003858 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003859 case TRANSMISSION_MODE_2K:
3860 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003861 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003862 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003863
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003864 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003865 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003866 default:
3867 case GUARD_INTERVAL_AUTO:
3868 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3869 /* fall through , try first guess DRX_GUARD_1DIV4 */
3870 case GUARD_INTERVAL_1_4:
3871 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003872 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003873 case GUARD_INTERVAL_1_32:
3874 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003875 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003876 case GUARD_INTERVAL_1_16:
3877 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003878 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003879 case GUARD_INTERVAL_1_8:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003881 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003882 }
3883
3884 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003885 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 case HIERARCHY_AUTO:
3887 case HIERARCHY_NONE:
3888 default:
3889 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3890 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3891 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3892 /* break; */
3893 case HIERARCHY_1:
3894 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3895 break;
3896 case HIERARCHY_2:
3897 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3898 break;
3899 case HIERARCHY_4:
3900 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3901 break;
3902 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003903
3904
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003905 /* modulation */
3906 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003907 case QAM_AUTO:
3908 default:
3909 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3910 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3911 case QAM_64:
3912 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3913 break;
3914 case QPSK:
3915 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3916 break;
3917 case QAM_16:
3918 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3919 break;
3920 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003921#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003922 /* No hierachical channels support in BDA */
3923 /* Priority (only for hierarchical channels) */
3924 switch (channel->priority) {
3925 case DRX_PRIORITY_LOW:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3927 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3928 OFDM_EC_SB_PRIOR_LO);
3929 break;
3930 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003931 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003932 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3933 OFDM_EC_SB_PRIOR_HI));
3934 break;
3935 case DRX_PRIORITY_UNKNOWN: /* fall through */
3936 default:
3937 status = -EINVAL;
3938 goto error;
3939 }
3940#else
3941 /* Set Priorty high */
3942 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3943 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3944 if (status < 0)
3945 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003946#endif
3947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003948 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003949 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003950 case FEC_AUTO:
3951 default:
3952 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3953 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3954 case FEC_2_3:
3955 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3956 break;
3957 case FEC_1_2:
3958 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3959 break;
3960 case FEC_3_4:
3961 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3962 break;
3963 case FEC_5_6:
3964 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3965 break;
3966 case FEC_7_8:
3967 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3968 break;
3969 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003970
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003971 /* SAW filter selection: normaly not necesarry, but if wanted
3972 the application can select a SAW filter via the driver by using UIOs */
3973 /* First determine real bandwidth (Hz) */
3974 /* Also set delay for impulse noise cruncher */
3975 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3976 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3977 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003978 switch (state->props.bandwidth_hz) {
3979 case 0:
3980 state->props.bandwidth_hz = 8000000;
3981 /* fall though */
3982 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003983 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3984 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003985 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003986 goto error;
3987 /* cochannel protection for PAL 8 MHz */
3988 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3989 if (status < 0)
3990 goto error;
3991 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3992 if (status < 0)
3993 goto error;
3994 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3995 if (status < 0)
3996 goto error;
3997 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3998 if (status < 0)
3999 goto error;
4000 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004001 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004002 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
4003 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
4004 if (status < 0)
4005 goto error;
4006 /* cochannel protection for PAL 7 MHz */
4007 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
4008 if (status < 0)
4009 goto error;
4010 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
4011 if (status < 0)
4012 goto error;
4013 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
4014 if (status < 0)
4015 goto error;
4016 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4017 if (status < 0)
4018 goto error;
4019 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004020 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004021 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
4022 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
4023 if (status < 0)
4024 goto error;
4025 /* cochannel protection for NTSC 6 MHz */
4026 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
4027 if (status < 0)
4028 goto error;
4029 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4030 if (status < 0)
4031 goto error;
4032 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4033 if (status < 0)
4034 goto error;
4035 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4036 if (status < 0)
4037 goto error;
4038 break;
4039 default:
4040 status = -EINVAL;
4041 goto error;
4042 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004044 if (iqmRcRateOfs == 0) {
4045 /* Now compute IQM_RC_RATE_OFS
4046 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4047 =>
4048 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4049 */
4050 /* (SysFreq / BandWidth) * (2^28) */
4051 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4052 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4053 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4054 iqmRcRateOfs = Frac28a((u32)
4055 ((state->m_sysClockFreq *
4056 1000) / 3), bandwidth);
4057 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4058 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4059 iqmRcRateOfs += 0x80L;
4060 iqmRcRateOfs = iqmRcRateOfs >> 7;
4061 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4062 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4063 }
4064
4065 iqmRcRateOfs &=
4066 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4067 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4068 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4069 if (status < 0)
4070 goto error;
4071
4072 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004073
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004074#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004075 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4076 if (status < 0)
4077 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004078#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004079 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4080 if (status < 0)
4081 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004083 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004084
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004085 /* Activate SCU to enable SCU commands */
4086 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4087 if (status < 0)
4088 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004089
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004090 /* Enable SC after setting all other parameters */
4091 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4092 if (status < 0)
4093 goto error;
4094 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4095 if (status < 0)
4096 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004097
4098
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004099 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4100 if (status < 0)
4101 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004102
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004103 /* Write SC parameter registers, set all AUTO flags in operation mode */
4104 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4105 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4106 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4107 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4108 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4109 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4110 0, transmissionParams, param1, 0, 0, 0);
4111 if (status < 0)
4112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004114 if (!state->m_DRXK_A3_ROM_CODE)
4115 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4116error:
4117 if (status < 0)
4118 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004119
4120 return status;
4121}
4122
4123
4124/*============================================================================*/
4125
4126/**
4127* \brief Retreive lock status .
4128* \param demod Pointer to demodulator instance.
4129* \param lockStat Pointer to lock status structure.
4130* \return DRXStatus_t.
4131*
4132*/
4133static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4134{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004135 int status;
4136 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4137 OFDM_SC_RA_RAM_LOCK_FEC__M);
4138 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4139 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141 u16 ScRaRamLock = 0;
4142 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004144 dprintk(1, "\n");
4145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004146 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004147 /* driver 0.9.0 */
4148 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004149 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004150 if (status < 0)
4151 goto end;
4152 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4153 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004155 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004156 if (status < 0)
4157 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004158
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4160 *pLockStatus = MPEG_LOCK;
4161 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4162 *pLockStatus = FEC_LOCK;
4163 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4164 *pLockStatus = DEMOD_LOCK;
4165 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4166 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004167end:
4168 if (status < 0)
4169 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004170
Oliver Endrissebc7de22011-07-03 13:49:44 -03004171 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004172}
4173
Oliver Endrissebc7de22011-07-03 13:49:44 -03004174static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004175{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004176 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004177 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004178
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004179 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004180 status = CtrlPowerMode(state, &powerMode);
4181 if (status < 0)
4182 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004183
Oliver Endrissebc7de22011-07-03 13:49:44 -03004184 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004185}
4186
4187
Oliver Endrissebc7de22011-07-03 13:49:44 -03004188/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004189static int PowerDownQAM(struct drxk_state *state)
4190{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004191 u16 data = 0;
4192 u16 cmdResult;
4193 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004194
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004195 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004196 status = read16(state, SCU_COMM_EXEC__A, &data);
4197 if (status < 0)
4198 goto error;
4199 if (data == SCU_COMM_EXEC_ACTIVE) {
4200 /*
4201 STOP demodulator
4202 QAM and HW blocks
4203 */
4204 /* stop all comstate->m_exec */
4205 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004206 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004207 goto error;
4208 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 -03004209 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004210 goto error;
4211 }
4212 /* powerdown AFE */
4213 status = SetIqmAf(state, false);
4214
4215error:
4216 if (status < 0)
4217 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004218
Oliver Endrissebc7de22011-07-03 13:49:44 -03004219 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004220}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004221
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004222/*============================================================================*/
4223
4224/**
4225* \brief Setup of the QAM Measurement intervals for signal quality
4226* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004227* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004228* \return DRXStatus_t.
4229*
4230* NOTE:
4231* Take into account that for certain settings the errorcounters can overflow.
4232* The implementation does not check this.
4233*
4234*/
4235static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004236 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004237 u32 symbolRate)
4238{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004239 u32 fecBitsDesired = 0; /* BER accounting period */
4240 u32 fecRsPeriodTotal = 0; /* Total period */
4241 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4242 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004243 int status = 0;
4244
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004245 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004246
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004247 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004248 /* fecBitsDesired = symbolRate [kHz] *
4249 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004250 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004251 SyncLoss (== 1) *
4252 ViterbiLoss (==1)
4253 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004254 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004255 case DRX_CONSTELLATION_QAM16:
4256 fecBitsDesired = 4 * symbolRate;
4257 break;
4258 case DRX_CONSTELLATION_QAM32:
4259 fecBitsDesired = 5 * symbolRate;
4260 break;
4261 case DRX_CONSTELLATION_QAM64:
4262 fecBitsDesired = 6 * symbolRate;
4263 break;
4264 case DRX_CONSTELLATION_QAM128:
4265 fecBitsDesired = 7 * symbolRate;
4266 break;
4267 case DRX_CONSTELLATION_QAM256:
4268 fecBitsDesired = 8 * symbolRate;
4269 break;
4270 default:
4271 status = -EINVAL;
4272 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004273 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004274 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004275
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004276 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4277 fecBitsDesired *= 500; /* meas. period [ms] */
4278
4279 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4280 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4281 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4282
4283 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4284 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4285 if (fecRsPrescale == 0) {
4286 /* Divide by zero (though impossible) */
4287 status = -EINVAL;
4288 if (status < 0)
4289 goto error;
4290 }
4291 fecRsPeriod =
4292 ((u16) fecRsPeriodTotal +
4293 (fecRsPrescale >> 1)) / fecRsPrescale;
4294
4295 /* write corresponding registers */
4296 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4297 if (status < 0)
4298 goto error;
4299 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4300 if (status < 0)
4301 goto error;
4302 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4303error:
4304 if (status < 0)
4305 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004306 return status;
4307}
4308
Oliver Endrissebc7de22011-07-03 13:49:44 -03004309static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004310{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004311 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004312
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004313 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004314 /* QAM Equalizer Setup */
4315 /* Equalizer */
4316 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4317 if (status < 0)
4318 goto error;
4319 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4320 if (status < 0)
4321 goto error;
4322 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4323 if (status < 0)
4324 goto error;
4325 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4326 if (status < 0)
4327 goto error;
4328 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4329 if (status < 0)
4330 goto error;
4331 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4332 if (status < 0)
4333 goto error;
4334 /* Decision Feedback Equalizer */
4335 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4351 if (status < 0)
4352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004354 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4355 if (status < 0)
4356 goto error;
4357 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4358 if (status < 0)
4359 goto error;
4360 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4361 if (status < 0)
4362 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004364 /* QAM Slicer Settings */
4365 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4366 if (status < 0)
4367 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004368
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004369 /* QAM Loop Controller Coeficients */
4370 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4392 if (status < 0)
4393 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004394
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004395 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4414 if (status < 0)
4415 goto error;
4416 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4417 if (status < 0)
4418 goto error;
4419 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4420 if (status < 0)
4421 goto error;
4422 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4423 if (status < 0)
4424 goto error;
4425 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4426 if (status < 0)
4427 goto error;
4428 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4429 if (status < 0)
4430 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004431
4432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004433 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004434
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004435 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4436 if (status < 0)
4437 goto error;
4438 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4439 if (status < 0)
4440 goto error;
4441 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4442 if (status < 0)
4443 goto error;
4444 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4445 if (status < 0)
4446 goto error;
4447 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4448 if (status < 0)
4449 goto error;
4450 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4451 if (status < 0)
4452 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004453
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004454 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4455 if (status < 0)
4456 goto error;
4457 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4458 if (status < 0)
4459 goto error;
4460 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4461 if (status < 0)
4462 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004463
4464
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004465 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004466
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004467 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4468 if (status < 0)
4469 goto error;
4470 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4471 if (status < 0)
4472 goto error;
4473 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4486 if (status < 0)
4487 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004489error:
4490 if (status < 0)
4491 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004492 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004493}
4494
4495/*============================================================================*/
4496
4497/**
4498* \brief QAM32 specific setup
4499* \param demod instance of demod.
4500* \return DRXStatus_t.
4501*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004502static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004503{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004504 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004505
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004506 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004507
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004508 /* QAM Equalizer Setup */
4509 /* Equalizer */
4510 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4514 if (status < 0)
4515 goto error;
4516 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4517 if (status < 0)
4518 goto error;
4519 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4520 if (status < 0)
4521 goto error;
4522 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4523 if (status < 0)
4524 goto error;
4525 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4526 if (status < 0)
4527 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004528
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004529 /* Decision Feedback Equalizer */
4530 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4546 if (status < 0)
4547 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004548
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004549 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4553 if (status < 0)
4554 goto error;
4555 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4556 if (status < 0)
4557 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004559 /* QAM Slicer Settings */
4560
4561 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4562 if (status < 0)
4563 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004564
4565
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004566 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004567
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004568 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4590 if (status < 0)
4591 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004593 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4612 if (status < 0)
4613 goto error;
4614 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4615 if (status < 0)
4616 goto error;
4617 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4618 if (status < 0)
4619 goto error;
4620 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4621 if (status < 0)
4622 goto error;
4623 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4624 if (status < 0)
4625 goto error;
4626 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4627 if (status < 0)
4628 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004629
4630
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004631 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004632
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004633 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4649 if (status < 0)
4650 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004651
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004652 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4653 if (status < 0)
4654 goto error;
4655 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4656 if (status < 0)
4657 goto error;
4658 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4659 if (status < 0)
4660 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004661
4662
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004663 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004664
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004665 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4666 if (status < 0)
4667 goto error;
4668 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4669 if (status < 0)
4670 goto error;
4671 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4672 if (status < 0)
4673 goto error;
4674 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4675 if (status < 0)
4676 goto error;
4677 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4678 if (status < 0)
4679 goto error;
4680 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4681 if (status < 0)
4682 goto error;
4683 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4684error:
4685 if (status < 0)
4686 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004687 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004688}
4689
4690/*============================================================================*/
4691
4692/**
4693* \brief QAM64 specific setup
4694* \param demod instance of demod.
4695* \return DRXStatus_t.
4696*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004697static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004698{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004699 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004700
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004701 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004702 /* QAM Equalizer Setup */
4703 /* Equalizer */
4704 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4708 if (status < 0)
4709 goto error;
4710 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4711 if (status < 0)
4712 goto error;
4713 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4717 if (status < 0)
4718 goto error;
4719 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4720 if (status < 0)
4721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 /* Decision Feedback Equalizer */
4724 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4740 if (status < 0)
4741 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004742
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004743 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4744 if (status < 0)
4745 goto error;
4746 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4747 if (status < 0)
4748 goto error;
4749 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4750 if (status < 0)
4751 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004752
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004753 /* QAM Slicer Settings */
4754 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4755 if (status < 0)
4756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004757
4758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004759 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004761 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4783 if (status < 0)
4784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004786 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4805 if (status < 0)
4806 goto error;
4807 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4808 if (status < 0)
4809 goto error;
4810 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4811 if (status < 0)
4812 goto error;
4813 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4814 if (status < 0)
4815 goto error;
4816 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4817 if (status < 0)
4818 goto error;
4819 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4820 if (status < 0)
4821 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004822
4823
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004824 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004825
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004826 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4842 if (status < 0)
4843 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004844
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004845 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4846 if (status < 0)
4847 goto error;
4848 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4849 if (status < 0)
4850 goto error;
4851 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4852 if (status < 0)
4853 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004854
4855
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004856 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004857
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004858 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4859 if (status < 0)
4860 goto error;
4861 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4877error:
4878 if (status < 0)
4879 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004880
Oliver Endrissebc7de22011-07-03 13:49:44 -03004881 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004882}
4883
4884/*============================================================================*/
4885
4886/**
4887* \brief QAM128 specific setup
4888* \param demod: instance of demod.
4889* \return DRXStatus_t.
4890*/
4891static int SetQAM128(struct drxk_state *state)
4892{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004893 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004894
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004895 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004896 /* QAM Equalizer Setup */
4897 /* Equalizer */
4898 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4899 if (status < 0)
4900 goto error;
4901 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4902 if (status < 0)
4903 goto error;
4904 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4905 if (status < 0)
4906 goto error;
4907 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4908 if (status < 0)
4909 goto error;
4910 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4911 if (status < 0)
4912 goto error;
4913 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4914 if (status < 0)
4915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 /* Decision Feedback Equalizer */
4918 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4919 if (status < 0)
4920 goto error;
4921 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4922 if (status < 0)
4923 goto error;
4924 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4925 if (status < 0)
4926 goto error;
4927 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4928 if (status < 0)
4929 goto error;
4930 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4934 if (status < 0)
4935 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004937 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4944 if (status < 0)
4945 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004946
4947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004948 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004950 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4951 if (status < 0)
4952 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004953
4954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004955 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004956
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004957 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4979 if (status < 0)
4980 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004981
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004982 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5001 if (status < 0)
5002 goto error;
5003 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5004 if (status < 0)
5005 goto error;
5006 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
5007 if (status < 0)
5008 goto error;
5009 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5010 if (status < 0)
5011 goto error;
5012 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5013 if (status < 0)
5014 goto error;
5015 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
5016 if (status < 0)
5017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005018
5019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005020 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005021
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005022 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5023 if (status < 0)
5024 goto error;
5025 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5026 if (status < 0)
5027 goto error;
5028 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5029 if (status < 0)
5030 goto error;
5031 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5032 if (status < 0)
5033 goto error;
5034 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5035 if (status < 0)
5036 goto error;
5037 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5038 if (status < 0)
5039 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005040
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005041 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5042 if (status < 0)
5043 goto error;
5044 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5045 if (status < 0)
5046 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005048 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5049 if (status < 0)
5050 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005051
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005052 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005054 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5073error:
5074 if (status < 0)
5075 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005076
Oliver Endrissebc7de22011-07-03 13:49:44 -03005077 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005078}
5079
5080/*============================================================================*/
5081
5082/**
5083* \brief QAM256 specific setup
5084* \param demod: instance of demod.
5085* \return DRXStatus_t.
5086*/
5087static int SetQAM256(struct drxk_state *state)
5088{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005089 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005090
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005091 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005092 /* QAM Equalizer Setup */
5093 /* Equalizer */
5094 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5098 if (status < 0)
5099 goto error;
5100 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5101 if (status < 0)
5102 goto error;
5103 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5104 if (status < 0)
5105 goto error;
5106 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5107 if (status < 0)
5108 goto error;
5109 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5110 if (status < 0)
5111 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 /* Decision Feedback Equalizer */
5114 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5115 if (status < 0)
5116 goto error;
5117 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5130 if (status < 0)
5131 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005132
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005133 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5137 if (status < 0)
5138 goto error;
5139 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5140 if (status < 0)
5141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005143 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005145 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5146 if (status < 0)
5147 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005148
5149
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005150 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005151
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005152 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5174 if (status < 0)
5175 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005176
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005177 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5178 if (status < 0)
5179 goto error;
5180 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5196 if (status < 0)
5197 goto error;
5198 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5199 if (status < 0)
5200 goto error;
5201 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5202 if (status < 0)
5203 goto error;
5204 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5205 if (status < 0)
5206 goto error;
5207 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5208 if (status < 0)
5209 goto error;
5210 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5211 if (status < 0)
5212 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005213
5214
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005215 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005216
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005217 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5233 if (status < 0)
5234 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005235
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005236 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5237 if (status < 0)
5238 goto error;
5239 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5240 if (status < 0)
5241 goto error;
5242 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5243 if (status < 0)
5244 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245
5246
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005247 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005249 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5250 if (status < 0)
5251 goto error;
5252 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5253 if (status < 0)
5254 goto error;
5255 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5256 if (status < 0)
5257 goto error;
5258 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5259 if (status < 0)
5260 goto error;
5261 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5262 if (status < 0)
5263 goto error;
5264 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5265 if (status < 0)
5266 goto error;
5267 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5268error:
5269 if (status < 0)
5270 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005271 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005272}
5273
5274
5275/*============================================================================*/
5276/**
5277* \brief Reset QAM block.
5278* \param demod: instance of demod.
5279* \param channel: pointer to channel data.
5280* \return DRXStatus_t.
5281*/
5282static int QAMResetQAM(struct drxk_state *state)
5283{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005284 int status;
5285 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005286
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005287 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005288 /* Stop QAM comstate->m_exec */
5289 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5290 if (status < 0)
5291 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005292
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005293 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5294error:
5295 if (status < 0)
5296 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005297 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005298}
5299
5300/*============================================================================*/
5301
5302/**
5303* \brief Set QAM symbolrate.
5304* \param demod: instance of demod.
5305* \param channel: pointer to channel data.
5306* \return DRXStatus_t.
5307*/
5308static int QAMSetSymbolrate(struct drxk_state *state)
5309{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005310 u32 adcFrequency = 0;
5311 u32 symbFreq = 0;
5312 u32 iqmRcRate = 0;
5313 u16 ratesel = 0;
5314 u32 lcSymbRate = 0;
5315 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005316
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005317 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005318 /* Select & calculate correct IQM rate */
5319 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5320 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005321 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5322 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005323 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005324 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005325 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005326 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005327 ratesel = 1;
5328 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5329 if (status < 0)
5330 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005332 /*
5333 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5334 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005335 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005336 if (symbFreq == 0) {
5337 /* Divide by zero */
5338 status = -EINVAL;
5339 goto error;
5340 }
5341 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5342 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5343 (1 << 23);
5344 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5345 if (status < 0)
5346 goto error;
5347 state->m_iqmRcRate = iqmRcRate;
5348 /*
5349 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5350 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005351 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005352 if (adcFrequency == 0) {
5353 /* Divide by zero */
5354 status = -EINVAL;
5355 goto error;
5356 }
5357 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5358 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5359 16);
5360 if (lcSymbRate > 511)
5361 lcSymbRate = 511;
5362 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005364error:
5365 if (status < 0)
5366 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005367 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005368}
5369
5370/*============================================================================*/
5371
5372/**
5373* \brief Get QAM lock status.
5374* \param demod: instance of demod.
5375* \param channel: pointer to channel data.
5376* \return DRXStatus_t.
5377*/
5378
5379static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5380{
5381 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005382 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005383
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005384 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005385 *pLockStatus = NOT_LOCKED;
5386 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005387 SCU_RAM_COMMAND_STANDARD_QAM |
5388 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5389 Result);
5390 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005391 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005392
5393 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005394 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005395 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005396 /* 0x4000 DEMOD LOCKED */
5397 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005398 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005399 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5400 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005401 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005402 /* 0xC000 NEVER LOCKED */
5403 /* (system will never be able to lock to the signal) */
5404 /* TODO: check this, intermediate & standard specific lock states are not
5405 taken into account here */
5406 *pLockStatus = NEVER_LOCK;
5407 }
5408 return status;
5409}
5410
5411#define QAM_MIRROR__M 0x03
5412#define QAM_MIRROR_NORMAL 0x00
5413#define QAM_MIRRORED 0x01
5414#define QAM_MIRROR_AUTO_ON 0x02
5415#define QAM_LOCKRANGE__M 0x10
5416#define QAM_LOCKRANGE_NORMAL 0x10
5417
Oliver Endrissebc7de22011-07-03 13:49:44 -03005418static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5419 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005420{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005421 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005422 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5423 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005424
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005425 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005426 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005427 * STEP 1: reset demodulator
5428 * resets FEC DI and FEC RS
5429 * resets QAM block
5430 * resets SCU variables
5431 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005432 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005433 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005434 goto error;
5435 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5436 if (status < 0)
5437 goto error;
5438 status = QAMResetQAM(state);
5439 if (status < 0)
5440 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005441
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005442 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005443 * STEP 2: configure demodulator
5444 * -set params; resets IQM,QAM,FEC HW; initializes some
5445 * SCU variables
5446 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005447 status = QAMSetSymbolrate(state);
5448 if (status < 0)
5449 goto error;
5450
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005451 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005452 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005453 case QAM_256:
5454 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5455 break;
5456 case QAM_AUTO:
5457 case QAM_64:
5458 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5459 break;
5460 case QAM_16:
5461 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5462 break;
5463 case QAM_32:
5464 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5465 break;
5466 case QAM_128:
5467 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5468 break;
5469 default:
5470 status = -EINVAL;
5471 break;
5472 }
5473 if (status < 0)
5474 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005475 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005476 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005477 if (state->m_OperationMode == OM_QAM_ITU_C)
5478 setParamParameters[2] = QAM_TOP_ANNEX_C;
5479 else
5480 setParamParameters[2] = QAM_TOP_ANNEX_A;
5481 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5482 /* Env parameters */
5483 /* check for LOCKRANGE Extented */
5484 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005485
5486 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005487 if (status < 0) {
5488 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005489 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005490 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005491 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005492 setParamParameters[0] = QAM_TOP_ANNEX_A;
5493 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5494 if (status < 0)
5495 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005496
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005497 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005498 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005499 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5500 }
5501 if (status < 0)
5502 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005503
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005504 /*
5505 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005506 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005507 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005508#if 0
5509 status = SetFrequency(channel, tunerFreqOffset));
5510 if (status < 0)
5511 goto error;
5512#endif
5513 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5514 if (status < 0)
5515 goto error;
5516
5517 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005518 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005519 if (status < 0)
5520 goto error;
5521
5522 /* Reset default values */
5523 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5524 if (status < 0)
5525 goto error;
5526 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5527 if (status < 0)
5528 goto error;
5529
5530 /* Reset default LC values */
5531 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_MODE__A, 7);
5541 if (status < 0)
5542 goto error;
5543
5544 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5545 if (status < 0)
5546 goto error;
5547 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5548 if (status < 0)
5549 goto error;
5550 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5551 if (status < 0)
5552 goto error;
5553 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5554 if (status < 0)
5555 goto error;
5556 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5557 if (status < 0)
5558 goto error;
5559 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5560 if (status < 0)
5561 goto error;
5562 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5563 if (status < 0)
5564 goto error;
5565 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5566 if (status < 0)
5567 goto error;
5568 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5569 if (status < 0)
5570 goto error;
5571 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5572 if (status < 0)
5573 goto error;
5574 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5575 if (status < 0)
5576 goto error;
5577 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5578 if (status < 0)
5579 goto error;
5580 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5581 if (status < 0)
5582 goto error;
5583 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5584 if (status < 0)
5585 goto error;
5586 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5587 if (status < 0)
5588 goto error;
5589
5590 /* Mirroring, QAM-block starting point not inverted */
5591 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5592 if (status < 0)
5593 goto error;
5594
5595 /* Halt SCU to enable safe non-atomic accesses */
5596 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5597 if (status < 0)
5598 goto error;
5599
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005600 /* STEP 4: modulation specific setup */
5601 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005602 case QAM_16:
5603 status = SetQAM16(state);
5604 break;
5605 case QAM_32:
5606 status = SetQAM32(state);
5607 break;
5608 case QAM_AUTO:
5609 case QAM_64:
5610 status = SetQAM64(state);
5611 break;
5612 case QAM_128:
5613 status = SetQAM128(state);
5614 break;
5615 case QAM_256:
5616 status = SetQAM256(state);
5617 break;
5618 default:
5619 status = -EINVAL;
5620 break;
5621 }
5622 if (status < 0)
5623 goto error;
5624
5625 /* Activate SCU to enable SCU commands */
5626 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5627 if (status < 0)
5628 goto error;
5629
5630 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005631 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005632 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5633 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5634 if (status < 0)
5635 goto error;
5636
5637 /* Start processes */
5638 status = MPEGTSStart(state);
5639 if (status < 0)
5640 goto error;
5641 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5642 if (status < 0)
5643 goto error;
5644 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5645 if (status < 0)
5646 goto error;
5647 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5648 if (status < 0)
5649 goto error;
5650
5651 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5652 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5653 if (status < 0)
5654 goto error;
5655
5656 /* update global DRXK data container */
5657/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5658
5659error:
5660 if (status < 0)
5661 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005662 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005663}
5664
Oliver Endrissebc7de22011-07-03 13:49:44 -03005665static int SetQAMStandard(struct drxk_state *state,
5666 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005667{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005668 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005669#ifdef DRXK_QAM_TAPS
5670#define DRXK_QAMA_TAPS_SELECT
5671#include "drxk_filters.h"
5672#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005673#endif
5674
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005675 dprintk(1, "\n");
5676
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005677 /* added antenna switch */
5678 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005679
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005680 /* Ensure correct power-up mode */
5681 status = PowerUpQAM(state);
5682 if (status < 0)
5683 goto error;
5684 /* Reset QAM block */
5685 status = QAMResetQAM(state);
5686 if (status < 0)
5687 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005689 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005691 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5695 if (status < 0)
5696 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005697
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005698 /* Upload IQM Channel Filter settings by
5699 boot loader from ROM table */
5700 switch (oMode) {
5701 case OM_QAM_ITU_A:
5702 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5703 break;
5704 case OM_QAM_ITU_C:
5705 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 -03005706 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005707 goto error;
5708 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5709 break;
5710 default:
5711 status = -EINVAL;
5712 }
5713 if (status < 0)
5714 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005715
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005716 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5717 if (status < 0)
5718 goto error;
5719 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5720 if (status < 0)
5721 goto error;
5722 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5723 if (status < 0)
5724 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005726 status = write16(state, IQM_RC_STRETCH__A, 21);
5727 if (status < 0)
5728 goto error;
5729 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5730 if (status < 0)
5731 goto error;
5732 status = write16(state, IQM_AF_CLP_TH__A, 448);
5733 if (status < 0)
5734 goto error;
5735 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5736 if (status < 0)
5737 goto error;
5738 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5739 if (status < 0)
5740 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005741
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005742 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5743 if (status < 0)
5744 goto error;
5745 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5746 if (status < 0)
5747 goto error;
5748 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5749 if (status < 0)
5750 goto error;
5751 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5752 if (status < 0)
5753 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005755 /* IQM Impulse Noise Processing Unit */
5756 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5757 if (status < 0)
5758 goto error;
5759 status = write16(state, IQM_CF_DATATH__A, 1000);
5760 if (status < 0)
5761 goto error;
5762 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5763 if (status < 0)
5764 goto error;
5765 status = write16(state, IQM_CF_DET_LCT__A, 0);
5766 if (status < 0)
5767 goto error;
5768 status = write16(state, IQM_CF_WND_LEN__A, 1);
5769 if (status < 0)
5770 goto error;
5771 status = write16(state, IQM_CF_PKDTH__A, 1);
5772 if (status < 0)
5773 goto error;
5774 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5775 if (status < 0)
5776 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005777
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005778 /* turn on IQMAF. Must be done before setAgc**() */
5779 status = SetIqmAf(state, true);
5780 if (status < 0)
5781 goto error;
5782 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5783 if (status < 0)
5784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005785
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005786 /* IQM will not be reset from here, sync ADC and update/init AGC */
5787 status = ADCSynchronization(state);
5788 if (status < 0)
5789 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005790
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005791 /* Set the FSM step period */
5792 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5793 if (status < 0)
5794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005796 /* Halt SCU to enable safe non-atomic accesses */
5797 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5798 if (status < 0)
5799 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005800
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005801 /* No more resets of the IQM, current standard correctly set =>
5802 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005803
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005804 status = InitAGC(state, true);
5805 if (status < 0)
5806 goto error;
5807 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5808 if (status < 0)
5809 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005810
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005811 /* Configure AGC's */
5812 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5813 if (status < 0)
5814 goto error;
5815 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5816 if (status < 0)
5817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005819 /* Activate SCU to enable SCU commands */
5820 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5821error:
5822 if (status < 0)
5823 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005824 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005825}
5826
5827static int WriteGPIO(struct drxk_state *state)
5828{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005829 int status;
5830 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005831
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005832 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005833 /* stop lock indicator process */
5834 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5835 if (status < 0)
5836 goto error;
5837
5838 /* Write magic word to enable pdr reg write */
5839 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5840 if (status < 0)
5841 goto error;
5842
5843 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005844 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5845 /* write to io pad configuration register - output mode */
5846 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5847 if (status < 0)
5848 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005849
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005850 /* use corresponding bit in io data output registar */
5851 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5852 if (status < 0)
5853 goto error;
5854 if ((state->m_GPIO & 0x0001) == 0)
5855 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5856 else
5857 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5858 /* write back to io data output register */
5859 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5860 if (status < 0)
5861 goto error;
5862 }
5863 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5864 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005865 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005866 if (status < 0)
5867 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005868
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005869 /* use corresponding bit in io data output registar */
5870 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5871 if (status < 0)
5872 goto error;
5873 if ((state->m_GPIO & 0x0002) == 0)
5874 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5875 else
5876 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5877 /* write back to io data output register */
5878 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5879 if (status < 0)
5880 goto error;
5881 }
5882 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5883 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005884 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005885 if (status < 0)
5886 goto error;
5887
5888 /* use corresponding bit in io data output registar */
5889 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5890 if (status < 0)
5891 goto error;
5892 if ((state->m_GPIO & 0x0004) == 0)
5893 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5894 else
5895 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5896 /* write back to io data output register */
5897 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5898 if (status < 0)
5899 goto error;
5900 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005901 }
5902 /* Write magic word to disable pdr reg write */
5903 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5904error:
5905 if (status < 0)
5906 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005907 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005908}
5909
5910static int SwitchAntennaToQAM(struct drxk_state *state)
5911{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005912 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005913 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005914
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005915 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005916
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005917 if (!state->antenna_gpio)
5918 return 0;
5919
5920 gpio_state = state->m_GPIO & state->antenna_gpio;
5921
5922 if (state->antenna_dvbt ^ gpio_state) {
5923 /* Antenna is on DVB-T mode. Switch */
5924 if (state->antenna_dvbt)
5925 state->m_GPIO &= ~state->antenna_gpio;
5926 else
5927 state->m_GPIO |= state->antenna_gpio;
5928 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005929 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005930 if (status < 0)
5931 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005932 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005933}
5934
5935static int SwitchAntennaToDVBT(struct drxk_state *state)
5936{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005937 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005938 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005939
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005940 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005941
5942 if (!state->antenna_gpio)
5943 return 0;
5944
5945 gpio_state = state->m_GPIO & state->antenna_gpio;
5946
5947 if (!(state->antenna_dvbt ^ gpio_state)) {
5948 /* Antenna is on DVB-C mode. Switch */
5949 if (state->antenna_dvbt)
5950 state->m_GPIO |= state->antenna_gpio;
5951 else
5952 state->m_GPIO &= ~state->antenna_gpio;
5953 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005954 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005955 if (status < 0)
5956 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005957 return status;
5958}
5959
5960
5961static int PowerDownDevice(struct drxk_state *state)
5962{
5963 /* Power down to requested mode */
5964 /* Backup some register settings */
5965 /* Set pins with possible pull-ups connected to them in input mode */
5966 /* Analog power down */
5967 /* ADC power down */
5968 /* Power down device */
5969 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005970
5971 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005972 if (state->m_bPDownOpenBridge) {
5973 /* Open I2C bridge before power down of DRXK */
5974 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005975 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005976 goto error;
5977 }
5978 /* driver 0.9.0 */
5979 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005980 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005981 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005982
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005983 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5984 if (status < 0)
5985 goto error;
5986 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5987 if (status < 0)
5988 goto error;
5989 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5990 status = HI_CfgCommand(state);
5991error:
5992 if (status < 0)
5993 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5994
5995 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005996}
5997
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005998static int init_drxk(struct drxk_state *state)
5999{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006000 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006001 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006002 u16 driverVersion;
6003
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006004 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006005 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006006 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006007 status = PowerUpDevice(state);
6008 if (status < 0)
6009 goto error;
6010 status = DRXX_Open(state);
6011 if (status < 0)
6012 goto error;
6013 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6014 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);
6015 if (status < 0)
6016 goto error;
6017 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6018 if (status < 0)
6019 goto error;
6020 /* TODO is this needed, if yes how much delay in worst case scenario */
6021 msleep(1);
6022 state->m_DRXK_A3_PATCH_CODE = true;
6023 status = GetDeviceCapabilities(state);
6024 if (status < 0)
6025 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006026
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006027 /* Bridge delay, uses oscilator clock */
6028 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6029 /* SDA brdige delay */
6030 state->m_HICfgBridgeDelay =
6031 (u16) ((state->m_oscClockFreq / 1000) *
6032 HI_I2C_BRIDGE_DELAY) / 1000;
6033 /* Clipping */
6034 if (state->m_HICfgBridgeDelay >
6035 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006036 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006037 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6038 }
6039 /* SCL bridge delay, same as SDA for now */
6040 state->m_HICfgBridgeDelay +=
6041 state->m_HICfgBridgeDelay <<
6042 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006043
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006044 status = InitHI(state);
6045 if (status < 0)
6046 goto error;
6047 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006048#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006049 if (!(state->m_DRXK_A1_ROM_CODE)
6050 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006052 {
6053 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6054 if (status < 0)
6055 goto error;
6056 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006057
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006058 /* disable MPEG port */
6059 status = MPEGTSDisable(state);
6060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 /* Stop AUD and SCU */
6064 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6065 if (status < 0)
6066 goto error;
6067 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6068 if (status < 0)
6069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006070
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006071 /* enable token-ring bus through OFDM block for possible ucode upload */
6072 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6073 if (status < 0)
6074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006076 /* include boot loader section */
6077 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6078 if (status < 0)
6079 goto error;
6080 status = BLChainCmd(state, 0, 6, 100);
6081 if (status < 0)
6082 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006083
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006084 if (state->fw) {
6085 status = DownloadMicrocode(state, state->fw->data,
6086 state->fw->size);
6087 if (status < 0)
6088 goto error;
6089 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006090
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006091 /* disable token-ring bus through OFDM block for possible ucode upload */
6092 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6093 if (status < 0)
6094 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006095
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006096 /* Run SCU for a little while to initialize microcode version numbers */
6097 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6098 if (status < 0)
6099 goto error;
6100 status = DRXX_Open(state);
6101 if (status < 0)
6102 goto error;
6103 /* added for test */
6104 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006105
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006106 powerMode = DRXK_POWER_DOWN_OFDM;
6107 status = CtrlPowerMode(state, &powerMode);
6108 if (status < 0)
6109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006111 /* Stamp driver version number in SCU data RAM in BCD code
6112 Done to enable field application engineers to retreive drxdriver version
6113 via I2C from SCU RAM.
6114 Not using SCU command interface for SCU register access since no
6115 microcode may be present.
6116 */
6117 driverVersion =
6118 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6119 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6120 ((DRXK_VERSION_MAJOR % 10) << 4) +
6121 (DRXK_VERSION_MINOR % 10);
6122 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6123 if (status < 0)
6124 goto error;
6125 driverVersion =
6126 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6127 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6128 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6129 (DRXK_VERSION_PATCH % 10);
6130 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6131 if (status < 0)
6132 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006134 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6135 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6136 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006137
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006138 /* Dirty fix of default values for ROM/PATCH microcode
6139 Dirty because this fix makes it impossible to setup suitable values
6140 before calling DRX_Open. This solution requires changes to RF AGC speed
6141 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006143 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006145 /* Reset driver debug flags to 0 */
6146 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6147 if (status < 0)
6148 goto error;
6149 /* driver 0.9.0 */
6150 /* Setup FEC OC:
6151 NOTE: No more full FEC resets allowed afterwards!! */
6152 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6153 if (status < 0)
6154 goto error;
6155 /* MPEGTS functions are still the same */
6156 status = MPEGTSDtoInit(state);
6157 if (status < 0)
6158 goto error;
6159 status = MPEGTSStop(state);
6160 if (status < 0)
6161 goto error;
6162 status = MPEGTSConfigurePolarity(state);
6163 if (status < 0)
6164 goto error;
6165 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6166 if (status < 0)
6167 goto error;
6168 /* added: configure GPIO */
6169 status = WriteGPIO(state);
6170 if (status < 0)
6171 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006173 state->m_DrxkState = DRXK_STOPPED;
6174
6175 if (state->m_bPowerDown) {
6176 status = PowerDownDevice(state);
6177 if (status < 0)
6178 goto error;
6179 state->m_DrxkState = DRXK_POWERED_DOWN;
6180 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006182
6183 /* Initialize the supported delivery systems */
6184 n = 0;
6185 if (state->m_hasDVBC) {
6186 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6187 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6188 strlcat(state->frontend.ops.info.name, " DVB-C",
6189 sizeof(state->frontend.ops.info.name));
6190 }
6191 if (state->m_hasDVBT) {
6192 state->frontend.ops.delsys[n++] = SYS_DVBT;
6193 strlcat(state->frontend.ops.info.name, " DVB-T",
6194 sizeof(state->frontend.ops.info.name));
6195 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006196 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006197 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006198error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006199 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006200 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006201 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006202 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006203 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006205 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006206}
6207
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006208static void load_firmware_cb(const struct firmware *fw,
6209 void *context)
6210{
6211 struct drxk_state *state = context;
6212
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006213 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006214 if (!fw) {
6215 printk(KERN_ERR
6216 "drxk: Could not load firmware file %s.\n",
6217 state->microcode_name);
6218 printk(KERN_INFO
6219 "drxk: Copy %s to your hotplug directory!\n",
6220 state->microcode_name);
6221 state->microcode_name = NULL;
6222
6223 /*
6224 * As firmware is now load asynchronous, it is not possible
6225 * anymore to fail at frontend attach. We might silently
6226 * return here, and hope that the driver won't crash.
6227 * We might also change all DVB callbacks to return -ENODEV
6228 * if the device is not initialized.
6229 * As the DRX-K devices have their own internal firmware,
6230 * let's just hope that it will match a firmware revision
6231 * compatible with this driver and proceed.
6232 */
6233 }
6234 state->fw = fw;
6235
6236 init_drxk(state);
6237}
6238
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006239static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006240{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006241 struct drxk_state *state = fe->demodulator_priv;
6242
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006243 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006244 if (state->fw)
6245 release_firmware(state->fw);
6246
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006247 kfree(state);
6248}
6249
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006250static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006251{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006252 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006253
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006254 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006255
6256 if (state->m_DrxkState == DRXK_NO_DEV)
6257 return -ENODEV;
6258 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6259 return 0;
6260
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006261 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262 return 0;
6263}
6264
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006266{
6267 struct drxk_state *state = fe->demodulator_priv;
6268
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006269 dprintk(1, "%s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006270
6271 if (state->m_DrxkState == DRXK_NO_DEV)
6272 return -ENODEV;
6273
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274 return ConfigureI2CBridge(state, enable ? true : false);
6275}
6276
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006277static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006278{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006279 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006280 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006281 struct drxk_state *state = fe->demodulator_priv;
6282 u32 IF;
6283
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006284 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006285
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006286 if (state->m_DrxkState == DRXK_NO_DEV)
6287 return -ENODEV;
6288
6289 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6290 return -EAGAIN;
6291
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006292 if (!fe->ops.tuner_ops.get_if_frequency) {
6293 printk(KERN_ERR
6294 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6295 return -EINVAL;
6296 }
6297
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006298 if (fe->ops.i2c_gate_ctrl)
6299 fe->ops.i2c_gate_ctrl(fe, 1);
6300 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006301 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006302 if (fe->ops.i2c_gate_ctrl)
6303 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006304
6305 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006306 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006307
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006308 if (old_delsys != delsys) {
6309 ShutDown(state);
6310 switch (delsys) {
6311 case SYS_DVBC_ANNEX_A:
6312 case SYS_DVBC_ANNEX_C:
6313 if (!state->m_hasDVBC)
6314 return -EINVAL;
6315 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6316 if (state->m_itut_annex_c)
6317 SetOperationMode(state, OM_QAM_ITU_C);
6318 else
6319 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006320 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006321 case SYS_DVBT:
6322 if (!state->m_hasDVBT)
6323 return -EINVAL;
6324 SetOperationMode(state, OM_DVBT);
6325 break;
6326 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006327 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006328 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006329 }
6330
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006331 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006332 Start(state, 0, IF);
6333
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006334 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006335
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006336 return 0;
6337}
6338
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006339static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6340{
6341 struct drxk_state *state = fe->demodulator_priv;
6342 u32 stat;
6343
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006344 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006345
6346 if (state->m_DrxkState == DRXK_NO_DEV)
6347 return -ENODEV;
6348 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6349 return -EAGAIN;
6350
Oliver Endrissebc7de22011-07-03 13:49:44 -03006351 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006352 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006353 if (stat == MPEG_LOCK)
6354 *status |= 0x1f;
6355 if (stat == FEC_LOCK)
6356 *status |= 0x0f;
6357 if (stat == DEMOD_LOCK)
6358 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006359 return 0;
6360}
6361
6362static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6363{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006364 struct drxk_state *state = fe->demodulator_priv;
6365
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006366 dprintk(1, "\n");
6367
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006368 if (state->m_DrxkState == DRXK_NO_DEV)
6369 return -ENODEV;
6370 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6371 return -EAGAIN;
6372
Oliver Endrissebc7de22011-07-03 13:49:44 -03006373 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006374 return 0;
6375}
6376
Oliver Endrissebc7de22011-07-03 13:49:44 -03006377static int drxk_read_signal_strength(struct dvb_frontend *fe,
6378 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006379{
6380 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006381 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006382
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006383 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006384
6385 if (state->m_DrxkState == DRXK_NO_DEV)
6386 return -ENODEV;
6387 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6388 return -EAGAIN;
6389
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006390 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006391 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006392 return 0;
6393}
6394
6395static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6396{
6397 struct drxk_state *state = fe->demodulator_priv;
6398 s32 snr2;
6399
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006400 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006401
6402 if (state->m_DrxkState == DRXK_NO_DEV)
6403 return -ENODEV;
6404 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6405 return -EAGAIN;
6406
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006407 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006408 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006409 return 0;
6410}
6411
6412static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6413{
6414 struct drxk_state *state = fe->demodulator_priv;
6415 u16 err;
6416
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 DVBTQAMGetAccPktErr(state, &err);
6425 *ucblocks = (u32) err;
6426 return 0;
6427}
6428
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006429static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006430 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006431{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006432 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006433 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006434
6435 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006436
6437 if (state->m_DrxkState == DRXK_NO_DEV)
6438 return -ENODEV;
6439 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6440 return -EAGAIN;
6441
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006442 switch (p->delivery_system) {
6443 case SYS_DVBC_ANNEX_A:
6444 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006445 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006446 sets->min_delay_ms = 3000;
6447 sets->max_drift = 0;
6448 sets->step_size = 0;
6449 return 0;
6450 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006451 return -EINVAL;
6452 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006453}
6454
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006455static struct dvb_frontend_ops drxk_ops = {
6456 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006457 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006458 .name = "DRXK",
6459 .frequency_min = 47000000,
6460 .frequency_max = 865000000,
6461 /* For DVB-C */
6462 .symbol_rate_min = 870000,
6463 .symbol_rate_max = 11700000,
6464 /* For DVB-T */
6465 .frequency_stepsize = 166667,
6466
6467 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6468 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6469 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6470 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6471 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6472 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6473 },
6474
6475 .release = drxk_release,
6476 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006477 .i2c_gate_ctrl = drxk_gate_ctrl,
6478
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006479 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006480 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006481
6482 .read_status = drxk_read_status,
6483 .read_ber = drxk_read_ber,
6484 .read_signal_strength = drxk_read_signal_strength,
6485 .read_snr = drxk_read_snr,
6486 .read_ucblocks = drxk_read_ucblocks,
6487};
6488
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006489struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006490 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006491{
6492 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006493 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006494 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006495
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006496 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006497 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006498 if (!state)
6499 return NULL;
6500
Oliver Endrissebc7de22011-07-03 13:49:44 -03006501 state->i2c = i2c;
6502 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006503 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006504 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006505 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006506 state->antenna_gpio = config->antenna_gpio;
6507 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006508 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006509 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006510
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006511 if (config->dynamic_clk) {
6512 state->m_DVBTStaticCLK = 0;
6513 state->m_DVBCStaticCLK = 0;
6514 } else {
6515 state->m_DVBTStaticCLK = 1;
6516 state->m_DVBCStaticCLK = 1;
6517 }
6518
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006519
6520 if (config->mpeg_out_clk_strength)
6521 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6522 else
6523 state->m_TSClockkStrength = 0x06;
6524
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006525 if (config->parallel_ts)
6526 state->m_enableParallel = true;
6527 else
6528 state->m_enableParallel = false;
6529
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006530 /* NOTE: as more UIO bits will be used, add them to the mask */
6531 state->UIO_mask = config->antenna_gpio;
6532
6533 /* Default gpio to DVB-C */
6534 if (!state->antenna_dvbt && state->antenna_gpio)
6535 state->m_GPIO |= state->antenna_gpio;
6536 else
6537 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006538
6539 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006540
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006541 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6542 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006543
6544 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006545
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006546 /* Load firmware and initialize DRX-K */
6547 if (state->microcode_name) {
6548 status = request_firmware_nowait(THIS_MODULE, 1,
6549 state->microcode_name,
6550 state->i2c->dev.parent,
6551 GFP_KERNEL,
6552 state, load_firmware_cb);
6553 if (status < 0) {
6554 printk(KERN_ERR
6555 "drxk: failed to request a firmware\n");
6556 return NULL;
6557 }
6558 } else if (init_drxk(state) < 0)
6559 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006560
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006561 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006562 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006563
6564error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006565 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006566 kfree(state);
6567 return NULL;
6568}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006569EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006570
6571MODULE_DESCRIPTION("DRX-K driver");
6572MODULE_AUTHOR("Ralph Metzler");
6573MODULE_LICENSE("GPL");