blob: 41b637534ed4fba5d6c486c2ddad420573119fb5 [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"
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -030037#include "dvb_math.h"
Ralph Metzler43dd07f2011-07-03 13:42:18 -030038
39static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
40static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030041static int SetDVBTStandard(struct drxk_state *state,
42 enum OperationMode oMode);
43static int SetQAMStandard(struct drxk_state *state,
44 enum OperationMode oMode);
45static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030046 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030047static int SetDVBTStandard(struct drxk_state *state,
48 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030049static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030050static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
51 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030052static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
54static int SwitchAntennaToQAM(struct drxk_state *state);
55static int SwitchAntennaToDVBT(struct drxk_state *state);
56
57static bool IsDVBT(struct drxk_state *state)
58{
59 return state->m_OperationMode == OM_DVBT;
60}
61
62static bool IsQAM(struct drxk_state *state)
63{
64 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030065 state->m_OperationMode == OM_QAM_ITU_B ||
66 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030067}
68
Ralph Metzler43dd07f2011-07-03 13:42:18 -030069#define NOA1ROM 0
70
Ralph Metzler43dd07f2011-07-03 13:42:18 -030071#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
72#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
73
74#define DEFAULT_MER_83 165
75#define DEFAULT_MER_93 250
76
77#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
78#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
79#endif
80
81#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
82#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
83#endif
84
Ralph Metzler43dd07f2011-07-03 13:42:18 -030085#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
86#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
87
88#ifndef DRXK_KI_RAGC_ATV
89#define DRXK_KI_RAGC_ATV 4
90#endif
91#ifndef DRXK_KI_IAGC_ATV
92#define DRXK_KI_IAGC_ATV 6
93#endif
94#ifndef DRXK_KI_DAGC_ATV
95#define DRXK_KI_DAGC_ATV 7
96#endif
97
98#ifndef DRXK_KI_RAGC_QAM
99#define DRXK_KI_RAGC_QAM 3
100#endif
101#ifndef DRXK_KI_IAGC_QAM
102#define DRXK_KI_IAGC_QAM 4
103#endif
104#ifndef DRXK_KI_DAGC_QAM
105#define DRXK_KI_DAGC_QAM 7
106#endif
107#ifndef DRXK_KI_RAGC_DVBT
108#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
109#endif
110#ifndef DRXK_KI_IAGC_DVBT
111#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
112#endif
113#ifndef DRXK_KI_DAGC_DVBT
114#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
115#endif
116
117#ifndef DRXK_AGC_DAC_OFFSET
118#define DRXK_AGC_DAC_OFFSET (0x800)
119#endif
120
121#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
122#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
123#endif
124
125#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
126#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
127#endif
128
129#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
130#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
131#endif
132
133#ifndef DRXK_QAM_SYMBOLRATE_MAX
134#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
135#endif
136
137#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
138#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
139#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
140#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
141#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
142#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
143#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
144#define DRXK_BL_ROM_OFFSET_UCODE 0
145
146#define DRXK_BLC_TIMEOUT 100
147
148#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
149#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
150
151#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
152
153#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
154#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
155#endif
156
157#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
158#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
159#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
160#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
161#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
162
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300163static unsigned int debug;
164module_param(debug, int, 0644);
165MODULE_PARM_DESC(debug, "enable debug messages");
166
167#define dprintk(level, fmt, arg...) do { \
168if (debug >= level) \
169 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
170} while (0)
171
172
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300173static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300174{
175 u64 tmp64;
176
Oliver Endrissebc7de22011-07-03 13:49:44 -0300177 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300178 do_div(tmp64, c);
179
180 return (u32) tmp64;
181}
182
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200183static inline u32 Frac28a(u32 a, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300184{
185 int i = 0;
186 u32 Q1 = 0;
187 u32 R0 = 0;
188
Oliver Endrissebc7de22011-07-03 13:49:44 -0300189 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
190 Q1 = a / c; /* integer part, only the 4 least significant bits
191 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300192
193 /* division using radix 16, 7 nibbles in the result */
194 for (i = 0; i < 7; i++) {
195 Q1 = (Q1 << 4) | (R0 / c);
196 R0 = (R0 % c) << 4;
197 }
198 /* rounding */
199 if ((R0 >> 3) >= c)
200 Q1++;
201
202 return Q1;
203}
204
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300205static inline u32 log10times100(u32 value)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300206{
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300207 return (100L * intlog10(value)) >> 24;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300208}
209
210/****************************************************************************/
211/* I2C **********************************************************************/
212/****************************************************************************/
213
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300214static int drxk_i2c_lock(struct drxk_state *state)
215{
216 i2c_lock_adapter(state->i2c);
217 state->drxk_i2c_exclusive_lock = true;
218
219 return 0;
220}
221
222static void drxk_i2c_unlock(struct drxk_state *state)
223{
224 if (!state->drxk_i2c_exclusive_lock)
225 return;
226
227 i2c_unlock_adapter(state->i2c);
228 state->drxk_i2c_exclusive_lock = false;
229}
230
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300231static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
232 unsigned len)
233{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300234 if (state->drxk_i2c_exclusive_lock)
235 return __i2c_transfer(state->i2c, msgs, len);
236 else
237 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300238}
239
240static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300241{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300242 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
243 .buf = val, .len = 1}
244 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300245
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300246 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300247}
248
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300249static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300250{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300251 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300252 struct i2c_msg msg = {
253 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300254
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300255 dprintk(3, ":");
256 if (debug > 2) {
257 int i;
258 for (i = 0; i < len; i++)
259 printk(KERN_CONT " %02x", data[i]);
260 printk(KERN_CONT "\n");
261 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300262 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300263 if (status >= 0 && status != 1)
264 status = -EIO;
265
266 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300267 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300268
269 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300270}
271
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300272static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300273 u8 adr, u8 *msg, int len, u8 *answ, int alen)
274{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300275 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300276 struct i2c_msg msgs[2] = {
277 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300278 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300279 {.addr = adr, .flags = I2C_M_RD,
280 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300282
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300283 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300284 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300285 if (debug > 2)
286 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300287 if (status >= 0)
288 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300289
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300290 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300291 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300292 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300293 if (debug > 2) {
294 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300295 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300296 for (i = 0; i < len; i++)
297 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300298 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300299 for (i = 0; i < alen; i++)
300 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300301 printk(KERN_CONT "\n");
302 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 return 0;
304}
305
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300306static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300307{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300308 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300310
311 if (state->single_master)
312 flags |= 0xC0;
313
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300314 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
315 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
316 mm1[1] = ((reg >> 16) & 0xFF);
317 mm1[2] = ((reg >> 24) & 0xFF) | flags;
318 mm1[3] = ((reg >> 7) & 0xFF);
319 len = 4;
320 } else {
321 mm1[0] = ((reg << 1) & 0xFF);
322 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
323 len = 2;
324 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300325 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300326 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 if (status < 0)
328 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300329 if (data)
330 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300332 return 0;
333}
334
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300335static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300337 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338}
339
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300340static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300341{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300342 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300343 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300344
345 if (state->single_master)
346 flags |= 0xC0;
347
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300348 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
349 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
350 mm1[1] = ((reg >> 16) & 0xFF);
351 mm1[2] = ((reg >> 24) & 0xFF) | flags;
352 mm1[3] = ((reg >> 7) & 0xFF);
353 len = 4;
354 } else {
355 mm1[0] = ((reg << 1) & 0xFF);
356 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
357 len = 2;
358 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300359 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300360 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300361 if (status < 0)
362 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 if (data)
364 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300365 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300366
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300367 return 0;
368}
369
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300370static int read32(struct drxk_state *state, u32 reg, u32 *data)
371{
372 return read32_flags(state, reg, data, 0);
373}
374
375static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300376{
377 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300378
379 if (state->single_master)
380 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300381 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
382 mm[0] = (((reg << 1) & 0xFF) | 0x01);
383 mm[1] = ((reg >> 16) & 0xFF);
384 mm[2] = ((reg >> 24) & 0xFF) | flags;
385 mm[3] = ((reg >> 7) & 0xFF);
386 len = 4;
387 } else {
388 mm[0] = ((reg << 1) & 0xFF);
389 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
390 len = 2;
391 }
392 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300393 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300394
395 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300396 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300397}
398
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300399static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300400{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300401 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300402}
403
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300404static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405{
406 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300407
408 if (state->single_master)
409 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300410 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
411 mm[0] = (((reg << 1) & 0xFF) | 0x01);
412 mm[1] = ((reg >> 16) & 0xFF);
413 mm[2] = ((reg >> 24) & 0xFF) | flags;
414 mm[3] = ((reg >> 7) & 0xFF);
415 len = 4;
416 } else {
417 mm[0] = ((reg << 1) & 0xFF);
418 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
419 len = 2;
420 }
421 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300422 mm[len + 1] = (data >> 8) & 0xff;
423 mm[len + 2] = (data >> 16) & 0xff;
424 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300425 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300426
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300427 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300428}
429
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300430static int write32(struct drxk_state *state, u32 reg, u32 data)
431{
432 return write32_flags(state, reg, data, 0);
433}
434
435static int write_block(struct drxk_state *state, u32 Address,
436 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300437{
438 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300439 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300440
441 if (state->single_master)
442 Flags |= 0xC0;
443
Oliver Endrissebc7de22011-07-03 13:49:44 -0300444 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300445 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300446 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300447 u8 *AdrBuf = &state->Chunk[0];
448 u32 AdrLength = 0;
449
Oliver Endrissebc7de22011-07-03 13:49:44 -0300450 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
451 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
452 AdrBuf[1] = ((Address >> 16) & 0xFF);
453 AdrBuf[2] = ((Address >> 24) & 0xFF);
454 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300455 AdrBuf[2] |= Flags;
456 AdrLength = 4;
457 if (Chunk == state->m_ChunkSize)
458 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300459 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300460 AdrBuf[0] = ((Address << 1) & 0xFF);
461 AdrBuf[1] = (((Address >> 16) & 0x0F) |
462 ((Address >> 18) & 0xF0));
463 AdrLength = 2;
464 }
465 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300466 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
467 if (debug > 1) {
468 int i;
469 if (pBlock)
470 for (i = 0; i < Chunk; i++)
471 printk(KERN_CONT " %02x", pBlock[i]);
472 printk(KERN_CONT "\n");
473 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300474 status = i2c_write(state, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300475 &state->Chunk[0], Chunk + AdrLength);
476 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300477 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
478 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479 break;
480 }
481 pBlock += Chunk;
482 Address += (Chunk >> 1);
483 BlkSize -= Chunk;
484 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300485 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300486}
487
488#ifndef DRXK_MAX_RETRIES_POWERUP
489#define DRXK_MAX_RETRIES_POWERUP 20
490#endif
491
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200492static int PowerUpDevice(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300493{
494 int status;
495 u8 data = 0;
496 u16 retryCount = 0;
497
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300498 dprintk(1, "\n");
499
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300500 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300501 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300502 do {
503 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300504 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300506 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300507 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300508 if (status < 0)
509 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300510 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300511 &data);
512 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300513 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300514 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
515 goto error;
516 }
517
518 /* Make sure all clk domains are active */
519 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
520 if (status < 0)
521 goto error;
522 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
523 if (status < 0)
524 goto error;
525 /* Enable pll lock tests */
526 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
527 if (status < 0)
528 goto error;
529
530 state->m_currentPowerMode = DRX_POWER_UP;
531
532error:
533 if (status < 0)
534 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
535
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300536 return status;
537}
538
539
540static int init_state(struct drxk_state *state)
541{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300542 /*
543 * FIXME: most (all?) of the values bellow should be moved into
544 * struct drxk_config, as they are probably board-specific
545 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300546 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
547 u32 ulVSBIfAgcOutputLevel = 0;
548 u32 ulVSBIfAgcMinLevel = 0;
549 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
550 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300551
Oliver Endrissebc7de22011-07-03 13:49:44 -0300552 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
553 u32 ulVSBRfAgcOutputLevel = 0;
554 u32 ulVSBRfAgcMinLevel = 0;
555 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
556 u32 ulVSBRfAgcSpeed = 3;
557 u32 ulVSBRfAgcTop = 9500;
558 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300559
Oliver Endrissebc7de22011-07-03 13:49:44 -0300560 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
561 u32 ulATVIfAgcOutputLevel = 0;
562 u32 ulATVIfAgcMinLevel = 0;
563 u32 ulATVIfAgcMaxLevel = 0;
564 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565
Oliver Endrissebc7de22011-07-03 13:49:44 -0300566 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
567 u32 ulATVRfAgcOutputLevel = 0;
568 u32 ulATVRfAgcMinLevel = 0;
569 u32 ulATVRfAgcMaxLevel = 0;
570 u32 ulATVRfAgcTop = 9500;
571 u32 ulATVRfAgcCutOffCurrent = 4000;
572 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300573
574 u32 ulQual83 = DEFAULT_MER_83;
575 u32 ulQual93 = DEFAULT_MER_93;
576
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
578 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
579
580 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
581 /* io_pad_cfg_mode output mode is drive always */
582 /* io_pad_cfg_drive is set to power 2 (23 mA) */
583 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300584 u32 ulInvertTSClock = 0;
585 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300586 u32 ulDVBTBitrate = 50000000;
587 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
588
589 u32 ulInsertRSByte = 0;
590
591 u32 ulRfMirror = 1;
592 u32 ulPowerDown = 0;
593
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300594 dprintk(1, "\n");
595
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300596 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300597 state->m_hasDVBT = false;
598 state->m_hasDVBC = false;
599 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300600 state->m_hasOOB = false;
601 state->m_hasAudio = false;
602
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300603 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200604 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300605
606 state->m_oscClockFreq = 0;
607 state->m_smartAntInverted = false;
608 state->m_bPDownOpenBridge = false;
609
610 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300611 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300612 /* Timing div, 250ns/Psys */
613 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
614 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
615 HI_I2C_DELAY) / 1000;
616 /* Clipping */
617 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
618 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
619 state->m_HICfgWakeUpKey = (state->demod_address << 1);
620 /* port/bridge/power down ctrl */
621 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
622
623 state->m_bPowerDown = (ulPowerDown != 0);
624
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300625 state->m_DRXK_A3_PATCH_CODE = false;
626
627 /* Init AGC and PGA parameters */
628 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300629 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
630 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
631 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
632 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
633 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300634 state->m_vsbPgaCfg = 140;
635
636 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300637 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
638 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
639 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
640 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
641 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
642 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
643 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
644 state->m_vsbPreSawCfg.reference = 0x07;
645 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300646
647 state->m_Quality83percent = DEFAULT_MER_83;
648 state->m_Quality93percent = DEFAULT_MER_93;
649 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
650 state->m_Quality83percent = ulQual83;
651 state->m_Quality93percent = ulQual93;
652 }
653
654 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300655 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
656 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
657 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
658 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
659 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300660
661 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300662 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
663 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
664 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
665 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
666 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
667 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
668 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
669 state->m_atvPreSawCfg.reference = 0x04;
670 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300671
672
673 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300674 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
675 state->m_dvbtRfAgcCfg.outputLevel = 0;
676 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
677 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
678 state->m_dvbtRfAgcCfg.top = 0x2100;
679 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
680 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681
682
683 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300684 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
685 state->m_dvbtIfAgcCfg.outputLevel = 0;
686 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
687 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
688 state->m_dvbtIfAgcCfg.top = 13424;
689 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
690 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300691 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300692 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
693 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300694
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 state->m_dvbtPreSawCfg.reference = 4;
696 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300697
698 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300699 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
700 state->m_qamRfAgcCfg.outputLevel = 0;
701 state->m_qamRfAgcCfg.minOutputLevel = 6023;
702 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
703 state->m_qamRfAgcCfg.top = 0x2380;
704 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
705 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300706
707 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300708 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
709 state->m_qamIfAgcCfg.outputLevel = 0;
710 state->m_qamIfAgcCfg.minOutputLevel = 0;
711 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
712 state->m_qamIfAgcCfg.top = 0x0511;
713 state->m_qamIfAgcCfg.cutOffCurrent = 0;
714 state->m_qamIfAgcCfg.speed = 3;
715 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300716 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
717
Oliver Endrissebc7de22011-07-03 13:49:44 -0300718 state->m_qamPgaCfg = 140;
719 state->m_qamPreSawCfg.reference = 4;
720 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300721
722 state->m_OperationMode = OM_NONE;
723 state->m_DrxkState = DRXK_UNINITIALIZED;
724
725 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300726 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
727 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300728 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
729 state->m_invertERR = false; /* If TRUE; invert ERR signal */
730 state->m_invertSTR = false; /* If TRUE; invert STR signals */
731 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
732 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300733
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300734 /* If TRUE; static MPEG clockrate will be used;
735 otherwise clockrate will adapt to the bitrate of the TS */
736
737 state->m_DVBTBitrate = ulDVBTBitrate;
738 state->m_DVBCBitrate = ulDVBCBitrate;
739
740 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300741
742 /* Maximum bitrate in b/s in case static clockrate is selected */
743 state->m_mpegTsStaticBitrate = 19392658;
744 state->m_disableTEIhandling = false;
745
746 if (ulInsertRSByte)
747 state->m_insertRSByte = true;
748
749 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
750 if (ulMpegLockTimeOut < 10000)
751 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
752 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
753 if (ulDemodLockTimeOut < 10000)
754 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
755
Oliver Endrissebc7de22011-07-03 13:49:44 -0300756 /* QAM defaults */
757 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300758 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300759 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
760 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300761
762 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
763 state->m_agcFastClipCtrlDelay = 0;
764
765 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300766
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767 state->m_bPowerDown = false;
768 state->m_currentPowerMode = DRX_POWER_DOWN;
769
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770 state->m_rfmirror = (ulRfMirror == 0);
771 state->m_IfAgcPol = false;
772 return 0;
773}
774
775static int DRXX_Open(struct drxk_state *state)
776{
777 int status = 0;
778 u32 jtag = 0;
779 u16 bid = 0;
780 u16 key = 0;
781
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300782 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300783 /* stop lock indicator process */
784 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
785 if (status < 0)
786 goto error;
787 /* Check device id */
788 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
789 if (status < 0)
790 goto error;
791 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
792 if (status < 0)
793 goto error;
794 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
795 if (status < 0)
796 goto error;
797 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
798 if (status < 0)
799 goto error;
800 status = write16(state, SIO_TOP_COMM_KEY__A, key);
801error:
802 if (status < 0)
803 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300804 return status;
805}
806
807static int GetDeviceCapabilities(struct drxk_state *state)
808{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300809 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810 u32 sioTopJtagidLo = 0;
811 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300812 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300813
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300814 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300816 /* driver 0.9.0 */
817 /* stop lock indicator process */
818 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
819 if (status < 0)
820 goto error;
Martin Blumenstingl84183662012-10-04 14:22:55 -0300821 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300822 if (status < 0)
823 goto error;
824 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
825 if (status < 0)
826 goto error;
827 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
828 if (status < 0)
829 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300831 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
832 case 0:
833 /* ignore (bypass ?) */
834 break;
835 case 1:
836 /* 27 MHz */
837 state->m_oscClockFreq = 27000;
838 break;
839 case 2:
840 /* 20.25 MHz */
841 state->m_oscClockFreq = 20250;
842 break;
843 case 3:
844 /* 4 MHz */
845 state->m_oscClockFreq = 20250;
846 break;
847 default:
Masanari Iida9c768202012-11-30 14:10:25 +0900848 printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300849 return -EINVAL;
850 }
851 /*
852 Determine device capabilities
853 Based on pinning v14
854 */
855 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
856 if (status < 0)
857 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300858
Martin Blumenstingl257ee972012-07-04 17:38:23 -0300859 printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300860
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300861 /* driver 0.9.0 */
862 switch ((sioTopJtagidLo >> 29) & 0xF) {
863 case 0:
864 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300865 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300866 break;
867 case 2:
868 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300869 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300870 break;
871 case 3:
872 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300873 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300874 break;
875 default:
876 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
877 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300878 printk(KERN_ERR "drxk: Spin %d unknown\n",
879 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300880 goto error2;
881 }
882 switch ((sioTopJtagidLo >> 12) & 0xFF) {
883 case 0x13:
884 /* typeId = DRX3913K_TYPE_ID */
885 state->m_hasLNA = false;
886 state->m_hasOOB = false;
887 state->m_hasATV = false;
888 state->m_hasAudio = false;
889 state->m_hasDVBT = true;
890 state->m_hasDVBC = true;
891 state->m_hasSAWSW = true;
892 state->m_hasGPIO2 = false;
893 state->m_hasGPIO1 = false;
894 state->m_hasIRQN = false;
895 break;
896 case 0x15:
897 /* typeId = DRX3915K_TYPE_ID */
898 state->m_hasLNA = false;
899 state->m_hasOOB = false;
900 state->m_hasATV = true;
901 state->m_hasAudio = false;
902 state->m_hasDVBT = true;
903 state->m_hasDVBC = false;
904 state->m_hasSAWSW = true;
905 state->m_hasGPIO2 = true;
906 state->m_hasGPIO1 = true;
907 state->m_hasIRQN = false;
908 break;
909 case 0x16:
910 /* typeId = DRX3916K_TYPE_ID */
911 state->m_hasLNA = false;
912 state->m_hasOOB = false;
913 state->m_hasATV = true;
914 state->m_hasAudio = false;
915 state->m_hasDVBT = true;
916 state->m_hasDVBC = false;
917 state->m_hasSAWSW = true;
918 state->m_hasGPIO2 = true;
919 state->m_hasGPIO1 = true;
920 state->m_hasIRQN = false;
921 break;
922 case 0x18:
923 /* typeId = DRX3918K_TYPE_ID */
924 state->m_hasLNA = false;
925 state->m_hasOOB = false;
926 state->m_hasATV = true;
927 state->m_hasAudio = true;
928 state->m_hasDVBT = true;
929 state->m_hasDVBC = false;
930 state->m_hasSAWSW = true;
931 state->m_hasGPIO2 = true;
932 state->m_hasGPIO1 = true;
933 state->m_hasIRQN = false;
934 break;
935 case 0x21:
936 /* typeId = DRX3921K_TYPE_ID */
937 state->m_hasLNA = false;
938 state->m_hasOOB = false;
939 state->m_hasATV = true;
940 state->m_hasAudio = true;
941 state->m_hasDVBT = true;
942 state->m_hasDVBC = true;
943 state->m_hasSAWSW = true;
944 state->m_hasGPIO2 = true;
945 state->m_hasGPIO1 = true;
946 state->m_hasIRQN = false;
947 break;
948 case 0x23:
949 /* typeId = DRX3923K_TYPE_ID */
950 state->m_hasLNA = false;
951 state->m_hasOOB = false;
952 state->m_hasATV = true;
953 state->m_hasAudio = true;
954 state->m_hasDVBT = true;
955 state->m_hasDVBC = true;
956 state->m_hasSAWSW = true;
957 state->m_hasGPIO2 = true;
958 state->m_hasGPIO1 = true;
959 state->m_hasIRQN = false;
960 break;
961 case 0x25:
962 /* typeId = DRX3925K_TYPE_ID */
963 state->m_hasLNA = false;
964 state->m_hasOOB = false;
965 state->m_hasATV = true;
966 state->m_hasAudio = true;
967 state->m_hasDVBT = true;
968 state->m_hasDVBC = true;
969 state->m_hasSAWSW = true;
970 state->m_hasGPIO2 = true;
971 state->m_hasGPIO1 = true;
972 state->m_hasIRQN = false;
973 break;
974 case 0x26:
975 /* typeId = DRX3926K_TYPE_ID */
976 state->m_hasLNA = false;
977 state->m_hasOOB = false;
978 state->m_hasATV = true;
979 state->m_hasAudio = false;
980 state->m_hasDVBT = true;
981 state->m_hasDVBC = true;
982 state->m_hasSAWSW = true;
983 state->m_hasGPIO2 = true;
984 state->m_hasGPIO1 = true;
985 state->m_hasIRQN = false;
986 break;
987 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300988 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300989 ((sioTopJtagidLo >> 12) & 0xFF));
990 status = -EINVAL;
991 goto error2;
992 }
993
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300994 printk(KERN_INFO
995 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
996 ((sioTopJtagidLo >> 12) & 0xFF), spin,
997 state->m_oscClockFreq / 1000,
998 state->m_oscClockFreq % 1000);
999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001000error:
1001 if (status < 0)
1002 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1003
1004error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001005 return status;
1006}
1007
1008static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1009{
1010 int status;
1011 bool powerdown_cmd;
1012
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001013 dprintk(1, "\n");
1014
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001015 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001016 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001017 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001019 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1020 msleep(1);
1021
1022 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001023 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1024 ((state->m_HICfgCtrl) &
1025 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1026 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001027 if (powerdown_cmd == false) {
1028 /* Wait until command rdy */
1029 u32 retryCount = 0;
1030 u16 waitCmd;
1031
1032 do {
1033 msleep(1);
1034 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001035 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1036 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001037 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1038 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001039 if (status < 0)
1040 goto error;
1041 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001042 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001043error:
1044 if (status < 0)
1045 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1046
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001047 return status;
1048}
1049
1050static int HI_CfgCommand(struct drxk_state *state)
1051{
1052 int status;
1053
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001054 dprintk(1, "\n");
1055
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001056 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001057
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001058 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1059 if (status < 0)
1060 goto error;
1061 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1062 if (status < 0)
1063 goto error;
1064 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1065 if (status < 0)
1066 goto error;
1067 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1068 if (status < 0)
1069 goto error;
1070 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1071 if (status < 0)
1072 goto error;
1073 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1074 if (status < 0)
1075 goto error;
1076 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1077 if (status < 0)
1078 goto error;
1079
1080 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1081error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001082 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001083 if (status < 0)
1084 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001085 return status;
1086}
1087
1088static int InitHI(struct drxk_state *state)
1089{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001090 dprintk(1, "\n");
1091
Oliver Endrissebc7de22011-07-03 13:49:44 -03001092 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093 state->m_HICfgTimeout = 0x96FF;
1094 /* port/bridge/power down ctrl */
1095 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001096
Oliver Endrissebc7de22011-07-03 13:49:44 -03001097 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001098}
1099
1100static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1101{
1102 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001103 u16 sioPdrMclkCfg = 0;
1104 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001105 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001107 dprintk(1, ": mpeg %s, %s mode\n",
1108 mpegEnable ? "enable" : "disable",
1109 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001111 /* stop lock indicator process */
1112 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1113 if (status < 0)
1114 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001116 /* MPEG TS pad configuration */
Martin Blumenstingl84183662012-10-04 14:22:55 -03001117 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001118 if (status < 0)
1119 goto error;
1120
1121 if (mpegEnable == false) {
1122 /* Set MPEG TS pads to inputmode */
1123 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1124 if (status < 0)
1125 goto error;
1126 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1127 if (status < 0)
1128 goto error;
1129 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1130 if (status < 0)
1131 goto error;
1132 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1133 if (status < 0)
1134 goto error;
1135 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1136 if (status < 0)
1137 goto error;
1138 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1139 if (status < 0)
1140 goto error;
1141 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1142 if (status < 0)
1143 goto error;
1144 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1145 if (status < 0)
1146 goto error;
1147 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1148 if (status < 0)
1149 goto error;
1150 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1151 if (status < 0)
1152 goto error;
1153 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1154 if (status < 0)
1155 goto error;
1156 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1157 if (status < 0)
1158 goto error;
1159 } else {
1160 /* Enable MPEG output */
1161 sioPdrMdxCfg =
1162 ((state->m_TSDataStrength <<
1163 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1164 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1165 SIO_PDR_MCLK_CFG_DRIVE__B) |
1166 0x0003);
1167
1168 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1169 if (status < 0)
1170 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001171
1172 if (state->enable_merr_cfg)
1173 err_cfg = sioPdrMdxCfg;
1174
1175 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001176 if (status < 0)
1177 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001178 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001179 if (status < 0)
1180 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001182 if (state->m_enableParallel == true) {
1183 /* paralel -> enable MD1 to MD7 */
1184 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001185 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001186 goto error;
1187 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001188 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001189 goto error;
1190 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001191 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001192 goto error;
1193 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001194 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001195 goto error;
1196 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001197 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001198 goto error;
1199 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1200 if (status < 0)
1201 goto error;
1202 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1203 if (status < 0)
1204 goto error;
1205 } else {
1206 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1207 SIO_PDR_MD0_CFG_DRIVE__B)
1208 | 0x0003);
1209 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001210 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001211 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001212 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001213 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001214 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001215 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001216 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001217 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001218 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001219 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001220 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001221 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001222 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001223 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001224 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001225 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001226 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001227 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001228 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001229 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001230 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001231 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001232 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001233 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001234 goto error;
1235 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001236 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001237 goto error;
1238 }
1239 /* Enable MB output over MPEG pads and ctl input */
1240 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1241 if (status < 0)
1242 goto error;
1243 /* Write nomagic word to enable pdr reg write */
1244 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1245error:
1246 if (status < 0)
1247 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001248 return status;
1249}
1250
1251static int MPEGTSDisable(struct drxk_state *state)
1252{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001253 dprintk(1, "\n");
1254
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001255 return MPEGTSConfigurePins(state, false);
1256}
1257
1258static int BLChainCmd(struct drxk_state *state,
1259 u16 romOffset, u16 nrOfElements, u32 timeOut)
1260{
1261 u16 blStatus = 0;
1262 int status;
1263 unsigned long end;
1264
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001265 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001266 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001267 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1268 if (status < 0)
1269 goto error;
1270 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1271 if (status < 0)
1272 goto error;
1273 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1274 if (status < 0)
1275 goto error;
1276 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1277 if (status < 0)
1278 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001279
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001280 end = jiffies + msecs_to_jiffies(timeOut);
1281 do {
1282 msleep(1);
1283 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1284 if (status < 0)
1285 goto error;
1286 } while ((blStatus == 0x1) &&
1287 ((time_is_after_jiffies(end))));
1288
1289 if (blStatus == 0x1) {
1290 printk(KERN_ERR "drxk: SIO not ready\n");
1291 status = -EINVAL;
1292 goto error2;
1293 }
1294error:
1295 if (status < 0)
1296 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1297error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001298 mutex_unlock(&state->mutex);
1299 return status;
1300}
1301
1302
1303static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001304 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001305{
1306 const u8 *pSrc = pMCImage;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001307 u32 Address;
1308 u16 nBlocks;
1309 u16 BlockSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001310 u32 offset = 0;
1311 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001312 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001313
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001314 dprintk(1, "\n");
1315
Hans Verkuil5becbc52012-05-14 10:22:58 -03001316 /* down the drain (we don't care about MAGIC_WORD) */
1317#if 0
1318 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001319 Drain = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001320#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001321 pSrc += sizeof(u16);
1322 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001323 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001324 pSrc += sizeof(u16);
1325 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001326
1327 for (i = 0; i < nBlocks; i += 1) {
1328 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001329 (pSrc[2] << 8) | pSrc[3];
1330 pSrc += sizeof(u32);
1331 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001332
1333 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001334 pSrc += sizeof(u16);
1335 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001336
Hans Verkuil5becbc52012-05-14 10:22:58 -03001337#if 0
1338 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001339 Flags = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001340#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001341 pSrc += sizeof(u16);
1342 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001343
Hans Verkuil5becbc52012-05-14 10:22:58 -03001344#if 0
1345 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001346 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001347#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001348 pSrc += sizeof(u16);
1349 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001350
1351 if (offset + BlockSize > Length) {
1352 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1353 return -EINVAL;
1354 }
1355
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001356 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001357 if (status < 0) {
1358 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001359 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001360 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001361 pSrc += BlockSize;
1362 offset += BlockSize;
1363 }
1364 return status;
1365}
1366
1367static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1368{
1369 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001370 u16 data = 0;
1371 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001372 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1373 unsigned long end;
1374
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001375 dprintk(1, "\n");
1376
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001378 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001379 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1380 }
1381
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001382 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1383 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384 /* tokenring already has correct status */
1385 return status;
1386 }
1387 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001388 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001389
Oliver Endrissebc7de22011-07-03 13:49:44 -03001390 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001391 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001392 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001393 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001394 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001395 msleep(1);
1396 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001397 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001398 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001399 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400 }
1401 return status;
1402}
1403
1404static int MPEGTSStop(struct drxk_state *state)
1405{
1406 int status = 0;
1407 u16 fecOcSncMode = 0;
1408 u16 fecOcIprMode = 0;
1409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001410 dprintk(1, "\n");
1411
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001412 /* Gracefull shutdown (byte boundaries) */
1413 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1414 if (status < 0)
1415 goto error;
1416 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1417 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1418 if (status < 0)
1419 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001420
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001421 /* Suppress MCLK during absence of data */
1422 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1423 if (status < 0)
1424 goto error;
1425 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1426 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1427
1428error:
1429 if (status < 0)
1430 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1431
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432 return status;
1433}
1434
1435static int scu_command(struct drxk_state *state,
1436 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001437 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001438{
1439#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1440#error DRXK register mapping no longer compatible with this routine!
1441#endif
1442 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001443 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001444 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001445 u8 buffer[34];
1446 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001447 const char *p;
1448 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001450 dprintk(1, "\n");
1451
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001452 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001453 ((resultLen > 0) && (result == NULL))) {
1454 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1455 return status;
1456 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457
1458 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001459
1460 /* assume that the command register is ready
1461 since it is checked afterwards */
1462 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1463 buffer[cnt++] = (parameter[ii] & 0xFF);
1464 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1465 }
1466 buffer[cnt++] = (cmd & 0xFF);
1467 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1468
1469 write_block(state, SCU_RAM_PARAM_0__A -
1470 (parameterLen - 1), cnt, buffer);
1471 /* Wait until SCU has processed command */
1472 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001474 msleep(1);
1475 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1476 if (status < 0)
1477 goto error;
1478 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1479 if (curCmd != DRX_SCU_READY) {
1480 printk(KERN_ERR "drxk: SCU not ready\n");
1481 status = -EIO;
1482 goto error2;
1483 }
1484 /* read results */
1485 if ((resultLen > 0) && (result != NULL)) {
1486 s16 err;
1487 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001488
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001489 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1490 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001491 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001492 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001493 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001494
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001495 /* Check if an error was reported by SCU */
1496 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001497 if (err >= 0)
1498 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001499
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001500 /* check for the known error codes */
1501 switch (err) {
1502 case SCU_RESULT_UNKCMD:
1503 p = "SCU_RESULT_UNKCMD";
1504 break;
1505 case SCU_RESULT_UNKSTD:
1506 p = "SCU_RESULT_UNKSTD";
1507 break;
1508 case SCU_RESULT_SIZE:
1509 p = "SCU_RESULT_SIZE";
1510 break;
1511 case SCU_RESULT_INVPAR:
1512 p = "SCU_RESULT_INVPAR";
1513 break;
1514 default: /* Other negative values are errors */
1515 sprintf(errname, "ERROR: %d\n", err);
1516 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001517 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001518 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1519 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1520 status = -EINVAL;
1521 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001522 }
1523
1524error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001525 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001526 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001527error2:
1528 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529 return status;
1530}
1531
1532static int SetIqmAf(struct drxk_state *state, bool active)
1533{
1534 u16 data = 0;
1535 int status;
1536
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001537 dprintk(1, "\n");
1538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001539 /* Configure IQM */
1540 status = read16(state, IQM_AF_STDBY__A, &data);
1541 if (status < 0)
1542 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001544 if (!active) {
1545 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1546 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1547 | IQM_AF_STDBY_STDBY_PD_STANDBY
1548 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1549 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1550 } else {
1551 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1552 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1553 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1554 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1555 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1556 );
1557 }
1558 status = write16(state, IQM_AF_STDBY__A, data);
1559
1560error:
1561 if (status < 0)
1562 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563 return status;
1564}
1565
Oliver Endrissebc7de22011-07-03 13:49:44 -03001566static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567{
1568 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001569 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001570
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001571 dprintk(1, "\n");
1572
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001573 /* Check arguments */
1574 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001575 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576
1577 switch (*mode) {
1578 case DRX_POWER_UP:
1579 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1580 break;
1581 case DRXK_POWER_DOWN_OFDM:
1582 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1583 break;
1584 case DRXK_POWER_DOWN_CORE:
1585 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1586 break;
1587 case DRXK_POWER_DOWN_PLL:
1588 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1589 break;
1590 case DRX_POWER_DOWN:
1591 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1592 break;
1593 default:
1594 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596 }
1597
1598 /* If already in requested power mode, do nothing */
1599 if (state->m_currentPowerMode == *mode)
1600 return 0;
1601
1602 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001603 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001604 status = PowerUpDevice(state);
1605 if (status < 0)
1606 goto error;
1607 status = DVBTEnableOFDMTokenRing(state, true);
1608 if (status < 0)
1609 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001610 }
1611
1612 if (*mode == DRX_POWER_UP) {
1613 /* Restore analog & pin configuartion */
1614 } else {
1615 /* Power down to requested mode */
1616 /* Backup some register settings */
1617 /* Set pins with possible pull-ups connected
1618 to them in input mode */
1619 /* Analog power down */
1620 /* ADC power down */
1621 /* Power down device */
1622 /* stop all comm_exec */
1623 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001624 switch (state->m_OperationMode) {
1625 case OM_DVBT:
1626 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001627 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001628 goto error;
1629 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001630 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001631 goto error;
1632 break;
1633 case OM_QAM_ITU_A:
1634 case OM_QAM_ITU_C:
1635 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001636 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001637 goto error;
1638 status = PowerDownQAM(state);
1639 if (status < 0)
1640 goto error;
1641 break;
1642 default:
1643 break;
1644 }
1645 status = DVBTEnableOFDMTokenRing(state, false);
1646 if (status < 0)
1647 goto error;
1648 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1649 if (status < 0)
1650 goto error;
1651 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1652 if (status < 0)
1653 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001654
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001655 if (*mode != DRXK_POWER_DOWN_OFDM) {
1656 state->m_HICfgCtrl |=
1657 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1658 status = HI_CfgCommand(state);
1659 if (status < 0)
1660 goto error;
1661 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001662 }
1663 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001664
1665error:
1666 if (status < 0)
1667 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1668
Oliver Endrissebc7de22011-07-03 13:49:44 -03001669 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670}
1671
1672static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1673{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001674 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001675 u16 cmdResult = 0;
1676 u16 data = 0;
1677 int status;
1678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001679 dprintk(1, "\n");
1680
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001681 status = read16(state, SCU_COMM_EXEC__A, &data);
1682 if (status < 0)
1683 goto error;
1684 if (data == SCU_COMM_EXEC_ACTIVE) {
1685 /* Send OFDM stop command */
1686 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 -03001687 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001688 goto error;
1689 /* Send OFDM reset command */
1690 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1691 if (status < 0)
1692 goto error;
1693 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001695 /* Reset datapath for OFDM, processors first */
1696 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1697 if (status < 0)
1698 goto error;
1699 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1700 if (status < 0)
1701 goto error;
1702 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1703 if (status < 0)
1704 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001705
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001706 /* powerdown AFE */
1707 status = SetIqmAf(state, false);
1708 if (status < 0)
1709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001711 /* powerdown to OFDM mode */
1712 if (setPowerMode) {
1713 status = CtrlPowerMode(state, &powerMode);
1714 if (status < 0)
1715 goto error;
1716 }
1717error:
1718 if (status < 0)
1719 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001720 return status;
1721}
1722
Oliver Endrissebc7de22011-07-03 13:49:44 -03001723static int SetOperationMode(struct drxk_state *state,
1724 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001725{
1726 int status = 0;
1727
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001728 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001729 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001730 Stop and power down previous standard
1731 TODO investigate total power down instead of partial
1732 power down depending on "previous" standard.
1733 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001734
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001735 /* disable HW lock indicator */
1736 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1737 if (status < 0)
1738 goto error;
1739
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001740 /* Device is already at the required mode */
1741 if (state->m_OperationMode == oMode)
1742 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001743
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001744 switch (state->m_OperationMode) {
1745 /* OM_NONE was added for start up */
1746 case OM_NONE:
1747 break;
1748 case OM_DVBT:
1749 status = MPEGTSStop(state);
1750 if (status < 0)
1751 goto error;
1752 status = PowerDownDVBT(state, true);
1753 if (status < 0)
1754 goto error;
1755 state->m_OperationMode = OM_NONE;
1756 break;
1757 case OM_QAM_ITU_A: /* fallthrough */
1758 case OM_QAM_ITU_C:
1759 status = MPEGTSStop(state);
1760 if (status < 0)
1761 goto error;
1762 status = PowerDownQAM(state);
1763 if (status < 0)
1764 goto error;
1765 state->m_OperationMode = OM_NONE;
1766 break;
1767 case OM_QAM_ITU_B:
1768 default:
1769 status = -EINVAL;
1770 goto error;
1771 }
1772
1773 /*
1774 Power up new standard
1775 */
1776 switch (oMode) {
1777 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001778 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001779 state->m_OperationMode = oMode;
1780 status = SetDVBTStandard(state, oMode);
1781 if (status < 0)
1782 goto error;
1783 break;
1784 case OM_QAM_ITU_A: /* fallthrough */
1785 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001786 dprintk(1, ": DVB-C Annex %c\n",
1787 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001788 state->m_OperationMode = oMode;
1789 status = SetQAMStandard(state, oMode);
1790 if (status < 0)
1791 goto error;
1792 break;
1793 case OM_QAM_ITU_B:
1794 default:
1795 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001796 }
1797error:
1798 if (status < 0)
1799 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1800 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801}
1802
1803static int Start(struct drxk_state *state, s32 offsetFreq,
1804 s32 IntermediateFrequency)
1805{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001806 int status = -EINVAL;
1807
1808 u16 IFreqkHz;
1809 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001811 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001812 if (state->m_DrxkState != DRXK_STOPPED &&
1813 state->m_DrxkState != DRXK_DTV_STARTED)
1814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001815
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001816 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001818 if (IntermediateFrequency < 0) {
1819 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1820 IntermediateFrequency = -IntermediateFrequency;
1821 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001823 switch (state->m_OperationMode) {
1824 case OM_QAM_ITU_A:
1825 case OM_QAM_ITU_C:
1826 IFreqkHz = (IntermediateFrequency / 1000);
1827 status = SetQAM(state, IFreqkHz, OffsetkHz);
1828 if (status < 0)
1829 goto error;
1830 state->m_DrxkState = DRXK_DTV_STARTED;
1831 break;
1832 case OM_DVBT:
1833 IFreqkHz = (IntermediateFrequency / 1000);
1834 status = MPEGTSStop(state);
1835 if (status < 0)
1836 goto error;
1837 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1838 if (status < 0)
1839 goto error;
1840 status = DVBTStart(state);
1841 if (status < 0)
1842 goto error;
1843 state->m_DrxkState = DRXK_DTV_STARTED;
1844 break;
1845 default:
1846 break;
1847 }
1848error:
1849 if (status < 0)
1850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001851 return status;
1852}
1853
1854static int ShutDown(struct drxk_state *state)
1855{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001856 dprintk(1, "\n");
1857
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001858 MPEGTSStop(state);
1859 return 0;
1860}
1861
Jean Delvarea3ad56d2013-03-20 12:43:21 +00001862static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001863{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001864 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001866 dprintk(1, "\n");
1867
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001868 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001869 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870
1871 *pLockStatus = NOT_LOCKED;
1872
1873 /* define the SCU command code */
1874 switch (state->m_OperationMode) {
1875 case OM_QAM_ITU_A:
1876 case OM_QAM_ITU_B:
1877 case OM_QAM_ITU_C:
1878 status = GetQAMLockStatus(state, pLockStatus);
1879 break;
1880 case OM_DVBT:
1881 status = GetDVBTLockStatus(state, pLockStatus);
1882 break;
1883 default:
1884 break;
1885 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886error:
1887 if (status < 0)
1888 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889 return status;
1890}
1891
1892static int MPEGTSStart(struct drxk_state *state)
1893{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001894 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895
1896 u16 fecOcSncMode = 0;
1897
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001898 /* Allow OC to sync again */
1899 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1900 if (status < 0)
1901 goto error;
1902 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1903 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1904 if (status < 0)
1905 goto error;
1906 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1907error:
1908 if (status < 0)
1909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001910 return status;
1911}
1912
1913static int MPEGTSDtoInit(struct drxk_state *state)
1914{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001915 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001916
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001917 dprintk(1, "\n");
1918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001919 /* Rate integration settings */
1920 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1921 if (status < 0)
1922 goto error;
1923 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1924 if (status < 0)
1925 goto error;
1926 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1927 if (status < 0)
1928 goto error;
1929 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1930 if (status < 0)
1931 goto error;
1932 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1933 if (status < 0)
1934 goto error;
1935 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1936 if (status < 0)
1937 goto error;
1938 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1939 if (status < 0)
1940 goto error;
1941 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1942 if (status < 0)
1943 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001944
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001945 /* Additional configuration */
1946 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
1947 if (status < 0)
1948 goto error;
1949 status = write16(state, FEC_OC_SNC_LWM__A, 2);
1950 if (status < 0)
1951 goto error;
1952 status = write16(state, FEC_OC_SNC_HWM__A, 12);
1953error:
1954 if (status < 0)
1955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1956
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001957 return status;
1958}
1959
Oliver Endrissebc7de22011-07-03 13:49:44 -03001960static int MPEGTSDtoSetup(struct drxk_state *state,
1961 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001964
Oliver Endrissebc7de22011-07-03 13:49:44 -03001965 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
1966 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
1967 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
1968 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
1969 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
1970 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
1971 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001972 u16 fecOcTmdMode = 0;
1973 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001974 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001975 bool staticCLK = false;
1976
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001977 dprintk(1, "\n");
1978
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001979 /* Check insertion of the Reed-Solomon parity bytes */
1980 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
1981 if (status < 0)
1982 goto error;
1983 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
1984 if (status < 0)
1985 goto error;
1986 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
1987 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
1988 if (state->m_insertRSByte == true) {
1989 /* enable parity symbol forward */
1990 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
1991 /* MVAL disable during parity bytes */
1992 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
1993 /* TS burst length to 204 */
1994 fecOcDtoBurstLen = 204;
1995 }
1996
1997 /* Check serial or parrallel output */
1998 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
1999 if (state->m_enableParallel == false) {
2000 /* MPEG data output is serial -> set ipr_mode[0] */
2001 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2002 }
2003
2004 switch (oMode) {
2005 case OM_DVBT:
2006 maxBitRate = state->m_DVBTBitrate;
2007 fecOcTmdMode = 3;
2008 fecOcRcnCtlRate = 0xC00000;
2009 staticCLK = state->m_DVBTStaticCLK;
2010 break;
2011 case OM_QAM_ITU_A: /* fallthrough */
2012 case OM_QAM_ITU_C:
2013 fecOcTmdMode = 0x0004;
2014 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2015 maxBitRate = state->m_DVBCBitrate;
2016 staticCLK = state->m_DVBCStaticCLK;
2017 break;
2018 default:
2019 status = -EINVAL;
2020 } /* switch (standard) */
2021 if (status < 0)
2022 goto error;
2023
2024 /* Configure DTO's */
2025 if (staticCLK) {
2026 u32 bitRate = 0;
2027
2028 /* Rational DTO for MCLK source (static MCLK rate),
2029 Dynamic DTO for optimal grouping
2030 (avoid intra-packet gaps),
2031 DTO offset enable to sync TS burst with MSTRT */
2032 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2033 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2034 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2035 FEC_OC_FCT_MODE_VIRT_ENA__M);
2036
2037 /* Check user defined bitrate */
2038 bitRate = maxBitRate;
2039 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2040 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002042 /* Rational DTO period:
2043 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002045 Result should be floored,
2046 to make sure >= requested bitrate
2047 */
2048 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2049 * 1000) / bitRate);
2050 if (fecOcDtoPeriod <= 2)
2051 fecOcDtoPeriod = 0;
2052 else
2053 fecOcDtoPeriod -= 2;
2054 fecOcTmdIntUpdRate = 8;
2055 } else {
2056 /* (commonAttr->staticCLK == false) => dynamic mode */
2057 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2058 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2059 fecOcTmdIntUpdRate = 5;
2060 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002062 /* Write appropriate registers with requested configuration */
2063 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2064 if (status < 0)
2065 goto error;
2066 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2067 if (status < 0)
2068 goto error;
2069 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2070 if (status < 0)
2071 goto error;
2072 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2073 if (status < 0)
2074 goto error;
2075 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2076 if (status < 0)
2077 goto error;
2078 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2079 if (status < 0)
2080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002082 /* Rate integration settings */
2083 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2084 if (status < 0)
2085 goto error;
2086 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2087 if (status < 0)
2088 goto error;
2089 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2090error:
2091 if (status < 0)
2092 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002093 return status;
2094}
2095
2096static int MPEGTSConfigurePolarity(struct drxk_state *state)
2097{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002098 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002099
2100 /* Data mask for the output data byte */
2101 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002102 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2103 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2104 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2105 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002107 dprintk(1, "\n");
2108
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002109 /* Control selective inversion of output bits */
2110 fecOcRegIprInvert &= (~(InvertDataMask));
2111 if (state->m_invertDATA == true)
2112 fecOcRegIprInvert |= InvertDataMask;
2113 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2114 if (state->m_invertERR == true)
2115 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2116 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2117 if (state->m_invertSTR == true)
2118 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2119 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2120 if (state->m_invertVAL == true)
2121 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2122 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2123 if (state->m_invertCLK == true)
2124 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002125
2126 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127}
2128
2129#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2130
2131static int SetAgcRf(struct drxk_state *state,
2132 struct SCfgAgc *pAgcCfg, bool isDTV)
2133{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002134 int status = -EINVAL;
2135 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002136 struct SCfgAgc *pIfAgcSettings;
2137
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002138 dprintk(1, "\n");
2139
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002140 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002142
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002143 switch (pAgcCfg->ctrlMode) {
2144 case DRXK_AGC_CTRL_AUTO:
2145 /* Enable RF AGC DAC */
2146 status = read16(state, IQM_AF_STDBY__A, &data);
2147 if (status < 0)
2148 goto error;
2149 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2150 status = write16(state, IQM_AF_STDBY__A, data);
2151 if (status < 0)
2152 goto error;
2153 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2154 if (status < 0)
2155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002157 /* Enable SCU RF AGC loop */
2158 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002160 /* Polarity */
2161 if (state->m_RfAgcPol)
2162 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2163 else
2164 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2165 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2166 if (status < 0)
2167 goto error;
2168
2169 /* Set speed (using complementary reduction value) */
2170 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2171 if (status < 0)
2172 goto error;
2173
2174 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2175 data |= (~(pAgcCfg->speed <<
2176 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2177 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2178
2179 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2180 if (status < 0)
2181 goto error;
2182
2183 if (IsDVBT(state))
2184 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2185 else if (IsQAM(state))
2186 pIfAgcSettings = &state->m_qamIfAgcCfg;
2187 else
2188 pIfAgcSettings = &state->m_atvIfAgcCfg;
2189 if (pIfAgcSettings == NULL) {
2190 status = -EINVAL;
2191 goto error;
2192 }
2193
2194 /* Set TOP, only if IF-AGC is in AUTO mode */
2195 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2196 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002197 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002198 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002199
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002200 /* Cut-Off current */
2201 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2202 if (status < 0)
2203 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002204
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002205 /* Max. output level */
2206 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2207 if (status < 0)
2208 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002210 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002212 case DRXK_AGC_CTRL_USER:
2213 /* Enable RF AGC DAC */
2214 status = read16(state, IQM_AF_STDBY__A, &data);
2215 if (status < 0)
2216 goto error;
2217 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2218 status = write16(state, IQM_AF_STDBY__A, data);
2219 if (status < 0)
2220 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002222 /* Disable SCU RF AGC loop */
2223 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2224 if (status < 0)
2225 goto error;
2226 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2227 if (state->m_RfAgcPol)
2228 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2229 else
2230 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2231 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2232 if (status < 0)
2233 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002234
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002235 /* SCU c.o.c. to 0, enabling full control range */
2236 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2237 if (status < 0)
2238 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002239
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002240 /* Write value to output pin */
2241 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2242 if (status < 0)
2243 goto error;
2244 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002246 case DRXK_AGC_CTRL_OFF:
2247 /* Disable RF AGC DAC */
2248 status = read16(state, IQM_AF_STDBY__A, &data);
2249 if (status < 0)
2250 goto error;
2251 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2252 status = write16(state, IQM_AF_STDBY__A, data);
2253 if (status < 0)
2254 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002255
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002256 /* Disable SCU RF AGC loop */
2257 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2258 if (status < 0)
2259 goto error;
2260 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2261 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2262 if (status < 0)
2263 goto error;
2264 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002266 default:
2267 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 }
2270error:
2271 if (status < 0)
2272 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273 return status;
2274}
2275
2276#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2277
Oliver Endrissebc7de22011-07-03 13:49:44 -03002278static int SetAgcIf(struct drxk_state *state,
2279 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280{
2281 u16 data = 0;
2282 int status = 0;
2283 struct SCfgAgc *pRfAgcSettings;
2284
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002285 dprintk(1, "\n");
2286
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002287 switch (pAgcCfg->ctrlMode) {
2288 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002289
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002290 /* Enable IF AGC DAC */
2291 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002292 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002293 goto error;
2294 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2295 status = write16(state, IQM_AF_STDBY__A, data);
2296 if (status < 0)
2297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2300 if (status < 0)
2301 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002302
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002303 /* Enable SCU IF AGC loop */
2304 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2305
2306 /* Polarity */
2307 if (state->m_IfAgcPol)
2308 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2309 else
2310 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2311 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2312 if (status < 0)
2313 goto error;
2314
2315 /* Set speed (using complementary reduction value) */
2316 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2317 if (status < 0)
2318 goto error;
2319 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2320 data |= (~(pAgcCfg->speed <<
2321 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2322 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2323
2324 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2325 if (status < 0)
2326 goto error;
2327
2328 if (IsQAM(state))
2329 pRfAgcSettings = &state->m_qamRfAgcCfg;
2330 else
2331 pRfAgcSettings = &state->m_atvRfAgcCfg;
2332 if (pRfAgcSettings == NULL)
2333 return -1;
2334 /* Restore TOP */
2335 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2336 if (status < 0)
2337 goto error;
2338 break;
2339
2340 case DRXK_AGC_CTRL_USER:
2341
2342 /* Enable IF AGC DAC */
2343 status = read16(state, IQM_AF_STDBY__A, &data);
2344 if (status < 0)
2345 goto error;
2346 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2347 status = write16(state, IQM_AF_STDBY__A, data);
2348 if (status < 0)
2349 goto error;
2350
2351 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2352 if (status < 0)
2353 goto error;
2354
2355 /* Disable SCU IF AGC loop */
2356 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2357
2358 /* Polarity */
2359 if (state->m_IfAgcPol)
2360 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2361 else
2362 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2363 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2364 if (status < 0)
2365 goto error;
2366
2367 /* Write value to output pin */
2368 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2369 if (status < 0)
2370 goto error;
2371 break;
2372
2373 case DRXK_AGC_CTRL_OFF:
2374
2375 /* Disable If AGC DAC */
2376 status = read16(state, IQM_AF_STDBY__A, &data);
2377 if (status < 0)
2378 goto error;
2379 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2380 status = write16(state, IQM_AF_STDBY__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 /* Disable SCU IF AGC loop */
2385 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2386 if (status < 0)
2387 goto error;
2388 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2389 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2390 if (status < 0)
2391 goto error;
2392 break;
2393 } /* switch (agcSettingsIf->ctrlMode) */
2394
2395 /* always set the top to support
2396 configurations without if-loop */
2397 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2398error:
2399 if (status < 0)
2400 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002401 return status;
2402}
2403
Oliver Endrissebc7de22011-07-03 13:49:44 -03002404static int GetQAMSignalToNoise(struct drxk_state *state,
2405 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002406{
2407 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002408 u16 qamSlErrPower = 0; /* accum. error between
2409 raw and sliced symbols */
2410 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002411 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002412 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002413
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002414 dprintk(1, "\n");
2415
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002416 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002417
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002418 /* get the register value needed for MER */
2419 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2420 if (status < 0) {
2421 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2422 return -EINVAL;
2423 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002424
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002425 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002426 case QAM_16:
2427 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2428 break;
2429 case QAM_32:
2430 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2431 break;
2432 case QAM_64:
2433 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2434 break;
2435 case QAM_128:
2436 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2437 break;
2438 default:
2439 case QAM_256:
2440 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2441 break;
2442 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002443
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002444 if (qamSlErrPower > 0) {
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -03002445 qamSlMer = log10times100(qamSlSigPower) -
2446 log10times100((u32) qamSlErrPower);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002447 }
2448 *pSignalToNoise = qamSlMer;
2449
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002450 return status;
2451}
2452
Oliver Endrissebc7de22011-07-03 13:49:44 -03002453static int GetDVBTSignalToNoise(struct drxk_state *state,
2454 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002455{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002456 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002457 u16 regData = 0;
2458 u32 EqRegTdSqrErrI = 0;
2459 u32 EqRegTdSqrErrQ = 0;
2460 u16 EqRegTdSqrErrExp = 0;
2461 u16 EqRegTdTpsPwrOfs = 0;
2462 u16 EqRegTdReqSmbCnt = 0;
2463 u32 tpsCnt = 0;
2464 u32 SqrErrIQ = 0;
2465 u32 a = 0;
2466 u32 b = 0;
2467 u32 c = 0;
2468 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002469 u16 transmissionParams = 0;
2470
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002471 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002473 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2474 if (status < 0)
2475 goto error;
2476 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2477 if (status < 0)
2478 goto error;
2479 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2480 if (status < 0)
2481 goto error;
2482 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2483 if (status < 0)
2484 goto error;
2485 /* Extend SQR_ERR_I operational range */
2486 EqRegTdSqrErrI = (u32) regData;
2487 if ((EqRegTdSqrErrExp > 11) &&
2488 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2489 EqRegTdSqrErrI += 0x00010000UL;
2490 }
2491 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2492 if (status < 0)
2493 goto error;
2494 /* Extend SQR_ERR_Q operational range */
2495 EqRegTdSqrErrQ = (u32) regData;
2496 if ((EqRegTdSqrErrExp > 11) &&
2497 (EqRegTdSqrErrQ < 0x00000FFFUL))
2498 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002499
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002500 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2501 if (status < 0)
2502 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002503
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002504 /* Check input data for MER */
2505
2506 /* MER calculation (in 0.1 dB) without math.h */
2507 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2508 iMER = 0;
2509 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2510 /* No error at all, this must be the HW reset value
2511 * Apparently no first measurement yet
2512 * Set MER to 0.0 */
2513 iMER = 0;
2514 } else {
2515 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2516 EqRegTdSqrErrExp;
2517 if ((transmissionParams &
2518 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2519 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2520 tpsCnt = 17;
2521 else
2522 tpsCnt = 68;
2523
2524 /* IMER = 100 * log10 (x)
2525 where x = (EqRegTdTpsPwrOfs^2 *
2526 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2527
2528 => IMER = a + b -c
2529 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2530 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2531 c = 100 * log10 (SqrErrIQ)
2532 */
2533
2534 /* log(x) x = 9bits * 9bits->18 bits */
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -03002535 a = log10times100(EqRegTdTpsPwrOfs *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002536 EqRegTdTpsPwrOfs);
2537 /* log(x) x = 16bits * 7bits->23 bits */
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -03002538 b = log10times100(EqRegTdReqSmbCnt * tpsCnt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002539 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -03002540 c = log10times100(SqrErrIQ);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002541
Mauro Carvalho Chehab48f72a12013-03-22 06:37:32 -03002542 iMER = a + b - c;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002543 }
2544 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002546error:
2547 if (status < 0)
2548 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002549 return status;
2550}
2551
2552static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2553{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002554 dprintk(1, "\n");
2555
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002556 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002557 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558 case OM_DVBT:
2559 return GetDVBTSignalToNoise(state, pSignalToNoise);
2560 case OM_QAM_ITU_A:
2561 case OM_QAM_ITU_C:
2562 return GetQAMSignalToNoise(state, pSignalToNoise);
2563 default:
2564 break;
2565 }
2566 return 0;
2567}
2568
2569#if 0
2570static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2571{
2572 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2573 int status = 0;
2574
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002575 dprintk(1, "\n");
2576
Oliver Endrissebc7de22011-07-03 13:49:44 -03002577 static s32 QE_SN[] = {
2578 51, /* QPSK 1/2 */
2579 69, /* QPSK 2/3 */
2580 79, /* QPSK 3/4 */
2581 89, /* QPSK 5/6 */
2582 97, /* QPSK 7/8 */
2583 108, /* 16-QAM 1/2 */
2584 131, /* 16-QAM 2/3 */
2585 146, /* 16-QAM 3/4 */
2586 156, /* 16-QAM 5/6 */
2587 160, /* 16-QAM 7/8 */
2588 165, /* 64-QAM 1/2 */
2589 187, /* 64-QAM 2/3 */
2590 202, /* 64-QAM 3/4 */
2591 216, /* 64-QAM 5/6 */
2592 225, /* 64-QAM 7/8 */
2593 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
2595 *pQuality = 0;
2596
2597 do {
2598 s32 SignalToNoise = 0;
2599 u16 Constellation = 0;
2600 u16 CodeRate = 0;
2601 u32 SignalToNoiseRel;
2602 u32 BERQuality;
2603
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002604 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2605 if (status < 0)
2606 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002607 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002608 if (status < 0)
2609 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002610 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2611
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002612 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002613 if (status < 0)
2614 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002615 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2616
2617 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2618 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2619 break;
2620 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002621 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002622 BERQuality = 100;
2623
Oliver Endrissebc7de22011-07-03 13:49:44 -03002624 if (SignalToNoiseRel < -70)
2625 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002626 else if (SignalToNoiseRel < 30)
2627 *pQuality = ((SignalToNoiseRel + 70) *
2628 BERQuality) / 100;
2629 else
2630 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002631 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002632 return 0;
2633};
2634
Oliver Endrissebc7de22011-07-03 13:49:44 -03002635static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002636{
2637 int status = 0;
2638 *pQuality = 0;
2639
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002640 dprintk(1, "\n");
2641
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002642 do {
2643 u32 SignalToNoise = 0;
2644 u32 BERQuality = 100;
2645 u32 SignalToNoiseRel = 0;
2646
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002647 status = GetQAMSignalToNoise(state, &SignalToNoise);
2648 if (status < 0)
2649 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002651 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002652 case QAM_16:
2653 SignalToNoiseRel = SignalToNoise - 200;
2654 break;
2655 case QAM_32:
2656 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002657 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658 case QAM_64:
2659 SignalToNoiseRel = SignalToNoise - 260;
2660 break;
2661 case QAM_128:
2662 SignalToNoiseRel = SignalToNoise - 290;
2663 break;
2664 default:
2665 case QAM_256:
2666 SignalToNoiseRel = SignalToNoise - 320;
2667 break;
2668 }
2669
2670 if (SignalToNoiseRel < -70)
2671 *pQuality = 0;
2672 else if (SignalToNoiseRel < 30)
2673 *pQuality = ((SignalToNoiseRel + 70) *
2674 BERQuality) / 100;
2675 else
2676 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002677 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678
2679 return status;
2680}
2681
2682static int GetQuality(struct drxk_state *state, s32 *pQuality)
2683{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002684 dprintk(1, "\n");
2685
Oliver Endrissebc7de22011-07-03 13:49:44 -03002686 switch (state->m_OperationMode) {
2687 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002688 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002689 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002690 return GetDVBCQuality(state, pQuality);
2691 default:
2692 break;
2693 }
2694
2695 return 0;
2696}
2697#endif
2698
2699/* Free data ram in SIO HI */
2700#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2701#define SIO_HI_RA_RAM_USR_END__A 0x420060
2702
2703#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2704#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2705#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2706#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2707
2708#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2709#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2710#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2711
2712static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2713{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002714 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002716 dprintk(1, "\n");
2717
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002718 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002719 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002723 if (state->no_i2c_bridge)
2724 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002726 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2727 if (status < 0)
2728 goto error;
2729 if (bEnableBridge) {
2730 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 -03002731 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002732 goto error;
2733 } else {
2734 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2735 if (status < 0)
2736 goto error;
2737 }
2738
2739 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2740
2741error:
2742 if (status < 0)
2743 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002744 return status;
2745}
2746
Oliver Endrissebc7de22011-07-03 13:49:44 -03002747static int SetPreSaw(struct drxk_state *state,
2748 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002749{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002750 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002752 dprintk(1, "\n");
2753
Oliver Endrissebc7de22011-07-03 13:49:44 -03002754 if ((pPreSawCfg == NULL)
2755 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002758 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002759error:
2760 if (status < 0)
2761 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 return status;
2763}
2764
2765static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002766 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002768 u16 blStatus = 0;
2769 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2770 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2771 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002772 unsigned long end;
2773
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002774 dprintk(1, "\n");
2775
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002777 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2778 if (status < 0)
2779 goto error;
2780 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2781 if (status < 0)
2782 goto error;
2783 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2784 if (status < 0)
2785 goto error;
2786 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2787 if (status < 0)
2788 goto error;
2789 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2790 if (status < 0)
2791 goto error;
2792 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2793 if (status < 0)
2794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002796 end = jiffies + msecs_to_jiffies(timeOut);
2797 do {
2798 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2799 if (status < 0)
2800 goto error;
2801 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2802 if (blStatus == 0x1) {
2803 printk(KERN_ERR "drxk: SIO not ready\n");
2804 status = -EINVAL;
2805 goto error2;
2806 }
2807error:
2808 if (status < 0)
2809 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2810error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811 mutex_unlock(&state->mutex);
2812 return status;
2813
2814}
2815
Oliver Endrissebc7de22011-07-03 13:49:44 -03002816static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817{
2818 u16 data = 0;
2819 int status;
2820
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002821 dprintk(1, "\n");
2822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002823 /* Start measurement */
2824 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2825 if (status < 0)
2826 goto error;
2827 status = write16(state, IQM_AF_START_LOCK__A, 1);
2828 if (status < 0)
2829 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002831 *count = 0;
2832 status = read16(state, IQM_AF_PHASE0__A, &data);
2833 if (status < 0)
2834 goto error;
2835 if (data == 127)
2836 *count = *count + 1;
2837 status = read16(state, IQM_AF_PHASE1__A, &data);
2838 if (status < 0)
2839 goto error;
2840 if (data == 127)
2841 *count = *count + 1;
2842 status = read16(state, IQM_AF_PHASE2__A, &data);
2843 if (status < 0)
2844 goto error;
2845 if (data == 127)
2846 *count = *count + 1;
2847
2848error:
2849 if (status < 0)
2850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851 return status;
2852}
2853
2854static int ADCSynchronization(struct drxk_state *state)
2855{
2856 u16 count = 0;
2857 int status;
2858
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002859 dprintk(1, "\n");
2860
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002861 status = ADCSyncMeasurement(state, &count);
2862 if (status < 0)
2863 goto error;
2864
2865 if (count == 1) {
2866 /* Try sampling on a diffrent edge */
2867 u16 clkNeg = 0;
2868
2869 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2870 if (status < 0)
2871 goto error;
Dan Carpenter22a09b42012-06-26 04:40:38 -03002872 if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002873 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2874 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2875 clkNeg |=
2876 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2877 } else {
2878 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2879 clkNeg |=
2880 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2881 }
2882 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2883 if (status < 0)
2884 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002885 status = ADCSyncMeasurement(state, &count);
2886 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002887 goto error;
2888 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002890 if (count < 2)
2891 status = -EINVAL;
2892error:
2893 if (status < 0)
2894 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002895 return status;
2896}
2897
2898static int SetFrequencyShifter(struct drxk_state *state,
2899 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002900 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002901{
2902 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002903 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002904 u32 fmFrequencyShift = 0;
2905 bool tunerMirror = !state->m_bMirrorFreqSpect;
2906 u32 adcFreq;
2907 bool adcFlip;
2908 int status;
2909 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002910 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002911 u32 frequencyShift;
2912 bool imageToSelect;
2913
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002914 dprintk(1, "\n");
2915
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002917 Program frequency shifter
2918 No need to account for mirroring on RF
2919 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002920 if (isDTV) {
2921 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
2922 (state->m_OperationMode == OM_QAM_ITU_C) ||
2923 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03002924 selectPosImage = true;
2925 else
2926 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002927 }
2928 if (tunerMirror)
2929 /* tuner doesn't mirror */
2930 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03002931 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932 else
2933 /* tuner mirrors */
2934 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002935 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002936 if (ifFreqActual > samplingFrequency / 2) {
2937 /* adc mirrors */
2938 adcFreq = samplingFrequency - ifFreqActual;
2939 adcFlip = true;
2940 } else {
2941 /* adc doesn't mirror */
2942 adcFreq = ifFreqActual;
2943 adcFlip = false;
2944 }
2945
2946 frequencyShift = adcFreq;
2947 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03002948 adcFlip ^ selectPosImage;
2949 state->m_IqmFsRateOfs =
2950 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002951
2952 if (imageToSelect)
2953 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
2954
2955 /* Program frequency shifter with tuner offset compensation */
2956 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002957 status = write32(state, IQM_FS_RATE_OFS_LO__A,
2958 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002959 if (status < 0)
2960 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002961 return status;
2962}
2963
2964static int InitAGC(struct drxk_state *state, bool isDTV)
2965{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002966 u16 ingainTgt = 0;
2967 u16 ingainTgtMin = 0;
2968 u16 ingainTgtMax = 0;
2969 u16 clpCyclen = 0;
2970 u16 clpSumMin = 0;
2971 u16 clpDirTo = 0;
2972 u16 snsSumMin = 0;
2973 u16 snsSumMax = 0;
2974 u16 clpSumMax = 0;
2975 u16 snsDirTo = 0;
2976 u16 kiInnergainMin = 0;
2977 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002978 u16 ifIaccuHiTgtMin = 0;
2979 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002980 u16 data = 0;
2981 u16 fastClpCtrlDelay = 0;
2982 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002983 int status = 0;
2984
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002985 dprintk(1, "\n");
2986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002987 /* Common settings */
2988 snsSumMax = 1023;
2989 ifIaccuHiTgtMin = 2047;
2990 clpCyclen = 500;
2991 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002992
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002993 /* AGCInit() not available for DVBT; init done in microcode */
2994 if (!IsQAM(state)) {
2995 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
2996 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002997 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002998
2999 /* FIXME: Analog TV AGC require different settings */
3000
3001 /* Standard specific settings */
3002 clpSumMin = 8;
3003 clpDirTo = (u16) -9;
3004 clpCtrlMode = 0;
3005 snsSumMin = 8;
3006 snsDirTo = (u16) -9;
3007 kiInnergainMin = (u16) -1030;
3008 ifIaccuHiTgtMax = 0x2380;
3009 ifIaccuHiTgt = 0x2380;
3010 ingainTgtMin = 0x0511;
3011 ingainTgt = 0x0511;
3012 ingainTgtMax = 5119;
3013 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003015 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3016 if (status < 0)
3017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003019 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3020 if (status < 0)
3021 goto error;
3022 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3023 if (status < 0)
3024 goto error;
3025 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3026 if (status < 0)
3027 goto error;
3028 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3029 if (status < 0)
3030 goto error;
3031 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3032 if (status < 0)
3033 goto error;
3034 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3035 if (status < 0)
3036 goto error;
3037 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3038 if (status < 0)
3039 goto error;
3040 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3041 if (status < 0)
3042 goto error;
3043 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3044 if (status < 0)
3045 goto error;
3046 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3047 if (status < 0)
3048 goto error;
3049 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3050 if (status < 0)
3051 goto error;
3052 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3053 if (status < 0)
3054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003056 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3057 if (status < 0)
3058 goto error;
3059 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3060 if (status < 0)
3061 goto error;
3062 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3063 if (status < 0)
3064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003066 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3067 if (status < 0)
3068 goto error;
3069 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3070 if (status < 0)
3071 goto error;
3072 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3073 if (status < 0)
3074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003076 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3077 if (status < 0)
3078 goto error;
3079 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3080 if (status < 0)
3081 goto error;
3082 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3083 if (status < 0)
3084 goto error;
3085 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3086 if (status < 0)
3087 goto error;
3088 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3089 if (status < 0)
3090 goto error;
3091 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3092 if (status < 0)
3093 goto error;
3094 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3095 if (status < 0)
3096 goto error;
3097 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3098 if (status < 0)
3099 goto error;
3100 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3101 if (status < 0)
3102 goto error;
3103 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3104 if (status < 0)
3105 goto error;
3106 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3107 if (status < 0)
3108 goto error;
3109 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3110 if (status < 0)
3111 goto error;
3112 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3113 if (status < 0)
3114 goto error;
3115 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3116 if (status < 0)
3117 goto error;
3118 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3119 if (status < 0)
3120 goto error;
3121 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3122 if (status < 0)
3123 goto error;
3124 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3131 if (status < 0)
3132 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003134 /* Initialize inner-loop KI gain factors */
3135 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3136 if (status < 0)
3137 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003138
3139 data = 0x0657;
3140 data &= ~SCU_RAM_AGC_KI_RF__M;
3141 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3142 data &= ~SCU_RAM_AGC_KI_IF__M;
3143 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003145 status = write16(state, SCU_RAM_AGC_KI__A, data);
3146error:
3147 if (status < 0)
3148 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003149 return status;
3150}
3151
Oliver Endrissebc7de22011-07-03 13:49:44 -03003152static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153{
3154 int status;
3155
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003156 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003157 if (packetErr == NULL)
3158 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3159 else
3160 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3161 if (status < 0)
3162 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003163 return status;
3164}
3165
3166static int DVBTScCommand(struct drxk_state *state,
3167 u16 cmd, u16 subcmd,
3168 u16 param0, u16 param1, u16 param2,
3169 u16 param3, u16 param4)
3170{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003171 u16 curCmd = 0;
3172 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003173 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003174 u16 scExec = 0;
3175 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003176
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003177 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003178 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003179 if (scExec != 1) {
3180 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003181 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003182 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003183 if (status < 0)
3184 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003185
3186 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003187 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003188 do {
3189 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003190 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003191 retryCnt++;
3192 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003193 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3194 goto error;
3195
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003196 /* Write sub-command */
3197 switch (cmd) {
3198 /* All commands using sub-cmd */
3199 case OFDM_SC_RA_RAM_CMD_PROC_START:
3200 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3201 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003202 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3203 if (status < 0)
3204 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003205 break;
3206 default:
3207 /* Do nothing */
3208 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003209 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210
3211 /* Write needed parameters and the command */
3212 switch (cmd) {
3213 /* All commands using 5 parameters */
3214 /* All commands using 4 parameters */
3215 /* All commands using 3 parameters */
3216 /* All commands using 2 parameters */
3217 case OFDM_SC_RA_RAM_CMD_PROC_START:
3218 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3219 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003220 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003221 /* All commands using 1 parameters */
3222 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3223 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003224 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003225 /* All commands using 0 parameters */
3226 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3227 case OFDM_SC_RA_RAM_CMD_NULL:
3228 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003229 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003230 break;
3231 default:
3232 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003233 status = -EINVAL;
3234 }
3235 if (status < 0)
3236 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237
3238 /* Wait until sc is ready processing command */
3239 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003240 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003242 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003243 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003244 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003245 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3246 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003247
3248 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003249 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003250 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003252 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003254 if (status < 0)
3255 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003256
3257 /* Retreive results parameters from SC */
3258 switch (cmd) {
3259 /* All commands yielding 5 results */
3260 /* All commands yielding 4 results */
3261 /* All commands yielding 3 results */
3262 /* All commands yielding 2 results */
3263 /* All commands yielding 1 result */
3264 case OFDM_SC_RA_RAM_CMD_USER_IO:
3265 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003266 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 /* All commands yielding 0 results */
3268 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3269 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3270 case OFDM_SC_RA_RAM_CMD_PROC_START:
3271 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3272 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3273 case OFDM_SC_RA_RAM_CMD_NULL:
3274 break;
3275 default:
3276 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003277 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003279 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003280error:
3281 if (status < 0)
3282 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 return status;
3284}
3285
Oliver Endrissebc7de22011-07-03 13:49:44 -03003286static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003288 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289 int status;
3290
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003291 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003292 status = CtrlPowerMode(state, &powerMode);
3293 if (status < 0)
3294 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 return status;
3296}
3297
Oliver Endrissebc7de22011-07-03 13:49:44 -03003298static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003301
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003302 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003303 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003304 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003305 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003306 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003307 if (status < 0)
3308 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003309 return status;
3310}
3311
3312#define DEFAULT_FR_THRES_8K 4000
3313static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3314{
3315
3316 int status;
3317
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003318 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003319 if (*enabled == true) {
3320 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003321 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003322 DEFAULT_FR_THRES_8K);
3323 } else {
3324 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003325 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003326 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003327 if (status < 0)
3328 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003329
3330 return status;
3331}
3332
3333static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3334 struct DRXKCfgDvbtEchoThres_t *echoThres)
3335{
3336 u16 data = 0;
3337 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003338
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003339 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003340 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3341 if (status < 0)
3342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003344 switch (echoThres->fftMode) {
3345 case DRX_FFTMODE_2K:
3346 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3347 data |= ((echoThres->threshold <<
3348 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3349 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003350 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003351 case DRX_FFTMODE_8K:
3352 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3353 data |= ((echoThres->threshold <<
3354 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3355 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003356 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 default:
3358 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003361 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3362error:
3363 if (status < 0)
3364 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003365 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366}
3367
3368static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003369 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003370{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003371 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003373 dprintk(1, "\n");
3374
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003375 switch (*speed) {
3376 case DRXK_DVBT_SQI_SPEED_FAST:
3377 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3378 case DRXK_DVBT_SQI_SPEED_SLOW:
3379 break;
3380 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003383 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003385error:
3386 if (status < 0)
3387 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 return status;
3389}
3390
3391/*============================================================================*/
3392
3393/**
3394* \brief Activate DVBT specific presets
3395* \param demod instance of demodulator.
3396* \return DRXStatus_t.
3397*
3398* Called in DVBTSetStandard
3399*
3400*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003401static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003404 bool setincenable = false;
3405 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003406
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3408 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003410 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003411 status = DVBTCtrlSetIncEnable(state, &setincenable);
3412 if (status < 0)
3413 goto error;
3414 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3415 if (status < 0)
3416 goto error;
3417 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3418 if (status < 0)
3419 goto error;
3420 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3421 if (status < 0)
3422 goto error;
3423 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3424error:
3425 if (status < 0)
3426 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003428}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003430/*============================================================================*/
3431
3432/**
3433* \brief Initialize channelswitch-independent settings for DVBT.
3434* \param demod instance of demodulator.
3435* \return DRXStatus_t.
3436*
3437* For ROM code channel filter taps are loaded from the bootloader. For microcode
3438* the DVB-T taps from the drxk_filters.h are used.
3439*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003440static int SetDVBTStandard(struct drxk_state *state,
3441 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003443 u16 cmdResult = 0;
3444 u16 data = 0;
3445 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003447 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003449 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003450 /* added antenna switch */
3451 SwitchAntennaToDVBT(state);
3452 /* send OFDM reset command */
3453 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 -03003454 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003455 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003456
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003457 /* send OFDM setenv command */
3458 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3459 if (status < 0)
3460 goto error;
3461
3462 /* reset datapath for OFDM, processors first */
3463 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3464 if (status < 0)
3465 goto error;
3466 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3467 if (status < 0)
3468 goto error;
3469 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3470 if (status < 0)
3471 goto error;
3472
3473 /* IQM setup */
3474 /* synchronize on ofdstate->m_festart */
3475 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3476 if (status < 0)
3477 goto error;
3478 /* window size for clipping ADC detection */
3479 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3480 if (status < 0)
3481 goto error;
3482 /* window size for for sense pre-SAW detection */
3483 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3484 if (status < 0)
3485 goto error;
3486 /* sense threshold for sense pre-SAW detection */
3487 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3488 if (status < 0)
3489 goto error;
3490 status = SetIqmAf(state, true);
3491 if (status < 0)
3492 goto error;
3493
3494 status = write16(state, IQM_AF_AGC_RF__A, 0);
3495 if (status < 0)
3496 goto error;
3497
3498 /* Impulse noise cruncher setup */
3499 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3500 if (status < 0)
3501 goto error;
3502 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3503 if (status < 0)
3504 goto error;
3505 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3506 if (status < 0)
3507 goto error;
3508
3509 status = write16(state, IQM_RC_STRETCH__A, 16);
3510 if (status < 0)
3511 goto error;
3512 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3513 if (status < 0)
3514 goto error;
3515 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3516 if (status < 0)
3517 goto error;
3518 status = write16(state, IQM_CF_SCALE__A, 1600);
3519 if (status < 0)
3520 goto error;
3521 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3522 if (status < 0)
3523 goto error;
3524
3525 /* virtual clipping threshold for clipping ADC detection */
3526 status = write16(state, IQM_AF_CLP_TH__A, 448);
3527 if (status < 0)
3528 goto error;
3529 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3530 if (status < 0)
3531 goto error;
3532
3533 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3534 if (status < 0)
3535 goto error;
3536
3537 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3538 if (status < 0)
3539 goto error;
3540 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3541 if (status < 0)
3542 goto error;
3543 /* enable power measurement interrupt */
3544 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3545 if (status < 0)
3546 goto error;
3547 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3548 if (status < 0)
3549 goto error;
3550
3551 /* IQM will not be reset from here, sync ADC and update/init AGC */
3552 status = ADCSynchronization(state);
3553 if (status < 0)
3554 goto error;
3555 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3556 if (status < 0)
3557 goto error;
3558
3559 /* Halt SCU to enable safe non-atomic accesses */
3560 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3561 if (status < 0)
3562 goto error;
3563
3564 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3565 if (status < 0)
3566 goto error;
3567 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3568 if (status < 0)
3569 goto error;
3570
3571 /* Set Noise Estimation notch width and enable DC fix */
3572 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3573 if (status < 0)
3574 goto error;
3575 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3576 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3577 if (status < 0)
3578 goto error;
3579
3580 /* Activate SCU to enable SCU commands */
3581 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3582 if (status < 0)
3583 goto error;
3584
3585 if (!state->m_DRXK_A3_ROM_CODE) {
3586 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3587 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3588 if (status < 0)
3589 goto error;
3590 }
3591
3592 /* OFDM_SC setup */
3593#ifdef COMPILE_FOR_NONRT
3594 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3595 if (status < 0)
3596 goto error;
3597 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3598 if (status < 0)
3599 goto error;
3600#endif
3601
3602 /* FEC setup */
3603 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3604 if (status < 0)
3605 goto error;
3606
3607
3608#ifdef COMPILE_FOR_NONRT
3609 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3610 if (status < 0)
3611 goto error;
3612#else
3613 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3614 if (status < 0)
3615 goto error;
3616#endif
3617 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3618 if (status < 0)
3619 goto error;
3620
3621 /* Setup MPEG bus */
3622 status = MPEGTSDtoSetup(state, OM_DVBT);
3623 if (status < 0)
3624 goto error;
3625 /* Set DVBT Presets */
3626 status = DVBTActivatePresets(state);
3627 if (status < 0)
3628 goto error;
3629
3630error:
3631 if (status < 0)
3632 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633 return status;
3634}
3635
3636/*============================================================================*/
3637/**
3638* \brief Start dvbt demodulating for channel.
3639* \param demod instance of demodulator.
3640* \return DRXStatus_t.
3641*/
3642static int DVBTStart(struct drxk_state *state)
3643{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003644 u16 param1;
3645 int status;
3646 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003647
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003648 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003649 /* Start correct processes to get in lock */
3650 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003651 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3652 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3653 if (status < 0)
3654 goto error;
3655 /* Start FEC OC */
3656 status = MPEGTSStart(state);
3657 if (status < 0)
3658 goto error;
3659 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3660 if (status < 0)
3661 goto error;
3662error:
3663 if (status < 0)
3664 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003665 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003666}
3667
3668
3669/*============================================================================*/
3670
3671/**
3672* \brief Set up dvbt demodulator for channel.
3673* \param demod instance of demodulator.
3674* \return DRXStatus_t.
3675* // original DVBTSetChannel()
3676*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003677static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3678 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003679{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003680 u16 cmdResult = 0;
3681 u16 transmissionParams = 0;
3682 u16 operationMode = 0;
3683 u32 iqmRcRateOfs = 0;
3684 u32 bandwidth = 0;
3685 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003686 int status;
3687
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003688 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003689
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003690 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3691 if (status < 0)
3692 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003693
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003694 /* 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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003698
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003699 /* Stop processors */
3700 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3701 if (status < 0)
3702 goto error;
3703 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3704 if (status < 0)
3705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003707 /* Mandatory fix, always stop CP, required to set spl offset back to
3708 hardware default (is set to 0 by ucode during pilot detection */
3709 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3710 if (status < 0)
3711 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003713 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003715 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003716 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003717 case TRANSMISSION_MODE_AUTO:
3718 default:
3719 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3720 /* fall through , try first guess DRX_FFTMODE_8K */
3721 case TRANSMISSION_MODE_8K:
3722 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003723 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003724 case TRANSMISSION_MODE_2K:
3725 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003726 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003727 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003729 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003730 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003731 default:
3732 case GUARD_INTERVAL_AUTO:
3733 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3734 /* fall through , try first guess DRX_GUARD_1DIV4 */
3735 case GUARD_INTERVAL_1_4:
3736 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003737 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003738 case GUARD_INTERVAL_1_32:
3739 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003740 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003741 case GUARD_INTERVAL_1_16:
3742 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003743 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003744 case GUARD_INTERVAL_1_8:
3745 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003746 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003747 }
3748
3749 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003750 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003751 case HIERARCHY_AUTO:
3752 case HIERARCHY_NONE:
3753 default:
3754 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3755 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3756 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3757 /* break; */
3758 case HIERARCHY_1:
3759 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3760 break;
3761 case HIERARCHY_2:
3762 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3763 break;
3764 case HIERARCHY_4:
3765 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3766 break;
3767 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768
3769
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003770 /* modulation */
3771 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003772 case QAM_AUTO:
3773 default:
3774 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3775 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3776 case QAM_64:
3777 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3778 break;
3779 case QPSK:
3780 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3781 break;
3782 case QAM_16:
3783 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3784 break;
3785 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003787 /* No hierachical channels support in BDA */
3788 /* Priority (only for hierarchical channels) */
3789 switch (channel->priority) {
3790 case DRX_PRIORITY_LOW:
3791 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3792 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3793 OFDM_EC_SB_PRIOR_LO);
3794 break;
3795 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003796 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003797 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3798 OFDM_EC_SB_PRIOR_HI));
3799 break;
3800 case DRX_PRIORITY_UNKNOWN: /* fall through */
3801 default:
3802 status = -EINVAL;
3803 goto error;
3804 }
3805#else
3806 /* Set Priorty high */
3807 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3808 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3809 if (status < 0)
3810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811#endif
3812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003814 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 case FEC_AUTO:
3816 default:
3817 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3818 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3819 case FEC_2_3:
3820 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3821 break;
3822 case FEC_1_2:
3823 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3824 break;
3825 case FEC_3_4:
3826 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3827 break;
3828 case FEC_5_6:
3829 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3830 break;
3831 case FEC_7_8:
3832 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3833 break;
3834 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003835
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003836 /* SAW filter selection: normaly not necesarry, but if wanted
3837 the application can select a SAW filter via the driver by using UIOs */
3838 /* First determine real bandwidth (Hz) */
3839 /* Also set delay for impulse noise cruncher */
3840 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3841 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3842 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003843 switch (state->props.bandwidth_hz) {
3844 case 0:
3845 state->props.bandwidth_hz = 8000000;
3846 /* fall though */
3847 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003848 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3849 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003850 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003851 goto error;
3852 /* cochannel protection for PAL 8 MHz */
3853 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3854 if (status < 0)
3855 goto error;
3856 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3857 if (status < 0)
3858 goto error;
3859 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3860 if (status < 0)
3861 goto error;
3862 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3863 if (status < 0)
3864 goto error;
3865 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003866 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003867 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3868 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3869 if (status < 0)
3870 goto error;
3871 /* cochannel protection for PAL 7 MHz */
3872 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3873 if (status < 0)
3874 goto error;
3875 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3876 if (status < 0)
3877 goto error;
3878 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3879 if (status < 0)
3880 goto error;
3881 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3882 if (status < 0)
3883 goto error;
3884 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003885 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3887 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3888 if (status < 0)
3889 goto error;
3890 /* cochannel protection for NTSC 6 MHz */
3891 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3892 if (status < 0)
3893 goto error;
3894 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3895 if (status < 0)
3896 goto error;
3897 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3898 if (status < 0)
3899 goto error;
3900 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3901 if (status < 0)
3902 goto error;
3903 break;
3904 default:
3905 status = -EINVAL;
3906 goto error;
3907 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003908
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003909 if (iqmRcRateOfs == 0) {
3910 /* Now compute IQM_RC_RATE_OFS
3911 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3912 =>
3913 ((SysFreq / BandWidth) * (2^21)) - (2^23)
3914 */
3915 /* (SysFreq / BandWidth) * (2^28) */
3916 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3917 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3918 => assert(109714272 > 48000000) = true so Frac 28 can be used */
3919 iqmRcRateOfs = Frac28a((u32)
3920 ((state->m_sysClockFreq *
3921 1000) / 3), bandwidth);
3922 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3923 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
3924 iqmRcRateOfs += 0x80L;
3925 iqmRcRateOfs = iqmRcRateOfs >> 7;
3926 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
3927 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
3928 }
3929
3930 iqmRcRateOfs &=
3931 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3932 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
3933 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
3934 if (status < 0)
3935 goto error;
3936
3937 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003938
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003939#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003940 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
3941 if (status < 0)
3942 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003943#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003944 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
3945 if (status < 0)
3946 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003947
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003948 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003950 /* Activate SCU to enable SCU commands */
3951 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3952 if (status < 0)
3953 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003955 /* Enable SC after setting all other parameters */
3956 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
3957 if (status < 0)
3958 goto error;
3959 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
3960 if (status < 0)
3961 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003962
3963
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003964 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
3965 if (status < 0)
3966 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003967
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003968 /* Write SC parameter registers, set all AUTO flags in operation mode */
3969 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3970 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3971 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3972 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3973 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
3974 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
3975 0, transmissionParams, param1, 0, 0, 0);
3976 if (status < 0)
3977 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003978
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003979 if (!state->m_DRXK_A3_ROM_CODE)
3980 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
3981error:
3982 if (status < 0)
3983 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003984
3985 return status;
3986}
3987
3988
3989/*============================================================================*/
3990
3991/**
3992* \brief Retreive lock status .
3993* \param demod Pointer to demodulator instance.
3994* \param lockStat Pointer to lock status structure.
3995* \return DRXStatus_t.
3996*
3997*/
3998static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
3999{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004000 int status;
4001 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4002 OFDM_SC_RA_RAM_LOCK_FEC__M);
4003 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4004 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004005
Oliver Endrissebc7de22011-07-03 13:49:44 -03004006 u16 ScRaRamLock = 0;
4007 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004008
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004009 dprintk(1, "\n");
4010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004011 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004012 /* driver 0.9.0 */
4013 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004014 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004015 if (status < 0)
4016 goto end;
4017 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4018 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004019
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004020 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004021 if (status < 0)
4022 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023
Oliver Endrissebc7de22011-07-03 13:49:44 -03004024 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4025 *pLockStatus = MPEG_LOCK;
4026 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4027 *pLockStatus = FEC_LOCK;
4028 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4029 *pLockStatus = DEMOD_LOCK;
4030 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4031 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004032end:
4033 if (status < 0)
4034 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004035
Oliver Endrissebc7de22011-07-03 13:49:44 -03004036 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037}
4038
Oliver Endrissebc7de22011-07-03 13:49:44 -03004039static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004040{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004041 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004042 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004044 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 status = CtrlPowerMode(state, &powerMode);
4046 if (status < 0)
4047 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004048
Oliver Endrissebc7de22011-07-03 13:49:44 -03004049 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050}
4051
4052
Oliver Endrissebc7de22011-07-03 13:49:44 -03004053/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004054static int PowerDownQAM(struct drxk_state *state)
4055{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004056 u16 data = 0;
4057 u16 cmdResult;
4058 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004060 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004061 status = read16(state, SCU_COMM_EXEC__A, &data);
4062 if (status < 0)
4063 goto error;
4064 if (data == SCU_COMM_EXEC_ACTIVE) {
4065 /*
4066 STOP demodulator
4067 QAM and HW blocks
4068 */
4069 /* stop all comstate->m_exec */
4070 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004071 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004072 goto error;
4073 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 -03004074 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004075 goto error;
4076 }
4077 /* powerdown AFE */
4078 status = SetIqmAf(state, false);
4079
4080error:
4081 if (status < 0)
4082 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004083
Oliver Endrissebc7de22011-07-03 13:49:44 -03004084 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004086
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087/*============================================================================*/
4088
4089/**
4090* \brief Setup of the QAM Measurement intervals for signal quality
4091* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004092* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004093* \return DRXStatus_t.
4094*
4095* NOTE:
4096* Take into account that for certain settings the errorcounters can overflow.
4097* The implementation does not check this.
4098*
4099*/
4100static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004101 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004102 u32 symbolRate)
4103{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 u32 fecBitsDesired = 0; /* BER accounting period */
4105 u32 fecRsPeriodTotal = 0; /* Total period */
4106 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4107 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004108 int status = 0;
4109
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004110 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004112 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004113 /* fecBitsDesired = symbolRate [kHz] *
4114 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004115 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004116 SyncLoss (== 1) *
4117 ViterbiLoss (==1)
4118 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004119 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004120 case DRX_CONSTELLATION_QAM16:
4121 fecBitsDesired = 4 * symbolRate;
4122 break;
4123 case DRX_CONSTELLATION_QAM32:
4124 fecBitsDesired = 5 * symbolRate;
4125 break;
4126 case DRX_CONSTELLATION_QAM64:
4127 fecBitsDesired = 6 * symbolRate;
4128 break;
4129 case DRX_CONSTELLATION_QAM128:
4130 fecBitsDesired = 7 * symbolRate;
4131 break;
4132 case DRX_CONSTELLATION_QAM256:
4133 fecBitsDesired = 8 * symbolRate;
4134 break;
4135 default:
4136 status = -EINVAL;
4137 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004139 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004140
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004141 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4142 fecBitsDesired *= 500; /* meas. period [ms] */
4143
4144 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4145 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4146 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4147
4148 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4149 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4150 if (fecRsPrescale == 0) {
4151 /* Divide by zero (though impossible) */
4152 status = -EINVAL;
4153 if (status < 0)
4154 goto error;
4155 }
4156 fecRsPeriod =
4157 ((u16) fecRsPeriodTotal +
4158 (fecRsPrescale >> 1)) / fecRsPrescale;
4159
4160 /* write corresponding registers */
4161 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4162 if (status < 0)
4163 goto error;
4164 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4165 if (status < 0)
4166 goto error;
4167 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4168error:
4169 if (status < 0)
4170 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004171 return status;
4172}
4173
Oliver Endrissebc7de22011-07-03 13:49:44 -03004174static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004175{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004176 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004178 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004179 /* QAM Equalizer Setup */
4180 /* Equalizer */
4181 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4182 if (status < 0)
4183 goto error;
4184 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4185 if (status < 0)
4186 goto error;
4187 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4188 if (status < 0)
4189 goto error;
4190 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4191 if (status < 0)
4192 goto error;
4193 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4194 if (status < 0)
4195 goto error;
4196 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4197 if (status < 0)
4198 goto error;
4199 /* Decision Feedback Equalizer */
4200 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4201 if (status < 0)
4202 goto error;
4203 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4204 if (status < 0)
4205 goto error;
4206 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4207 if (status < 0)
4208 goto error;
4209 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4210 if (status < 0)
4211 goto error;
4212 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4213 if (status < 0)
4214 goto error;
4215 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4216 if (status < 0)
4217 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004218
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004219 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4220 if (status < 0)
4221 goto error;
4222 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4223 if (status < 0)
4224 goto error;
4225 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4226 if (status < 0)
4227 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004229 /* QAM Slicer Settings */
4230 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4231 if (status < 0)
4232 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004234 /* QAM Loop Controller Coeficients */
4235 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4236 if (status < 0)
4237 goto error;
4238 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4239 if (status < 0)
4240 goto error;
4241 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4242 if (status < 0)
4243 goto error;
4244 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4245 if (status < 0)
4246 goto error;
4247 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4248 if (status < 0)
4249 goto error;
4250 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4251 if (status < 0)
4252 goto error;
4253 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4254 if (status < 0)
4255 goto error;
4256 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4257 if (status < 0)
4258 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004259
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004260 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4261 if (status < 0)
4262 goto error;
4263 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4264 if (status < 0)
4265 goto error;
4266 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4267 if (status < 0)
4268 goto error;
4269 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4270 if (status < 0)
4271 goto error;
4272 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4273 if (status < 0)
4274 goto error;
4275 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4276 if (status < 0)
4277 goto error;
4278 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4279 if (status < 0)
4280 goto error;
4281 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4294 if (status < 0)
4295 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004296
4297
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004298 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004299
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004300 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4301 if (status < 0)
4302 goto error;
4303 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4304 if (status < 0)
4305 goto error;
4306 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4316 if (status < 0)
4317 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004318
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004319 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4320 if (status < 0)
4321 goto error;
4322 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4323 if (status < 0)
4324 goto error;
4325 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4326 if (status < 0)
4327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004328
4329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004330 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004332 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4333 if (status < 0)
4334 goto error;
4335 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4351 if (status < 0)
4352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004354error:
4355 if (status < 0)
4356 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004357 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004358}
4359
4360/*============================================================================*/
4361
4362/**
4363* \brief QAM32 specific setup
4364* \param demod instance of demod.
4365* \return DRXStatus_t.
4366*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004367static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004368{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004369 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004370
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004371 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004373 /* QAM Equalizer Setup */
4374 /* Equalizer */
4375 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4391 if (status < 0)
4392 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004393
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004394 /* Decision Feedback Equalizer */
4395 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4411 if (status < 0)
4412 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004413
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004414 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4421 if (status < 0)
4422 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004423
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004424 /* QAM Slicer Settings */
4425
4426 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4427 if (status < 0)
4428 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004429
4430
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004431 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004433 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4449 if (status < 0)
4450 goto error;
4451 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4452 if (status < 0)
4453 goto error;
4454 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4455 if (status < 0)
4456 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004458 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4459 if (status < 0)
4460 goto error;
4461 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4462 if (status < 0)
4463 goto error;
4464 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4465 if (status < 0)
4466 goto error;
4467 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4468 if (status < 0)
4469 goto error;
4470 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4471 if (status < 0)
4472 goto error;
4473 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4489 if (status < 0)
4490 goto error;
4491 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4492 if (status < 0)
4493 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004494
4495
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004496 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004498 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4514 if (status < 0)
4515 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004517 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4518 if (status < 0)
4519 goto error;
4520 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4521 if (status < 0)
4522 goto error;
4523 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4524 if (status < 0)
4525 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004526
4527
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004528 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004530 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4549error:
4550 if (status < 0)
4551 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004552 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004553}
4554
4555/*============================================================================*/
4556
4557/**
4558* \brief QAM64 specific setup
4559* \param demod instance of demod.
4560* \return DRXStatus_t.
4561*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004562static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004563{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004564 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004566 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004567 /* QAM Equalizer Setup */
4568 /* Equalizer */
4569 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4585 if (status < 0)
4586 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004587
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004588 /* Decision Feedback Equalizer */
4589 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4590 if (status < 0)
4591 goto error;
4592 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4593 if (status < 0)
4594 goto error;
4595 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4596 if (status < 0)
4597 goto error;
4598 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4605 if (status < 0)
4606 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004607
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004608 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4612 if (status < 0)
4613 goto error;
4614 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4615 if (status < 0)
4616 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004618 /* QAM Slicer Settings */
4619 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4620 if (status < 0)
4621 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004622
4623
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004624 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004625
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004626 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4627 if (status < 0)
4628 goto error;
4629 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4630 if (status < 0)
4631 goto error;
4632 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4633 if (status < 0)
4634 goto error;
4635 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4642 if (status < 0)
4643 goto error;
4644 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4645 if (status < 0)
4646 goto error;
4647 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4648 if (status < 0)
4649 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004651 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4652 if (status < 0)
4653 goto error;
4654 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4655 if (status < 0)
4656 goto error;
4657 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4658 if (status < 0)
4659 goto error;
4660 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4661 if (status < 0)
4662 goto error;
4663 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4664 if (status < 0)
4665 goto error;
4666 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4667 if (status < 0)
4668 goto error;
4669 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4685 if (status < 0)
4686 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004687
4688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004689 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004691 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4692 if (status < 0)
4693 goto error;
4694 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4695 if (status < 0)
4696 goto error;
4697 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4707 if (status < 0)
4708 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004709
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004710 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4711 if (status < 0)
4712 goto error;
4713 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4717 if (status < 0)
4718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004719
4720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004721 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4724 if (status < 0)
4725 goto error;
4726 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4742error:
4743 if (status < 0)
4744 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004745
Oliver Endrissebc7de22011-07-03 13:49:44 -03004746 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004747}
4748
4749/*============================================================================*/
4750
4751/**
4752* \brief QAM128 specific setup
4753* \param demod: instance of demod.
4754* \return DRXStatus_t.
4755*/
4756static int SetQAM128(struct drxk_state *state)
4757{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004758 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004759
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004760 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004761 /* QAM Equalizer Setup */
4762 /* Equalizer */
4763 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4779 if (status < 0)
4780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004782 /* Decision Feedback Equalizer */
4783 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4799 if (status < 0)
4800 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004802 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4809 if (status < 0)
4810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004811
4812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004813 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004815 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4816 if (status < 0)
4817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004818
4819
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004820 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004822 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4823 if (status < 0)
4824 goto error;
4825 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4826 if (status < 0)
4827 goto error;
4828 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4835 if (status < 0)
4836 goto error;
4837 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4838 if (status < 0)
4839 goto error;
4840 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4841 if (status < 0)
4842 goto error;
4843 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4844 if (status < 0)
4845 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004846
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004847 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4848 if (status < 0)
4849 goto error;
4850 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4851 if (status < 0)
4852 goto error;
4853 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4854 if (status < 0)
4855 goto error;
4856 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4857 if (status < 0)
4858 goto error;
4859 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4860 if (status < 0)
4861 goto error;
4862 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4863 if (status < 0)
4864 goto error;
4865 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4866 if (status < 0)
4867 goto error;
4868 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4869 if (status < 0)
4870 goto error;
4871 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4881 if (status < 0)
4882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004883
4884
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004885 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004887 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4897 if (status < 0)
4898 goto error;
4899 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4900 if (status < 0)
4901 goto error;
4902 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4903 if (status < 0)
4904 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004905
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004906 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4907 if (status < 0)
4908 goto error;
4909 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4910 if (status < 0)
4911 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004913 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4914 if (status < 0)
4915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4920 if (status < 0)
4921 goto error;
4922 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
4938error:
4939 if (status < 0)
4940 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004941
Oliver Endrissebc7de22011-07-03 13:49:44 -03004942 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004943}
4944
4945/*============================================================================*/
4946
4947/**
4948* \brief QAM256 specific setup
4949* \param demod: instance of demod.
4950* \return DRXStatus_t.
4951*/
4952static int SetQAM256(struct drxk_state *state)
4953{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004954 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004955
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004956 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004957 /* QAM Equalizer Setup */
4958 /* Equalizer */
4959 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
4975 if (status < 0)
4976 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004977
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004978 /* Decision Feedback Equalizer */
4979 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4995 if (status < 0)
4996 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004997
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004998 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5005 if (status < 0)
5006 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005008 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005010 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5011 if (status < 0)
5012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
5014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005015 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005017 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5036 if (status < 0)
5037 goto error;
5038 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5039 if (status < 0)
5040 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005041
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005042 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5043 if (status < 0)
5044 goto error;
5045 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5046 if (status < 0)
5047 goto error;
5048 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5049 if (status < 0)
5050 goto error;
5051 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5052 if (status < 0)
5053 goto error;
5054 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5073 if (status < 0)
5074 goto error;
5075 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5076 if (status < 0)
5077 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005078
5079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005080 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005082 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5098 if (status < 0)
5099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005101 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5102 if (status < 0)
5103 goto error;
5104 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5105 if (status < 0)
5106 goto error;
5107 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5108 if (status < 0)
5109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005110
5111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005114 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5115 if (status < 0)
5116 goto error;
5117 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5133error:
5134 if (status < 0)
5135 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005136 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005137}
5138
5139
5140/*============================================================================*/
5141/**
5142* \brief Reset QAM block.
5143* \param demod: instance of demod.
5144* \param channel: pointer to channel data.
5145* \return DRXStatus_t.
5146*/
5147static int QAMResetQAM(struct drxk_state *state)
5148{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005149 int status;
5150 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005151
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005152 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005153 /* Stop QAM comstate->m_exec */
5154 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5155 if (status < 0)
5156 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005157
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005158 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5159error:
5160 if (status < 0)
5161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005162 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005163}
5164
5165/*============================================================================*/
5166
5167/**
5168* \brief Set QAM symbolrate.
5169* \param demod: instance of demod.
5170* \param channel: pointer to channel data.
5171* \return DRXStatus_t.
5172*/
5173static int QAMSetSymbolrate(struct drxk_state *state)
5174{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005175 u32 adcFrequency = 0;
5176 u32 symbFreq = 0;
5177 u32 iqmRcRate = 0;
5178 u16 ratesel = 0;
5179 u32 lcSymbRate = 0;
5180 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005182 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005183 /* Select & calculate correct IQM rate */
5184 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5185 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005186 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5187 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005188 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005189 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005190 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005191 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005192 ratesel = 1;
5193 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5194 if (status < 0)
5195 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005196
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005197 /*
5198 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5199 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005200 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005201 if (symbFreq == 0) {
5202 /* Divide by zero */
5203 status = -EINVAL;
5204 goto error;
5205 }
5206 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5207 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5208 (1 << 23);
5209 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5210 if (status < 0)
5211 goto error;
5212 state->m_iqmRcRate = iqmRcRate;
5213 /*
5214 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5215 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005216 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005217 if (adcFrequency == 0) {
5218 /* Divide by zero */
5219 status = -EINVAL;
5220 goto error;
5221 }
5222 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5223 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5224 16);
5225 if (lcSymbRate > 511)
5226 lcSymbRate = 511;
5227 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005229error:
5230 if (status < 0)
5231 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005232 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005233}
5234
5235/*============================================================================*/
5236
5237/**
5238* \brief Get QAM lock status.
5239* \param demod: instance of demod.
5240* \param channel: pointer to channel data.
5241* \return DRXStatus_t.
5242*/
5243
5244static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5245{
5246 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005247 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005249 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005250 *pLockStatus = NOT_LOCKED;
5251 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005252 SCU_RAM_COMMAND_STANDARD_QAM |
5253 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5254 Result);
5255 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005256 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257
5258 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005259 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005260 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005261 /* 0x4000 DEMOD LOCKED */
5262 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005263 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005264 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5265 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005266 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005267 /* 0xC000 NEVER LOCKED */
5268 /* (system will never be able to lock to the signal) */
5269 /* TODO: check this, intermediate & standard specific lock states are not
5270 taken into account here */
5271 *pLockStatus = NEVER_LOCK;
5272 }
5273 return status;
5274}
5275
5276#define QAM_MIRROR__M 0x03
5277#define QAM_MIRROR_NORMAL 0x00
5278#define QAM_MIRRORED 0x01
5279#define QAM_MIRROR_AUTO_ON 0x02
5280#define QAM_LOCKRANGE__M 0x10
5281#define QAM_LOCKRANGE_NORMAL 0x10
5282
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005283static int QAMDemodulatorCommand(struct drxk_state *state,
5284 int numberOfParameters)
5285{
5286 int status;
5287 u16 cmdResult;
5288 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5289
5290 setParamParameters[0] = state->m_Constellation; /* modulation */
5291 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5292
5293 if (numberOfParameters == 2) {
5294 u16 setEnvParameters[1] = { 0 };
5295
5296 if (state->m_OperationMode == OM_QAM_ITU_C)
5297 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5298 else
5299 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5300
5301 status = scu_command(state,
5302 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5303 1, setEnvParameters, 1, &cmdResult);
5304 if (status < 0)
5305 goto error;
5306
5307 status = scu_command(state,
5308 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5309 numberOfParameters, setParamParameters,
5310 1, &cmdResult);
5311 } else if (numberOfParameters == 4) {
5312 if (state->m_OperationMode == OM_QAM_ITU_C)
5313 setParamParameters[2] = QAM_TOP_ANNEX_C;
5314 else
5315 setParamParameters[2] = QAM_TOP_ANNEX_A;
5316
5317 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5318 /* Env parameters */
5319 /* check for LOCKRANGE Extented */
5320 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5321
5322 status = scu_command(state,
5323 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5324 numberOfParameters, setParamParameters,
5325 1, &cmdResult);
5326 } else {
5327 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5328 "count %d\n", numberOfParameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005329 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005330 }
5331
5332error:
5333 if (status < 0)
5334 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5335 status, __func__);
5336 return status;
5337}
5338
Oliver Endrissebc7de22011-07-03 13:49:44 -03005339static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5340 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005341{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005342 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005343 u16 cmdResult;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005344 int qamDemodParamCount = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005345
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005346 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005347 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005348 * STEP 1: reset demodulator
5349 * resets FEC DI and FEC RS
5350 * resets QAM block
5351 * resets SCU variables
5352 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005353 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005355 goto error;
5356 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5357 if (status < 0)
5358 goto error;
5359 status = QAMResetQAM(state);
5360 if (status < 0)
5361 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005363 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005364 * STEP 2: configure demodulator
5365 * -set params; resets IQM,QAM,FEC HW; initializes some
5366 * SCU variables
5367 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005368 status = QAMSetSymbolrate(state);
5369 if (status < 0)
5370 goto error;
5371
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005372 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005373 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005374 case QAM_256:
5375 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5376 break;
5377 case QAM_AUTO:
5378 case QAM_64:
5379 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5380 break;
5381 case QAM_16:
5382 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5383 break;
5384 case QAM_32:
5385 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5386 break;
5387 case QAM_128:
5388 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5389 break;
5390 default:
5391 status = -EINVAL;
5392 break;
5393 }
5394 if (status < 0)
5395 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005396
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005397 /* Use the 4-parameter if it's requested or we're probing for
5398 * the correct command. */
5399 if (state->qam_demod_parameter_count == 4
5400 || !state->qam_demod_parameter_count) {
5401 qamDemodParamCount = 4;
5402 status = QAMDemodulatorCommand(state, qamDemodParamCount);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005403 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005404
5405 /* Use the 2-parameter command if it was requested or if we're
5406 * probing for the correct command and the 4-parameter command
5407 * failed. */
5408 if (state->qam_demod_parameter_count == 2
5409 || (!state->qam_demod_parameter_count && status < 0)) {
5410 qamDemodParamCount = 2;
5411 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5412 }
5413
5414 if (status < 0) {
5415 dprintk(1, "Could not set demodulator parameters. Make "
5416 "sure qam_demod_parameter_count (%d) is correct for "
5417 "your firmware (%s).\n",
5418 state->qam_demod_parameter_count,
5419 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005420 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005421 } else if (!state->qam_demod_parameter_count) {
5422 dprintk(1, "Auto-probing the correct QAM demodulator command "
5423 "parameters was successful - using %d parameters.\n",
5424 qamDemodParamCount);
5425
Mauro Carvalho Chehab7eaf7182012-07-06 14:53:51 -03005426 /*
5427 * One of our commands was successful. We don't need to
5428 * auto-probe anymore, now that we got the correct command.
5429 */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005430 state->qam_demod_parameter_count = qamDemodParamCount;
5431 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005432
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005433 /*
5434 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005435 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005436 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005437#if 0
5438 status = SetFrequency(channel, tunerFreqOffset));
5439 if (status < 0)
5440 goto error;
5441#endif
5442 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5443 if (status < 0)
5444 goto error;
5445
5446 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005447 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005448 if (status < 0)
5449 goto error;
5450
5451 /* Reset default values */
5452 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5453 if (status < 0)
5454 goto error;
5455 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5456 if (status < 0)
5457 goto error;
5458
5459 /* Reset default LC values */
5460 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5461 if (status < 0)
5462 goto error;
5463 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5464 if (status < 0)
5465 goto error;
5466 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5467 if (status < 0)
5468 goto error;
5469 status = write16(state, QAM_LC_MODE__A, 7);
5470 if (status < 0)
5471 goto error;
5472
5473 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5474 if (status < 0)
5475 goto error;
5476 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5477 if (status < 0)
5478 goto error;
5479 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5480 if (status < 0)
5481 goto error;
5482 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5483 if (status < 0)
5484 goto error;
5485 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5486 if (status < 0)
5487 goto error;
5488 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5489 if (status < 0)
5490 goto error;
5491 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5492 if (status < 0)
5493 goto error;
5494 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5507 if (status < 0)
5508 goto error;
5509 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5510 if (status < 0)
5511 goto error;
5512 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5513 if (status < 0)
5514 goto error;
5515 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5516 if (status < 0)
5517 goto error;
5518
5519 /* Mirroring, QAM-block starting point not inverted */
5520 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5521 if (status < 0)
5522 goto error;
5523
5524 /* Halt SCU to enable safe non-atomic accesses */
5525 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5526 if (status < 0)
5527 goto error;
5528
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005529 /* STEP 4: modulation specific setup */
5530 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005531 case QAM_16:
5532 status = SetQAM16(state);
5533 break;
5534 case QAM_32:
5535 status = SetQAM32(state);
5536 break;
5537 case QAM_AUTO:
5538 case QAM_64:
5539 status = SetQAM64(state);
5540 break;
5541 case QAM_128:
5542 status = SetQAM128(state);
5543 break;
5544 case QAM_256:
5545 status = SetQAM256(state);
5546 break;
5547 default:
5548 status = -EINVAL;
5549 break;
5550 }
5551 if (status < 0)
5552 goto error;
5553
5554 /* Activate SCU to enable SCU commands */
5555 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5556 if (status < 0)
5557 goto error;
5558
5559 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005560 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005561 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5562 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5563 if (status < 0)
5564 goto error;
5565
5566 /* Start processes */
5567 status = MPEGTSStart(state);
5568 if (status < 0)
5569 goto error;
5570 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5571 if (status < 0)
5572 goto error;
5573 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5574 if (status < 0)
5575 goto error;
5576 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5577 if (status < 0)
5578 goto error;
5579
5580 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5581 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5582 if (status < 0)
5583 goto error;
5584
5585 /* update global DRXK data container */
5586/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5587
5588error:
5589 if (status < 0)
5590 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005591 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005592}
5593
Oliver Endrissebc7de22011-07-03 13:49:44 -03005594static int SetQAMStandard(struct drxk_state *state,
5595 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005596{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005597 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005598#ifdef DRXK_QAM_TAPS
5599#define DRXK_QAMA_TAPS_SELECT
5600#include "drxk_filters.h"
5601#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005602#endif
5603
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005604 dprintk(1, "\n");
5605
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005606 /* added antenna switch */
5607 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005608
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005609 /* Ensure correct power-up mode */
5610 status = PowerUpQAM(state);
5611 if (status < 0)
5612 goto error;
5613 /* Reset QAM block */
5614 status = QAMResetQAM(state);
5615 if (status < 0)
5616 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005618 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005619
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005620 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5621 if (status < 0)
5622 goto error;
5623 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5624 if (status < 0)
5625 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005627 /* Upload IQM Channel Filter settings by
5628 boot loader from ROM table */
5629 switch (oMode) {
5630 case OM_QAM_ITU_A:
5631 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5632 break;
5633 case OM_QAM_ITU_C:
5634 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 -03005635 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005636 goto error;
5637 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5638 break;
5639 default:
5640 status = -EINVAL;
5641 }
5642 if (status < 0)
5643 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005644
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005645 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5646 if (status < 0)
5647 goto error;
5648 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5649 if (status < 0)
5650 goto error;
5651 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5652 if (status < 0)
5653 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005654
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005655 status = write16(state, IQM_RC_STRETCH__A, 21);
5656 if (status < 0)
5657 goto error;
5658 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5659 if (status < 0)
5660 goto error;
5661 status = write16(state, IQM_AF_CLP_TH__A, 448);
5662 if (status < 0)
5663 goto error;
5664 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5665 if (status < 0)
5666 goto error;
5667 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5668 if (status < 0)
5669 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005670
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005671 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5672 if (status < 0)
5673 goto error;
5674 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5675 if (status < 0)
5676 goto error;
5677 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5678 if (status < 0)
5679 goto error;
5680 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5681 if (status < 0)
5682 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005683
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005684 /* IQM Impulse Noise Processing Unit */
5685 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_CF_DATATH__A, 1000);
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_CF_DET_LCT__A, 0);
5695 if (status < 0)
5696 goto error;
5697 status = write16(state, IQM_CF_WND_LEN__A, 1);
5698 if (status < 0)
5699 goto error;
5700 status = write16(state, IQM_CF_PKDTH__A, 1);
5701 if (status < 0)
5702 goto error;
5703 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5704 if (status < 0)
5705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005707 /* turn on IQMAF. Must be done before setAgc**() */
5708 status = SetIqmAf(state, true);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 /* IQM will not be reset from here, sync ADC and update/init AGC */
5716 status = ADCSynchronization(state);
5717 if (status < 0)
5718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005720 /* Set the FSM step period */
5721 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5722 if (status < 0)
5723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005725 /* Halt SCU to enable safe non-atomic accesses */
5726 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5727 if (status < 0)
5728 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005730 /* No more resets of the IQM, current standard correctly set =>
5731 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005732
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005733 status = InitAGC(state, true);
5734 if (status < 0)
5735 goto error;
5736 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5737 if (status < 0)
5738 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005740 /* Configure AGC's */
5741 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5742 if (status < 0)
5743 goto error;
5744 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5745 if (status < 0)
5746 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005748 /* Activate SCU to enable SCU commands */
5749 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5750error:
5751 if (status < 0)
5752 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005753 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754}
5755
5756static int WriteGPIO(struct drxk_state *state)
5757{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005758 int status;
5759 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005761 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005762 /* stop lock indicator process */
5763 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5764 if (status < 0)
5765 goto error;
5766
5767 /* Write magic word to enable pdr reg write */
5768 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5769 if (status < 0)
5770 goto error;
5771
5772 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005773 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5774 /* write to io pad configuration register - output mode */
5775 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5776 if (status < 0)
5777 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005778
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005779 /* use corresponding bit in io data output registar */
5780 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5781 if (status < 0)
5782 goto error;
5783 if ((state->m_GPIO & 0x0001) == 0)
5784 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5785 else
5786 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5787 /* write back to io data output register */
5788 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5789 if (status < 0)
5790 goto error;
5791 }
5792 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5793 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005794 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005795 if (status < 0)
5796 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005797
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005798 /* use corresponding bit in io data output registar */
5799 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5800 if (status < 0)
5801 goto error;
5802 if ((state->m_GPIO & 0x0002) == 0)
5803 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5804 else
5805 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5806 /* write back to io data output register */
5807 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5808 if (status < 0)
5809 goto error;
5810 }
5811 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5812 /* write to io pad configuration register - output mode */
Antti Palosaari14053442012-05-17 18:26:50 -03005813 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005814 if (status < 0)
5815 goto error;
5816
5817 /* use corresponding bit in io data output registar */
5818 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5819 if (status < 0)
5820 goto error;
5821 if ((state->m_GPIO & 0x0004) == 0)
5822 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5823 else
5824 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5825 /* write back to io data output register */
5826 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5827 if (status < 0)
5828 goto error;
5829 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005830 }
5831 /* Write magic word to disable pdr reg write */
5832 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5833error:
5834 if (status < 0)
5835 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005836 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005837}
5838
5839static int SwitchAntennaToQAM(struct drxk_state *state)
5840{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005841 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005842 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005843
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005844 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005845
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005846 if (!state->antenna_gpio)
5847 return 0;
5848
5849 gpio_state = state->m_GPIO & state->antenna_gpio;
5850
5851 if (state->antenna_dvbt ^ gpio_state) {
5852 /* Antenna is on DVB-T mode. Switch */
5853 if (state->antenna_dvbt)
5854 state->m_GPIO &= ~state->antenna_gpio;
5855 else
5856 state->m_GPIO |= state->antenna_gpio;
5857 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005858 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005859 if (status < 0)
5860 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005861 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005862}
5863
5864static int SwitchAntennaToDVBT(struct drxk_state *state)
5865{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005866 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005867 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005868
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005869 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005870
5871 if (!state->antenna_gpio)
5872 return 0;
5873
5874 gpio_state = state->m_GPIO & state->antenna_gpio;
5875
5876 if (!(state->antenna_dvbt ^ gpio_state)) {
5877 /* Antenna is on DVB-C mode. Switch */
5878 if (state->antenna_dvbt)
5879 state->m_GPIO |= state->antenna_gpio;
5880 else
5881 state->m_GPIO &= ~state->antenna_gpio;
5882 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005883 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005884 if (status < 0)
5885 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886 return status;
5887}
5888
5889
5890static int PowerDownDevice(struct drxk_state *state)
5891{
5892 /* Power down to requested mode */
5893 /* Backup some register settings */
5894 /* Set pins with possible pull-ups connected to them in input mode */
5895 /* Analog power down */
5896 /* ADC power down */
5897 /* Power down device */
5898 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005899
5900 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005901 if (state->m_bPDownOpenBridge) {
5902 /* Open I2C bridge before power down of DRXK */
5903 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005904 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005905 goto error;
5906 }
5907 /* driver 0.9.0 */
5908 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005909 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005910 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005912 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5913 if (status < 0)
5914 goto error;
5915 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5916 if (status < 0)
5917 goto error;
5918 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5919 status = HI_CfgCommand(state);
5920error:
5921 if (status < 0)
5922 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5923
5924 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005925}
5926
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927static int init_drxk(struct drxk_state *state)
5928{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03005929 int status = 0, n = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005930 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005931 u16 driverVersion;
5932
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005933 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005934 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03005935 drxk_i2c_lock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005936 status = PowerUpDevice(state);
5937 if (status < 0)
5938 goto error;
5939 status = DRXX_Open(state);
5940 if (status < 0)
5941 goto error;
5942 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5943 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);
5944 if (status < 0)
5945 goto error;
5946 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5947 if (status < 0)
5948 goto error;
5949 /* TODO is this needed, if yes how much delay in worst case scenario */
5950 msleep(1);
5951 state->m_DRXK_A3_PATCH_CODE = true;
5952 status = GetDeviceCapabilities(state);
5953 if (status < 0)
5954 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005956 /* Bridge delay, uses oscilator clock */
5957 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5958 /* SDA brdige delay */
5959 state->m_HICfgBridgeDelay =
5960 (u16) ((state->m_oscClockFreq / 1000) *
5961 HI_I2C_BRIDGE_DELAY) / 1000;
5962 /* Clipping */
5963 if (state->m_HICfgBridgeDelay >
5964 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03005965 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005966 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
5967 }
5968 /* SCL bridge delay, same as SDA for now */
5969 state->m_HICfgBridgeDelay +=
5970 state->m_HICfgBridgeDelay <<
5971 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005973 status = InitHI(state);
5974 if (status < 0)
5975 goto error;
5976 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005978 if (!(state->m_DRXK_A1_ROM_CODE)
5979 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005981 {
5982 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5983 if (status < 0)
5984 goto error;
5985 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005987 /* disable MPEG port */
5988 status = MPEGTSDisable(state);
5989 if (status < 0)
5990 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005992 /* Stop AUD and SCU */
5993 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5994 if (status < 0)
5995 goto error;
5996 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5997 if (status < 0)
5998 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006000 /* enable token-ring bus through OFDM block for possible ucode upload */
6001 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6002 if (status < 0)
6003 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006005 /* include boot loader section */
6006 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6007 if (status < 0)
6008 goto error;
6009 status = BLChainCmd(state, 0, 6, 100);
6010 if (status < 0)
6011 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006013 if (state->fw) {
6014 status = DownloadMicrocode(state, state->fw->data,
6015 state->fw->size);
6016 if (status < 0)
6017 goto error;
6018 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006020 /* disable token-ring bus through OFDM block for possible ucode upload */
6021 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6022 if (status < 0)
6023 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006024
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 /* Run SCU for a little while to initialize microcode version numbers */
6026 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6027 if (status < 0)
6028 goto error;
6029 status = DRXX_Open(state);
6030 if (status < 0)
6031 goto error;
6032 /* added for test */
6033 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 powerMode = DRXK_POWER_DOWN_OFDM;
6036 status = CtrlPowerMode(state, &powerMode);
6037 if (status < 0)
6038 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006039
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006040 /* Stamp driver version number in SCU data RAM in BCD code
6041 Done to enable field application engineers to retreive drxdriver version
6042 via I2C from SCU RAM.
6043 Not using SCU command interface for SCU register access since no
6044 microcode may be present.
6045 */
6046 driverVersion =
6047 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6048 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6049 ((DRXK_VERSION_MAJOR % 10) << 4) +
6050 (DRXK_VERSION_MINOR % 10);
6051 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6052 if (status < 0)
6053 goto error;
6054 driverVersion =
6055 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6056 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6057 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6058 (DRXK_VERSION_PATCH % 10);
6059 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6064 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6065 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006067 /* Dirty fix of default values for ROM/PATCH microcode
6068 Dirty because this fix makes it impossible to setup suitable values
6069 before calling DRX_Open. This solution requires changes to RF AGC speed
6070 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006071
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006072 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006073
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006074 /* Reset driver debug flags to 0 */
6075 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6076 if (status < 0)
6077 goto error;
6078 /* driver 0.9.0 */
6079 /* Setup FEC OC:
6080 NOTE: No more full FEC resets allowed afterwards!! */
6081 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6082 if (status < 0)
6083 goto error;
6084 /* MPEGTS functions are still the same */
6085 status = MPEGTSDtoInit(state);
6086 if (status < 0)
6087 goto error;
6088 status = MPEGTSStop(state);
6089 if (status < 0)
6090 goto error;
6091 status = MPEGTSConfigurePolarity(state);
6092 if (status < 0)
6093 goto error;
6094 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6095 if (status < 0)
6096 goto error;
6097 /* added: configure GPIO */
6098 status = WriteGPIO(state);
6099 if (status < 0)
6100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006101
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006102 state->m_DrxkState = DRXK_STOPPED;
6103
6104 if (state->m_bPowerDown) {
6105 status = PowerDownDevice(state);
6106 if (status < 0)
6107 goto error;
6108 state->m_DrxkState = DRXK_POWERED_DOWN;
6109 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006110 state->m_DrxkState = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006111
6112 /* Initialize the supported delivery systems */
6113 n = 0;
6114 if (state->m_hasDVBC) {
6115 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6116 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6117 strlcat(state->frontend.ops.info.name, " DVB-C",
6118 sizeof(state->frontend.ops.info.name));
6119 }
6120 if (state->m_hasDVBT) {
6121 state->frontend.ops.delsys[n++] = SYS_DVBT;
6122 strlcat(state->frontend.ops.info.name, " DVB-T",
6123 sizeof(state->frontend.ops.info.name));
6124 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006125 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006127error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006128 if (status < 0) {
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006129 state->m_DrxkState = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006130 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006131 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006132 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006134 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006135}
6136
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006137static void load_firmware_cb(const struct firmware *fw,
6138 void *context)
6139{
6140 struct drxk_state *state = context;
6141
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006142 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006143 if (!fw) {
6144 printk(KERN_ERR
6145 "drxk: Could not load firmware file %s.\n",
6146 state->microcode_name);
6147 printk(KERN_INFO
6148 "drxk: Copy %s to your hotplug directory!\n",
6149 state->microcode_name);
6150 state->microcode_name = NULL;
6151
6152 /*
6153 * As firmware is now load asynchronous, it is not possible
6154 * anymore to fail at frontend attach. We might silently
6155 * return here, and hope that the driver won't crash.
6156 * We might also change all DVB callbacks to return -ENODEV
6157 * if the device is not initialized.
6158 * As the DRX-K devices have their own internal firmware,
6159 * let's just hope that it will match a firmware revision
6160 * compatible with this driver and proceed.
6161 */
6162 }
6163 state->fw = fw;
6164
6165 init_drxk(state);
6166}
6167
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006168static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006170 struct drxk_state *state = fe->demodulator_priv;
6171
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006172 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006173 if (state->fw)
6174 release_firmware(state->fw);
6175
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176 kfree(state);
6177}
6178
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006179static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006183 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006184
6185 if (state->m_DrxkState == DRXK_NO_DEV)
6186 return -ENODEV;
6187 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6188 return 0;
6189
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191 return 0;
6192}
6193
Oliver Endrissebc7de22011-07-03 13:49:44 -03006194static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195{
6196 struct drxk_state *state = fe->demodulator_priv;
6197
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006198 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006199
6200 if (state->m_DrxkState == DRXK_NO_DEV)
6201 return -ENODEV;
6202
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006203 return ConfigureI2CBridge(state, enable ? true : false);
6204}
6205
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006206static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006207{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006208 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006209 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210 struct drxk_state *state = fe->demodulator_priv;
6211 u32 IF;
6212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006213 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006214
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006215 if (state->m_DrxkState == DRXK_NO_DEV)
6216 return -ENODEV;
6217
6218 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6219 return -EAGAIN;
6220
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006221 if (!fe->ops.tuner_ops.get_if_frequency) {
6222 printk(KERN_ERR
6223 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6224 return -EINVAL;
6225 }
6226
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 if (fe->ops.i2c_gate_ctrl)
6228 fe->ops.i2c_gate_ctrl(fe, 1);
6229 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006230 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 if (fe->ops.i2c_gate_ctrl)
6232 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006233
6234 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006235 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006236
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006237 if (old_delsys != delsys) {
6238 ShutDown(state);
6239 switch (delsys) {
6240 case SYS_DVBC_ANNEX_A:
6241 case SYS_DVBC_ANNEX_C:
6242 if (!state->m_hasDVBC)
6243 return -EINVAL;
6244 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6245 if (state->m_itut_annex_c)
6246 SetOperationMode(state, OM_QAM_ITU_C);
6247 else
6248 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006249 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006250 case SYS_DVBT:
6251 if (!state->m_hasDVBT)
6252 return -EINVAL;
6253 SetOperationMode(state, OM_DVBT);
6254 break;
6255 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006256 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006257 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006258 }
6259
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006260 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006261 Start(state, 0, IF);
6262
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006263 /* After set_frontend, stats aren't avaliable */
6264 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6265 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6266 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6267 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6268 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6269 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6270 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6271 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6272
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006273 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 return 0;
6276}
6277
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006278static int get_strength(struct drxk_state *state, u64 *strength)
6279{
6280 int status;
6281 struct SCfgAgc rfAgc, ifAgc;
6282 u32 totalGain = 0;
6283 u32 atten = 0;
6284 u32 agcRange = 0;
6285 u16 scu_lvl = 0;
6286 u16 scu_coc = 0;
6287 /* FIXME: those are part of the tuner presets */
6288 u16 tunerRfGain = 50; /* Default value on az6007 driver */
6289 u16 tunerIfGain = 40; /* Default value on az6007 driver */
6290
6291 *strength = 0;
6292
6293 if (IsDVBT(state)) {
6294 rfAgc = state->m_dvbtRfAgcCfg;
6295 ifAgc = state->m_dvbtIfAgcCfg;
6296 } else if (IsQAM(state)) {
6297 rfAgc = state->m_qamRfAgcCfg;
6298 ifAgc = state->m_qamIfAgcCfg;
6299 } else {
6300 rfAgc = state->m_atvRfAgcCfg;
6301 ifAgc = state->m_atvIfAgcCfg;
6302 }
6303
6304 if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6305 /* SCU outputLevel */
6306 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6307 if (status < 0)
6308 return status;
6309
6310 /* SCU c.o.c. */
6311 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6312 if (status < 0)
6313 return status;
6314
6315 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6316 rfAgc.outputLevel = scu_lvl + scu_coc;
6317 else
6318 rfAgc.outputLevel = 0xffff;
6319
6320 /* Take RF gain into account */
6321 totalGain += tunerRfGain;
6322
6323 /* clip output value */
6324 if (rfAgc.outputLevel < rfAgc.minOutputLevel)
6325 rfAgc.outputLevel = rfAgc.minOutputLevel;
6326 if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
6327 rfAgc.outputLevel = rfAgc.maxOutputLevel;
6328
6329 agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
6330 if (agcRange > 0) {
6331 atten += 100UL *
6332 ((u32)(tunerRfGain)) *
6333 ((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
6334 / agcRange;
6335 }
6336 }
6337
6338 if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
6339 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6340 &ifAgc.outputLevel);
6341 if (status < 0)
6342 return status;
6343
6344 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6345 &ifAgc.top);
6346 if (status < 0)
6347 return status;
6348
6349 /* Take IF gain into account */
6350 totalGain += (u32) tunerIfGain;
6351
6352 /* clip output value */
6353 if (ifAgc.outputLevel < ifAgc.minOutputLevel)
6354 ifAgc.outputLevel = ifAgc.minOutputLevel;
6355 if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
6356 ifAgc.outputLevel = ifAgc.maxOutputLevel;
6357
6358 agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
6359 if (agcRange > 0) {
6360 atten += 100UL *
6361 ((u32)(tunerIfGain)) *
6362 ((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
6363 / agcRange;
6364 }
6365 }
6366
6367 /*
6368 * Convert to 0..65535 scale.
6369 * If it can't be measured (AGC is disabled), just show 100%.
6370 */
6371 if (totalGain > 0)
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006372 *strength = (65535UL * atten / totalGain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006373 else
6374 *strength = 65535;
6375
6376 return 0;
6377}
6378
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006379static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006380{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006381 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006382 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006383 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006384 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006385 u16 reg16;
6386 u32 post_bit_count;
6387 u32 post_bit_err_count;
6388 u32 post_bit_error_scale;
6389 u32 pre_bit_err_count;
6390 u32 pre_bit_count;
6391 u32 pkt_count;
6392 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006393 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006394
6395 if (state->m_DrxkState == DRXK_NO_DEV)
6396 return -ENODEV;
6397 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6398 return -EAGAIN;
6399
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006400 /* get status */
6401 state->fe_status = 0;
Jean Delvarea3ad56d2013-03-20 12:43:21 +00006402 GetLockStatus(state, &stat);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006403 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006404 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006405 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006406 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006407 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006408 state->fe_status |= 0x07;
6409
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006410 /*
6411 * Estimate signal strength from AGC
6412 */
6413 get_strength(state, &c->strength.stat[0].uvalue);
6414 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6415
6416
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006417 if (stat >= DEMOD_LOCK) {
6418 GetSignalToNoise(state, &cnr);
6419 c->cnr.stat[0].svalue = cnr * 100;
6420 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6421 } else {
6422 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6423 }
6424
6425 if (stat < FEC_LOCK) {
6426 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6427 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6428 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6429 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6430 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6431 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6432 return 0;
6433 }
6434
6435 /* Get post BER */
6436
6437 /* BER measurement is valid if at least FEC lock is achieved */
6438
6439 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6440 to set nr of symbols or bits over which
6441 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6442
6443 /* Read registers for post/preViterbi BER calculation */
6444 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6445 if (status < 0)
6446 goto error;
6447 pre_bit_err_count = reg16;
6448
6449 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6450 if (status < 0)
6451 goto error;
6452 pre_bit_count = reg16;
6453
6454 /* Number of bit-errors */
6455 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6456 if (status < 0)
6457 goto error;
6458 post_bit_err_count = reg16;
6459
6460 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6461 if (status < 0)
6462 goto error;
6463 post_bit_error_scale = reg16;
6464
6465 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6466 if (status < 0)
6467 goto error;
6468 pkt_count = reg16;
6469
6470 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6471 if (status < 0)
6472 goto error;
6473 pkt_error_count = reg16;
6474 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6475
6476 post_bit_err_count *= post_bit_error_scale;
6477
6478 post_bit_count = pkt_count * 204 * 8;
6479
6480 /* Store the results */
6481 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6482 c->block_error.stat[0].uvalue += pkt_error_count;
6483 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6484 c->block_count.stat[0].uvalue += pkt_count;
6485
6486 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6487 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6488 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6489 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6490
6491 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6492 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6493 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6494 c->post_bit_count.stat[0].uvalue += post_bit_count;
6495
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006496error:
6497 return status;
6498}
6499
6500
6501static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6502{
6503 struct drxk_state *state = fe->demodulator_priv;
6504 int rc;
6505
6506 dprintk(1, "\n");
6507
6508 rc = drxk_get_stats(fe);
6509 if (rc < 0)
6510 return rc;
6511
6512 *status = state->fe_status;
6513
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006514 return 0;
6515}
6516
Oliver Endrissebc7de22011-07-03 13:49:44 -03006517static int drxk_read_signal_strength(struct dvb_frontend *fe,
6518 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006519{
6520 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006521 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006522
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006523 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006524
6525 if (state->m_DrxkState == DRXK_NO_DEV)
6526 return -ENODEV;
6527 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6528 return -EAGAIN;
6529
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006530 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006531 return 0;
6532}
6533
6534static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6535{
6536 struct drxk_state *state = fe->demodulator_priv;
6537 s32 snr2;
6538
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006539 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006540
6541 if (state->m_DrxkState == DRXK_NO_DEV)
6542 return -ENODEV;
6543 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6544 return -EAGAIN;
6545
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006546 GetSignalToNoise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006547
6548 /* No negative SNR, clip to zero */
6549 if (snr2 < 0)
6550 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006551 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006552 return 0;
6553}
6554
6555static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6556{
6557 struct drxk_state *state = fe->demodulator_priv;
6558 u16 err;
6559
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006560 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006561
6562 if (state->m_DrxkState == DRXK_NO_DEV)
6563 return -ENODEV;
6564 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6565 return -EAGAIN;
6566
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006567 DVBTQAMGetAccPktErr(state, &err);
6568 *ucblocks = (u32) err;
6569 return 0;
6570}
6571
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006572static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006573 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006574{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006575 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006576 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006577
6578 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006579
6580 if (state->m_DrxkState == DRXK_NO_DEV)
6581 return -ENODEV;
6582 if (state->m_DrxkState == DRXK_UNINITIALIZED)
6583 return -EAGAIN;
6584
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006585 switch (p->delivery_system) {
6586 case SYS_DVBC_ANNEX_A:
6587 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006588 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006589 sets->min_delay_ms = 3000;
6590 sets->max_drift = 0;
6591 sets->step_size = 0;
6592 return 0;
6593 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006594 return -EINVAL;
6595 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006596}
6597
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006598static struct dvb_frontend_ops drxk_ops = {
6599 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006600 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006601 .name = "DRXK",
6602 .frequency_min = 47000000,
6603 .frequency_max = 865000000,
6604 /* For DVB-C */
6605 .symbol_rate_min = 870000,
6606 .symbol_rate_max = 11700000,
6607 /* For DVB-T */
6608 .frequency_stepsize = 166667,
6609
6610 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6611 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6612 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6613 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6614 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6615 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6616 },
6617
6618 .release = drxk_release,
6619 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006620 .i2c_gate_ctrl = drxk_gate_ctrl,
6621
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006622 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006623 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006624
6625 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006626 .read_signal_strength = drxk_read_signal_strength,
6627 .read_snr = drxk_read_snr,
6628 .read_ucblocks = drxk_read_ucblocks,
6629};
6630
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006631struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006632 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006633{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006634 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006635 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006636 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006637 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006638
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006639 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006640 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006641 if (!state)
6642 return NULL;
6643
Oliver Endrissebc7de22011-07-03 13:49:44 -03006644 state->i2c = i2c;
6645 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006646 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006647 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006648 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006649 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006650 state->antenna_gpio = config->antenna_gpio;
6651 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006652 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006653 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006654
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006655 if (config->dynamic_clk) {
6656 state->m_DVBTStaticCLK = 0;
6657 state->m_DVBCStaticCLK = 0;
6658 } else {
6659 state->m_DVBTStaticCLK = 1;
6660 state->m_DVBCStaticCLK = 1;
6661 }
6662
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006663
6664 if (config->mpeg_out_clk_strength)
6665 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6666 else
6667 state->m_TSClockkStrength = 0x06;
6668
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006669 if (config->parallel_ts)
6670 state->m_enableParallel = true;
6671 else
6672 state->m_enableParallel = false;
6673
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006674 /* NOTE: as more UIO bits will be used, add them to the mask */
6675 state->UIO_mask = config->antenna_gpio;
6676
6677 /* Default gpio to DVB-C */
6678 if (!state->antenna_dvbt && state->antenna_gpio)
6679 state->m_GPIO |= state->antenna_gpio;
6680 else
6681 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006682
6683 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006684
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006685 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6686 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006687
6688 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006689
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006690 /* Load firmware and initialize DRX-K */
6691 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006692 if (config->load_firmware_sync) {
6693 const struct firmware *fw = NULL;
6694
6695 status = request_firmware(&fw, state->microcode_name,
6696 state->i2c->dev.parent);
6697 if (status < 0)
6698 fw = NULL;
6699 load_firmware_cb(fw, state);
6700 } else {
6701 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006702 state->microcode_name,
6703 state->i2c->dev.parent,
6704 GFP_KERNEL,
6705 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006706 if (status < 0) {
6707 printk(KERN_ERR
6708 "drxk: failed to request a firmware\n");
6709 return NULL;
6710 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006711 }
6712 } else if (init_drxk(state) < 0)
6713 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006714
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006715
6716 /* Initialize stats */
6717 p = &state->frontend.dtv_property_cache;
6718 p->strength.len = 1;
6719 p->cnr.len = 1;
6720 p->block_error.len = 1;
6721 p->block_count.len = 1;
6722 p->pre_bit_error.len = 1;
6723 p->pre_bit_count.len = 1;
6724 p->post_bit_error.len = 1;
6725 p->post_bit_count.len = 1;
6726
6727 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6728 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6729 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6730 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6731 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6732 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6733 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6734 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6735
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006736 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006737 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006738
6739error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006740 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006741 kfree(state);
6742 return NULL;
6743}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006744EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006745
6746MODULE_DESCRIPTION("DRX-K driver");
6747MODULE_AUTHOR("Ralph Metzler");
6748MODULE_LICENSE("GPL");