blob: 082014de6875ed26a800bc15844bde5a0199c7f3 [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
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -030024#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
Ralph Metzler43dd07f2011-07-03 13:42:18 -030026#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/firmware.h>
32#include <linux/i2c.h>
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -030033#include <linux/hardirq.h>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030034#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "drxk.h"
38#include "drxk_hard.h"
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -030039#include "dvb_math.h"
Ralph Metzler43dd07f2011-07-03 13:42:18 -030040
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030041static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
42static int power_down_qam(struct drxk_state *state);
43static int set_dvbt_standard(struct drxk_state *state,
44 enum operation_mode o_mode);
45static int set_qam_standard(struct drxk_state *state,
46 enum operation_mode o_mode);
47static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
48 s32 tuner_freq_offset);
49static int set_dvbt_standard(struct drxk_state *state,
50 enum operation_mode o_mode);
51static int dvbt_start(struct drxk_state *state);
52static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
53 s32 tuner_freq_offset);
54static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
55static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
56static int switch_antenna_to_qam(struct drxk_state *state);
57static int switch_antenna_to_dvbt(struct drxk_state *state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030058
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030059static bool is_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030060{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030061 return state->m_operation_mode == OM_DVBT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030062}
63
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030064static bool is_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030065{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030066 return state->m_operation_mode == OM_QAM_ITU_A ||
67 state->m_operation_mode == OM_QAM_ITU_B ||
68 state->m_operation_mode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030069}
70
Ralph Metzler43dd07f2011-07-03 13:42:18 -030071#define NOA1ROM 0
72
Ralph Metzler43dd07f2011-07-03 13:42:18 -030073#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
74#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
75
76#define DEFAULT_MER_83 165
77#define DEFAULT_MER_93 250
78
79#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
80#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
81#endif
82
83#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
84#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
85#endif
86
Ralph Metzler43dd07f2011-07-03 13:42:18 -030087#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
88#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
89
90#ifndef DRXK_KI_RAGC_ATV
91#define DRXK_KI_RAGC_ATV 4
92#endif
93#ifndef DRXK_KI_IAGC_ATV
94#define DRXK_KI_IAGC_ATV 6
95#endif
96#ifndef DRXK_KI_DAGC_ATV
97#define DRXK_KI_DAGC_ATV 7
98#endif
99
100#ifndef DRXK_KI_RAGC_QAM
101#define DRXK_KI_RAGC_QAM 3
102#endif
103#ifndef DRXK_KI_IAGC_QAM
104#define DRXK_KI_IAGC_QAM 4
105#endif
106#ifndef DRXK_KI_DAGC_QAM
107#define DRXK_KI_DAGC_QAM 7
108#endif
109#ifndef DRXK_KI_RAGC_DVBT
110#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
111#endif
112#ifndef DRXK_KI_IAGC_DVBT
113#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
114#endif
115#ifndef DRXK_KI_DAGC_DVBT
116#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
117#endif
118
119#ifndef DRXK_AGC_DAC_OFFSET
120#define DRXK_AGC_DAC_OFFSET (0x800)
121#endif
122
123#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
124#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
125#endif
126
127#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
128#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
129#endif
130
131#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
132#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
133#endif
134
135#ifndef DRXK_QAM_SYMBOLRATE_MAX
136#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
137#endif
138
139#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
140#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
141#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
142#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
143#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
144#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
145#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
146#define DRXK_BL_ROM_OFFSET_UCODE 0
147
148#define DRXK_BLC_TIMEOUT 100
149
150#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
151#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
152
153#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
154
155#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
156#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
157#endif
158
159#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
160#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
161#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
162#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
163#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300165static unsigned int debug;
166module_param(debug, int, 0644);
167MODULE_PARM_DESC(debug, "enable debug messages");
168
169#define dprintk(level, fmt, arg...) do { \
170if (debug >= level) \
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300171 pr_debug(fmt, ##arg); \
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300172} while (0)
173
174
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300175static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300176{
177 u64 tmp64;
178
Oliver Endrissebc7de22011-07-03 13:49:44 -0300179 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300180 do_div(tmp64, c);
181
182 return (u32) tmp64;
183}
184
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200185static inline u32 Frac28a(u32 a, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300186{
187 int i = 0;
188 u32 Q1 = 0;
189 u32 R0 = 0;
190
Oliver Endrissebc7de22011-07-03 13:49:44 -0300191 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -0300192 Q1 = a / c; /*
193 * integer part, only the 4 least significant
194 * bits will be visible in the result
195 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300196
197 /* division using radix 16, 7 nibbles in the result */
198 for (i = 0; i < 7; i++) {
199 Q1 = (Q1 << 4) | (R0 / c);
200 R0 = (R0 % c) << 4;
201 }
202 /* rounding */
203 if ((R0 >> 3) >= c)
204 Q1++;
205
206 return Q1;
207}
208
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300209static inline u32 log10times100(u32 value)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300210{
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300211 return (100L * intlog10(value)) >> 24;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300212}
213
214/****************************************************************************/
215/* I2C **********************************************************************/
216/****************************************************************************/
217
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300218static int drxk_i2c_lock(struct drxk_state *state)
219{
220 i2c_lock_adapter(state->i2c);
221 state->drxk_i2c_exclusive_lock = true;
222
223 return 0;
224}
225
226static void drxk_i2c_unlock(struct drxk_state *state)
227{
228 if (!state->drxk_i2c_exclusive_lock)
229 return;
230
231 i2c_unlock_adapter(state->i2c);
232 state->drxk_i2c_exclusive_lock = false;
233}
234
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300235static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
236 unsigned len)
237{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300238 if (state->drxk_i2c_exclusive_lock)
239 return __i2c_transfer(state->i2c, msgs, len);
240 else
241 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300242}
243
244static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300245{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300246 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
247 .buf = val, .len = 1}
248 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300249
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300250 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300251}
252
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300253static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300254{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300255 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300256 struct i2c_msg msg = {
257 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300258
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300259 dprintk(3, ":");
260 if (debug > 2) {
261 int i;
262 for (i = 0; i < len; i++)
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300263 pr_cont(" %02x", data[i]);
264 pr_cont("\n");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300265 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300266 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300267 if (status >= 0 && status != 1)
268 status = -EIO;
269
270 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300271 pr_err("i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300272
273 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300274}
275
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300276static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300277 u8 adr, u8 *msg, int len, u8 *answ, int alen)
278{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300279 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300280 struct i2c_msg msgs[2] = {
281 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300282 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300283 {.addr = adr, .flags = I2C_M_RD,
284 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300285 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300286
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300287 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300288 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300289 if (debug > 2)
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300290 pr_cont(": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300291 if (status >= 0)
292 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300293
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300294 pr_err("i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300295 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300296 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300297 if (debug > 2) {
298 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300299 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300300 for (i = 0; i < len; i++)
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300301 pr_cont(" %02x", msg[i]);
302 pr_cont(", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300303 for (i = 0; i < alen; i++)
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300304 pr_cont(" %02x", answ[i]);
305 pr_cont("\n");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300306 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300307 return 0;
308}
309
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300310static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300311{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300312 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300313 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300314
315 if (state->single_master)
316 flags |= 0xC0;
317
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300318 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
319 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
320 mm1[1] = ((reg >> 16) & 0xFF);
321 mm1[2] = ((reg >> 24) & 0xFF) | flags;
322 mm1[3] = ((reg >> 7) & 0xFF);
323 len = 4;
324 } else {
325 mm1[0] = ((reg << 1) & 0xFF);
326 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
327 len = 2;
328 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300329 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300330 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300331 if (status < 0)
332 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300333 if (data)
334 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300335
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336 return 0;
337}
338
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300339static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300340{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300341 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300342}
343
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300344static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300345{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300346 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300347 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300348
349 if (state->single_master)
350 flags |= 0xC0;
351
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300352 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
353 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
354 mm1[1] = ((reg >> 16) & 0xFF);
355 mm1[2] = ((reg >> 24) & 0xFF) | flags;
356 mm1[3] = ((reg >> 7) & 0xFF);
357 len = 4;
358 } else {
359 mm1[0] = ((reg << 1) & 0xFF);
360 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
361 len = 2;
362 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300363 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300364 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300365 if (status < 0)
366 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300367 if (data)
368 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300369 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300370
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300371 return 0;
372}
373
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300374static int read32(struct drxk_state *state, u32 reg, u32 *data)
375{
376 return read32_flags(state, reg, data, 0);
377}
378
379static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300380{
381 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300382
383 if (state->single_master)
384 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300385 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
386 mm[0] = (((reg << 1) & 0xFF) | 0x01);
387 mm[1] = ((reg >> 16) & 0xFF);
388 mm[2] = ((reg >> 24) & 0xFF) | flags;
389 mm[3] = ((reg >> 7) & 0xFF);
390 len = 4;
391 } else {
392 mm[0] = ((reg << 1) & 0xFF);
393 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
394 len = 2;
395 }
396 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300397 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300398
399 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300400 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300401}
402
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300403static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300404{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300405 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300406}
407
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300408static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300409{
410 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300411
412 if (state->single_master)
413 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
415 mm[0] = (((reg << 1) & 0xFF) | 0x01);
416 mm[1] = ((reg >> 16) & 0xFF);
417 mm[2] = ((reg >> 24) & 0xFF) | flags;
418 mm[3] = ((reg >> 7) & 0xFF);
419 len = 4;
420 } else {
421 mm[0] = ((reg << 1) & 0xFF);
422 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
423 len = 2;
424 }
425 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300426 mm[len + 1] = (data >> 8) & 0xff;
427 mm[len + 2] = (data >> 16) & 0xff;
428 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300429 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300430
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300431 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300432}
433
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300434static int write32(struct drxk_state *state, u32 reg, u32 data)
435{
436 return write32_flags(state, reg, data, 0);
437}
438
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300439static int write_block(struct drxk_state *state, u32 address,
440 const int block_size, const u8 p_block[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300441{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300442 int status = 0, blk_size = block_size;
443 u8 flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300444
445 if (state->single_master)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300446 flags |= 0xC0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300447
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300448 while (blk_size > 0) {
449 int chunk = blk_size > state->m_chunk_size ?
450 state->m_chunk_size : blk_size;
451 u8 *adr_buf = &state->chunk[0];
452 u32 adr_length = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300453
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300454 if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
455 adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
456 adr_buf[1] = ((address >> 16) & 0xFF);
457 adr_buf[2] = ((address >> 24) & 0xFF);
458 adr_buf[3] = ((address >> 7) & 0xFF);
459 adr_buf[2] |= flags;
460 adr_length = 4;
461 if (chunk == state->m_chunk_size)
462 chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300463 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300464 adr_buf[0] = ((address << 1) & 0xFF);
465 adr_buf[1] = (((address >> 16) & 0x0F) |
466 ((address >> 18) & 0xF0));
467 adr_length = 2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300468 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300469 memcpy(&state->chunk[adr_length], p_block, chunk);
470 dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300471 if (debug > 1) {
472 int i;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300473 if (p_block)
474 for (i = 0; i < chunk; i++)
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -0300475 pr_cont(" %02x", p_block[i]);
476 pr_cont("\n");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300477 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300478 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300479 &state->chunk[0], chunk + adr_length);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300480 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300481 pr_err("%s: i2c write error at addr 0x%02x\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300482 __func__, address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300483 break;
484 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300485 p_block += chunk;
486 address += (chunk >> 1);
487 blk_size -= chunk;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300488 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300489 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300490}
491
492#ifndef DRXK_MAX_RETRIES_POWERUP
493#define DRXK_MAX_RETRIES_POWERUP 20
494#endif
495
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300496static int power_up_device(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300497{
498 int status;
499 u8 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300500 u16 retry_count = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300501
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300502 dprintk(1, "\n");
503
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300504 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300506 do {
507 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300508 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300509 &data, 1);
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -0300510 usleep_range(10000, 11000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300511 retry_count++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300512 if (status < 0)
513 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300514 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300515 &data);
516 } while (status < 0 &&
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300517 (retry_count < DRXK_MAX_RETRIES_POWERUP));
518 if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300519 goto error;
520 }
521
522 /* Make sure all clk domains are active */
523 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
524 if (status < 0)
525 goto error;
526 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
527 if (status < 0)
528 goto error;
529 /* Enable pll lock tests */
530 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
531 if (status < 0)
532 goto error;
533
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300534 state->m_current_power_mode = DRX_POWER_UP;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300535
536error:
537 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300538 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300539
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300540 return status;
541}
542
543
544static int init_state(struct drxk_state *state)
545{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300546 /*
547 * FIXME: most (all?) of the values bellow should be moved into
548 * struct drxk_config, as they are probably board-specific
549 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300550 u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
551 u32 ul_vsb_if_agc_output_level = 0;
552 u32 ul_vsb_if_agc_min_level = 0;
553 u32 ul_vsb_if_agc_max_level = 0x7FFF;
554 u32 ul_vsb_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300555
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300556 u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
557 u32 ul_vsb_rf_agc_output_level = 0;
558 u32 ul_vsb_rf_agc_min_level = 0;
559 u32 ul_vsb_rf_agc_max_level = 0x7FFF;
560 u32 ul_vsb_rf_agc_speed = 3;
561 u32 ul_vsb_rf_agc_top = 9500;
562 u32 ul_vsb_rf_agc_cut_off_current = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300563
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300564 u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
565 u32 ul_atv_if_agc_output_level = 0;
566 u32 ul_atv_if_agc_min_level = 0;
567 u32 ul_atv_if_agc_max_level = 0;
568 u32 ul_atv_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300569
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300570 u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
571 u32 ul_atv_rf_agc_output_level = 0;
572 u32 ul_atv_rf_agc_min_level = 0;
573 u32 ul_atv_rf_agc_max_level = 0;
574 u32 ul_atv_rf_agc_top = 9500;
575 u32 ul_atv_rf_agc_cut_off_current = 4000;
576 u32 ul_atv_rf_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577
578 u32 ulQual83 = DEFAULT_MER_83;
579 u32 ulQual93 = DEFAULT_MER_93;
580
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300581 u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
582 u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300583
584 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
585 /* io_pad_cfg_mode output mode is drive always */
586 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300587 u32 ul_gpio_cfg = 0x0113;
588 u32 ul_invert_ts_clock = 0;
589 u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
590 u32 ul_dvbt_bitrate = 50000000;
591 u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300592
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300593 u32 ul_insert_rs_byte = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300594
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300595 u32 ul_rf_mirror = 1;
596 u32 ul_power_down = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300597
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300598 dprintk(1, "\n");
599
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300600 state->m_has_lna = false;
601 state->m_has_dvbt = false;
602 state->m_has_dvbc = false;
603 state->m_has_atv = false;
604 state->m_has_oob = false;
605 state->m_has_audio = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300606
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300607 if (!state->m_chunk_size)
608 state->m_chunk_size = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300609
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300610 state->m_osc_clock_freq = 0;
611 state->m_smart_ant_inverted = false;
612 state->m_b_p_down_open_bridge = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300613
614 /* real system clock frequency in kHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300615 state->m_sys_clock_freq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300616 /* Timing div, 250ns/Psys */
617 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300618 state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300619 HI_I2C_DELAY) / 1000;
620 /* Clipping */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300621 if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
622 state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
623 state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300624 /* port/bridge/power down ctrl */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300625 state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300626
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300627 state->m_b_power_down = (ul_power_down != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300628
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300629 state->m_drxk_a3_patch_code = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
631 /* Init AGC and PGA parameters */
632 /* VSB IF */
Mauro Carvalho Chehab949dd082013-04-28 11:47:50 -0300633 state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
634 state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
635 state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
636 state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
637 state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300638 state->m_vsb_pga_cfg = 140;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300639
640 /* VSB RF */
Mauro Carvalho Chehab949dd082013-04-28 11:47:50 -0300641 state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
642 state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
643 state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
644 state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
645 state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
646 state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
647 state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300648 state->m_vsb_pre_saw_cfg.reference = 0x07;
649 state->m_vsb_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300650
651 state->m_Quality83percent = DEFAULT_MER_83;
652 state->m_Quality93percent = DEFAULT_MER_93;
653 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
654 state->m_Quality83percent = ulQual83;
655 state->m_Quality93percent = ulQual93;
656 }
657
658 /* ATV IF */
Mauro Carvalho Chehab949dd082013-04-28 11:47:50 -0300659 state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
660 state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
661 state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
662 state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
663 state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300664
665 /* ATV RF */
Mauro Carvalho Chehab949dd082013-04-28 11:47:50 -0300666 state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
667 state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
668 state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
669 state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
670 state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
671 state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
672 state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300673 state->m_atv_pre_saw_cfg.reference = 0x04;
674 state->m_atv_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300675
676
677 /* DVBT RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300678 state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
679 state->m_dvbt_rf_agc_cfg.output_level = 0;
680 state->m_dvbt_rf_agc_cfg.min_output_level = 0;
681 state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
682 state->m_dvbt_rf_agc_cfg.top = 0x2100;
683 state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
684 state->m_dvbt_rf_agc_cfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300685
686
687 /* DVBT IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300688 state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
689 state->m_dvbt_if_agc_cfg.output_level = 0;
690 state->m_dvbt_if_agc_cfg.min_output_level = 0;
691 state->m_dvbt_if_agc_cfg.max_output_level = 9000;
692 state->m_dvbt_if_agc_cfg.top = 13424;
693 state->m_dvbt_if_agc_cfg.cut_off_current = 0;
694 state->m_dvbt_if_agc_cfg.speed = 3;
695 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
696 state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300697 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300698
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300699 state->m_dvbt_pre_saw_cfg.reference = 4;
700 state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300701
702 /* QAM RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300703 state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
704 state->m_qam_rf_agc_cfg.output_level = 0;
705 state->m_qam_rf_agc_cfg.min_output_level = 6023;
706 state->m_qam_rf_agc_cfg.max_output_level = 27000;
707 state->m_qam_rf_agc_cfg.top = 0x2380;
708 state->m_qam_rf_agc_cfg.cut_off_current = 4000;
709 state->m_qam_rf_agc_cfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300710
711 /* QAM IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300712 state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
713 state->m_qam_if_agc_cfg.output_level = 0;
714 state->m_qam_if_agc_cfg.min_output_level = 0;
715 state->m_qam_if_agc_cfg.max_output_level = 9000;
716 state->m_qam_if_agc_cfg.top = 0x0511;
717 state->m_qam_if_agc_cfg.cut_off_current = 0;
718 state->m_qam_if_agc_cfg.speed = 3;
719 state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
720 state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300721
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300722 state->m_qam_pga_cfg = 140;
723 state->m_qam_pre_saw_cfg.reference = 4;
724 state->m_qam_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300725
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300726 state->m_operation_mode = OM_NONE;
727 state->m_drxk_state = DRXK_UNINITIALIZED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300728
729 /* MPEG output configuration */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300730 state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */
731 state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */
732 state->m_invert_data = false; /* If TRUE; invert DATA signals */
733 state->m_invert_err = false; /* If TRUE; invert ERR signal */
734 state->m_invert_str = false; /* If TRUE; invert STR signals */
735 state->m_invert_val = false; /* If TRUE; invert VAL signals */
736 state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300737
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300738 /* If TRUE; static MPEG clockrate will be used;
739 otherwise clockrate will adapt to the bitrate of the TS */
740
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300741 state->m_dvbt_bitrate = ul_dvbt_bitrate;
742 state->m_dvbc_bitrate = ul_dvbc_bitrate;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300743
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300744 state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300745
746 /* Maximum bitrate in b/s in case static clockrate is selected */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300747 state->m_mpeg_ts_static_bitrate = 19392658;
748 state->m_disable_te_ihandling = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300749
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300750 if (ul_insert_rs_byte)
751 state->m_insert_rs_byte = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300752
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300753 state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
754 if (ul_mpeg_lock_time_out < 10000)
755 state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
756 state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
757 if (ul_demod_lock_time_out < 10000)
758 state->m_demod_lock_time_out = ul_demod_lock_time_out;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300759
Oliver Endrissebc7de22011-07-03 13:49:44 -0300760 /* QAM defaults */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300761 state->m_constellation = DRX_CONSTELLATION_AUTO;
762 state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
763 state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */
764 state->m_fec_rs_prescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300765
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300766 state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
767 state->m_agcfast_clip_ctrl_delay = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300768
Mauro Carvalho Chehab949dd082013-04-28 11:47:50 -0300769 state->m_gpio_cfg = ul_gpio_cfg;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300771 state->m_b_power_down = false;
772 state->m_current_power_mode = DRX_POWER_DOWN;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300773
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300774 state->m_rfmirror = (ul_rf_mirror == 0);
775 state->m_if_agc_pol = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776 return 0;
777}
778
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300779static int drxx_open(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300780{
781 int status = 0;
782 u32 jtag = 0;
783 u16 bid = 0;
784 u16 key = 0;
785
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300786 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300787 /* stop lock indicator process */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -0300788 status = write16(state, SCU_RAM_GPIO__A,
789 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300790 if (status < 0)
791 goto error;
792 /* Check device id */
793 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
794 if (status < 0)
795 goto error;
796 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
797 if (status < 0)
798 goto error;
799 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
800 if (status < 0)
801 goto error;
802 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
803 if (status < 0)
804 goto error;
805 status = write16(state, SIO_TOP_COMM_KEY__A, key);
806error:
807 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300808 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300809 return status;
810}
811
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300812static int get_device_capabilities(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300813{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300814 u16 sio_pdr_ohw_cfg = 0;
815 u32 sio_top_jtagid_lo = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300816 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300817 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300818
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300819 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300821 /* driver 0.9.0 */
822 /* stop lock indicator process */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -0300823 status = write16(state, SCU_RAM_GPIO__A,
824 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300825 if (status < 0)
826 goto error;
Martin Blumenstingl84183662012-10-04 14:22:55 -0300827 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300828 if (status < 0)
829 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300830 status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300831 if (status < 0)
832 goto error;
833 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
834 if (status < 0)
835 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300836
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300837 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300838 case 0:
839 /* ignore (bypass ?) */
840 break;
841 case 1:
842 /* 27 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300843 state->m_osc_clock_freq = 27000;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300844 break;
845 case 2:
846 /* 20.25 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300847 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300848 break;
849 case 3:
850 /* 4 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300851 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300852 break;
853 default:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300854 pr_err("Clock Frequency is unknown\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300855 return -EINVAL;
856 }
857 /*
858 Determine device capabilities
859 Based on pinning v14
860 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300861 status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300862 if (status < 0)
863 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300864
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300865 pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300866
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300867 /* driver 0.9.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300868 switch ((sio_top_jtagid_lo >> 29) & 0xF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300869 case 0:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300870 state->m_device_spin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300871 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300872 break;
873 case 2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300874 state->m_device_spin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300875 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300876 break;
877 case 3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300878 state->m_device_spin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300879 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300880 break;
881 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300882 state->m_device_spin = DRXK_SPIN_UNKNOWN;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300883 status = -EINVAL;
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300884 pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300885 goto error2;
886 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300887 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300888 case 0x13:
889 /* typeId = DRX3913K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300890 state->m_has_lna = false;
891 state->m_has_oob = false;
892 state->m_has_atv = false;
893 state->m_has_audio = false;
894 state->m_has_dvbt = true;
895 state->m_has_dvbc = true;
896 state->m_has_sawsw = true;
897 state->m_has_gpio2 = false;
898 state->m_has_gpio1 = false;
899 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300900 break;
901 case 0x15:
902 /* typeId = DRX3915K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300903 state->m_has_lna = false;
904 state->m_has_oob = false;
905 state->m_has_atv = true;
906 state->m_has_audio = false;
907 state->m_has_dvbt = true;
908 state->m_has_dvbc = false;
909 state->m_has_sawsw = true;
910 state->m_has_gpio2 = true;
911 state->m_has_gpio1 = true;
912 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300913 break;
914 case 0x16:
915 /* typeId = DRX3916K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300916 state->m_has_lna = false;
917 state->m_has_oob = false;
918 state->m_has_atv = true;
919 state->m_has_audio = false;
920 state->m_has_dvbt = true;
921 state->m_has_dvbc = false;
922 state->m_has_sawsw = true;
923 state->m_has_gpio2 = true;
924 state->m_has_gpio1 = true;
925 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300926 break;
927 case 0x18:
928 /* typeId = DRX3918K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300929 state->m_has_lna = false;
930 state->m_has_oob = false;
931 state->m_has_atv = true;
932 state->m_has_audio = true;
933 state->m_has_dvbt = true;
934 state->m_has_dvbc = false;
935 state->m_has_sawsw = true;
936 state->m_has_gpio2 = true;
937 state->m_has_gpio1 = true;
938 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300939 break;
940 case 0x21:
941 /* typeId = DRX3921K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300942 state->m_has_lna = false;
943 state->m_has_oob = false;
944 state->m_has_atv = true;
945 state->m_has_audio = true;
946 state->m_has_dvbt = true;
947 state->m_has_dvbc = true;
948 state->m_has_sawsw = true;
949 state->m_has_gpio2 = true;
950 state->m_has_gpio1 = true;
951 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300952 break;
953 case 0x23:
954 /* typeId = DRX3923K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300955 state->m_has_lna = false;
956 state->m_has_oob = false;
957 state->m_has_atv = true;
958 state->m_has_audio = true;
959 state->m_has_dvbt = true;
960 state->m_has_dvbc = true;
961 state->m_has_sawsw = true;
962 state->m_has_gpio2 = true;
963 state->m_has_gpio1 = true;
964 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300965 break;
966 case 0x25:
967 /* typeId = DRX3925K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300968 state->m_has_lna = false;
969 state->m_has_oob = false;
970 state->m_has_atv = true;
971 state->m_has_audio = true;
972 state->m_has_dvbt = true;
973 state->m_has_dvbc = true;
974 state->m_has_sawsw = true;
975 state->m_has_gpio2 = true;
976 state->m_has_gpio1 = true;
977 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300978 break;
979 case 0x26:
980 /* typeId = DRX3926K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300981 state->m_has_lna = false;
982 state->m_has_oob = false;
983 state->m_has_atv = true;
984 state->m_has_audio = false;
985 state->m_has_dvbt = true;
986 state->m_has_dvbc = true;
987 state->m_has_sawsw = true;
988 state->m_has_gpio2 = true;
989 state->m_has_gpio1 = true;
990 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300991 break;
992 default:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300993 pr_err("DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300994 ((sio_top_jtagid_lo >> 12) & 0xFF));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300995 status = -EINVAL;
996 goto error2;
997 }
998
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300999 pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001000 ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
1001 state->m_osc_clock_freq / 1000,
1002 state->m_osc_clock_freq % 1000);
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001003
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001004error:
1005 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001006 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001007
1008error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001009 return status;
1010}
1011
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001012static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001013{
1014 int status;
1015 bool powerdown_cmd;
1016
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001017 dprintk(1, "\n");
1018
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001019 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001020 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001021 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001022 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001023 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03001024 usleep_range(1000, 2000);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001025
1026 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001027 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001028 ((state->m_hi_cfg_ctrl) &
Oliver Endrissebc7de22011-07-03 13:49:44 -03001029 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1030 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001031 if (powerdown_cmd == false) {
1032 /* Wait until command rdy */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001033 u32 retry_count = 0;
1034 u16 wait_cmd;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001035
1036 do {
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03001037 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001038 retry_count += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001039 status = read16(state, SIO_HI_RA_RAM_CMD__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001040 &wait_cmd);
1041 } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
1042 && (wait_cmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001043 if (status < 0)
1044 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001045 status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001046 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001047error:
1048 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001049 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001050
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001051 return status;
1052}
1053
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001054static int hi_cfg_command(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001055{
1056 int status;
1057
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001058 dprintk(1, "\n");
1059
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001060 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001061
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001062 status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1063 state->m_hi_cfg_timeout);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001064 if (status < 0)
1065 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001066 status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1067 state->m_hi_cfg_ctrl);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001068 if (status < 0)
1069 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001070 status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1071 state->m_hi_cfg_wake_up_key);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001072 if (status < 0)
1073 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001074 status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1075 state->m_hi_cfg_bridge_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001076 if (status < 0)
1077 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001078 status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1079 state->m_hi_cfg_timing_div);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001080 if (status < 0)
1081 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001082 status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1083 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001084 if (status < 0)
1085 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001086 status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001087 if (status < 0)
1088 goto error;
1089
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001090 state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001091error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001092 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001093 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001094 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001095 return status;
1096}
1097
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001098static int init_hi(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001099{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001100 dprintk(1, "\n");
1101
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001102 state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1103 state->m_hi_cfg_timeout = 0x96FF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001104 /* port/bridge/power down ctrl */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001105 state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001106
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001107 return hi_cfg_command(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001108}
1109
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001110static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001111{
1112 int status = -1;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001113 u16 sio_pdr_mclk_cfg = 0;
1114 u16 sio_pdr_mdx_cfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001115 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001116
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001117 dprintk(1, ": mpeg %s, %s mode\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001118 mpeg_enable ? "enable" : "disable",
1119 state->m_enable_parallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001121 /* stop lock indicator process */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001122 status = write16(state, SCU_RAM_GPIO__A,
1123 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001124 if (status < 0)
1125 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001127 /* MPEG TS pad configuration */
Martin Blumenstingl84183662012-10-04 14:22:55 -03001128 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001129 if (status < 0)
1130 goto error;
1131
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001132 if (mpeg_enable == false) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001133 /* Set MPEG TS pads to inputmode */
1134 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1135 if (status < 0)
1136 goto error;
1137 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1138 if (status < 0)
1139 goto error;
1140 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1141 if (status < 0)
1142 goto error;
1143 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1144 if (status < 0)
1145 goto error;
1146 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1150 if (status < 0)
1151 goto error;
1152 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1153 if (status < 0)
1154 goto error;
1155 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1156 if (status < 0)
1157 goto error;
1158 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1159 if (status < 0)
1160 goto error;
1161 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1162 if (status < 0)
1163 goto error;
1164 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1165 if (status < 0)
1166 goto error;
1167 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1168 if (status < 0)
1169 goto error;
1170 } else {
1171 /* Enable MPEG output */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001172 sio_pdr_mdx_cfg =
1173 ((state->m_ts_data_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001174 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001175 sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001176 SIO_PDR_MCLK_CFG_DRIVE__B) |
1177 0x0003);
1178
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001179 status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001180 if (status < 0)
1181 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001182
1183 if (state->enable_merr_cfg)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001184 err_cfg = sio_pdr_mdx_cfg;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001185
1186 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187 if (status < 0)
1188 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001189 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001190 if (status < 0)
1191 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001192
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001193 if (state->m_enable_parallel == true) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001194 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001195 status = write16(state, SIO_PDR_MD1_CFG__A,
1196 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001197 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001198 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001199 status = write16(state, SIO_PDR_MD2_CFG__A,
1200 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001201 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001202 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001203 status = write16(state, SIO_PDR_MD3_CFG__A,
1204 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001205 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001206 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001207 status = write16(state, SIO_PDR_MD4_CFG__A,
1208 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001209 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001210 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001211 status = write16(state, SIO_PDR_MD5_CFG__A,
1212 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001213 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001214 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001215 status = write16(state, SIO_PDR_MD6_CFG__A,
1216 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001217 if (status < 0)
1218 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001219 status = write16(state, SIO_PDR_MD7_CFG__A,
1220 sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001221 if (status < 0)
1222 goto error;
1223 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001224 sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001225 SIO_PDR_MD0_CFG_DRIVE__B)
1226 | 0x0003);
1227 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001228 status = write16(state, SIO_PDR_MD1_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;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001231 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001232 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001233 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001234 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001235 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001236 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001237 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001238 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001239 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001240 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001241 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001242 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001243 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001244 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001245 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001246 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001247 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001248 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001249 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001250 status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001251 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001252 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001253 status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001254 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001255 goto error;
1256 }
1257 /* Enable MB output over MPEG pads and ctl input */
1258 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1259 if (status < 0)
1260 goto error;
1261 /* Write nomagic word to enable pdr reg write */
1262 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1263error:
1264 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001265 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001266 return status;
1267}
1268
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001269static int mpegts_disable(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001270{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001271 dprintk(1, "\n");
1272
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001273 return mpegts_configure_pins(state, false);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001274}
1275
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001276static int bl_chain_cmd(struct drxk_state *state,
1277 u16 rom_offset, u16 nr_of_elements, u32 time_out)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001278{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001279 u16 bl_status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001280 int status;
1281 unsigned long end;
1282
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001283 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001284 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001285 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1286 if (status < 0)
1287 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001288 status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001289 if (status < 0)
1290 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001291 status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001292 if (status < 0)
1293 goto error;
1294 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1295 if (status < 0)
1296 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001297
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001298 end = jiffies + msecs_to_jiffies(time_out);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001299 do {
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03001300 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001301 status = read16(state, SIO_BL_STATUS__A, &bl_status);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001302 if (status < 0)
1303 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001304 } while ((bl_status == 0x1) &&
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001305 ((time_is_after_jiffies(end))));
1306
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001307 if (bl_status == 0x1) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001308 pr_err("SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001309 status = -EINVAL;
1310 goto error2;
1311 }
1312error:
1313 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001314 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001315error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001316 mutex_unlock(&state->mutex);
1317 return status;
1318}
1319
1320
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001321static int download_microcode(struct drxk_state *state,
1322 const u8 p_mc_image[], u32 length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001323{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001324 const u8 *p_src = p_mc_image;
1325 u32 address;
1326 u16 n_blocks;
1327 u16 block_size;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001328 u32 offset = 0;
1329 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001330 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001332 dprintk(1, "\n");
1333
Hans Verkuil5becbc52012-05-14 10:22:58 -03001334 /* down the drain (we don't care about MAGIC_WORD) */
1335#if 0
1336 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001337 drain = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001338#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001339 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001340 offset += sizeof(u16);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001341 n_blocks = (p_src[0] << 8) | p_src[1];
1342 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001343 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001344
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001345 for (i = 0; i < n_blocks; i += 1) {
1346 address = (p_src[0] << 24) | (p_src[1] << 16) |
1347 (p_src[2] << 8) | p_src[3];
1348 p_src += sizeof(u32);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001349 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001350
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001351 block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1352 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001353 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001354
Hans Verkuil5becbc52012-05-14 10:22:58 -03001355#if 0
1356 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001357 flags = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001358#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001359 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001360 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001361
Hans Verkuil5becbc52012-05-14 10:22:58 -03001362#if 0
1363 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001364 block_crc = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001365#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001366 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001367 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001368
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001369 if (offset + block_size > length) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001370 pr_err("Firmware is corrupted.\n");
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001371 return -EINVAL;
1372 }
1373
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001374 status = write_block(state, address, block_size, p_src);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001375 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001376 pr_err("Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001378 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001379 p_src += block_size;
1380 offset += block_size;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001381 }
1382 return status;
1383}
1384
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001385static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001386{
1387 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001388 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001389 u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1390 u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001391 unsigned long end;
1392
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001393 dprintk(1, "\n");
1394
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395 if (enable == false) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001396 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1397 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001398 }
1399
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001400 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001401 if (status >= 0 && data == desired_status) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402 /* tokenring already has correct status */
1403 return status;
1404 }
1405 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001406 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001407
Oliver Endrissebc7de22011-07-03 13:49:44 -03001408 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001409 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001410 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001411 if ((status >= 0 && data == desired_status)
1412 || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001413 break;
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03001414 usleep_range(1000, 2000);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001415 } while (1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001416 if (data != desired_status) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001417 pr_err("SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001418 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419 }
1420 return status;
1421}
1422
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001423static int mpegts_stop(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001424{
1425 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001426 u16 fec_oc_snc_mode = 0;
1427 u16 fec_oc_ipr_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001428
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001429 dprintk(1, "\n");
1430
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001431 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001432 status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001433 if (status < 0)
1434 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001435 fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1436 status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001437 if (status < 0)
1438 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001439
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001440 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001441 status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001442 if (status < 0)
1443 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001444 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1445 status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001446
1447error:
1448 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001449 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001450
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001451 return status;
1452}
1453
1454static int scu_command(struct drxk_state *state,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001455 u16 cmd, u8 parameter_len,
1456 u16 *parameter, u8 result_len, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457{
1458#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1459#error DRXK register mapping no longer compatible with this routine!
1460#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001461 u16 cur_cmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001462 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001463 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 u8 buffer[34];
1465 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001466 const char *p;
1467 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001468
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001469 dprintk(1, "\n");
1470
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001471 if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1472 ((result_len > 0) && (result == NULL))) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001473 pr_err("Error %d on %s\n", status, __func__);
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001474 return status;
1475 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001476
1477 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001478
1479 /* assume that the command register is ready
1480 since it is checked afterwards */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001481 for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001482 buffer[cnt++] = (parameter[ii] & 0xFF);
1483 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1484 }
1485 buffer[cnt++] = (cmd & 0xFF);
1486 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1487
1488 write_block(state, SCU_RAM_PARAM_0__A -
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001489 (parameter_len - 1), cnt, buffer);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001490 /* Wait until SCU has processed command */
1491 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001492 do {
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03001493 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001494 status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001495 if (status < 0)
1496 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001497 } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1498 if (cur_cmd != DRX_SCU_READY) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001499 pr_err("SCU not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001500 status = -EIO;
1501 goto error2;
1502 }
1503 /* read results */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001504 if ((result_len > 0) && (result != NULL)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001505 s16 err;
1506 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001507
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001508 for (ii = result_len - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001509 status = read16(state, SCU_RAM_PARAM_0__A - ii,
1510 &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001511 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001512 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001513 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001515 /* Check if an error was reported by SCU */
1516 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001517 if (err >= 0)
1518 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001519
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001520 /* check for the known error codes */
1521 switch (err) {
1522 case SCU_RESULT_UNKCMD:
1523 p = "SCU_RESULT_UNKCMD";
1524 break;
1525 case SCU_RESULT_UNKSTD:
1526 p = "SCU_RESULT_UNKSTD";
1527 break;
1528 case SCU_RESULT_SIZE:
1529 p = "SCU_RESULT_SIZE";
1530 break;
1531 case SCU_RESULT_INVPAR:
1532 p = "SCU_RESULT_INVPAR";
1533 break;
1534 default: /* Other negative values are errors */
1535 sprintf(errname, "ERROR: %d\n", err);
1536 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001537 }
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001538 pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001539 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1540 status = -EINVAL;
1541 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001542 }
1543
1544error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001545 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001546 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001547error2:
1548 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001549 return status;
1550}
1551
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001552static int set_iqm_af(struct drxk_state *state, bool active)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001553{
1554 u16 data = 0;
1555 int status;
1556
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001557 dprintk(1, "\n");
1558
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001559 /* Configure IQM */
1560 status = read16(state, IQM_AF_STDBY__A, &data);
1561 if (status < 0)
1562 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001564 if (!active) {
1565 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1566 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1567 | IQM_AF_STDBY_STDBY_PD_STANDBY
1568 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1569 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1570 } else {
1571 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1572 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1573 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1574 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1575 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1576 );
1577 }
1578 status = write16(state, IQM_AF_STDBY__A, data);
1579
1580error:
1581 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001582 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001583 return status;
1584}
1585
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001586static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001587{
1588 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001589 u16 sio_cc_pwd_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001590
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001591 dprintk(1, "\n");
1592
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001593 /* Check arguments */
1594 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596
1597 switch (*mode) {
1598 case DRX_POWER_UP:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001599 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001600 break;
1601 case DRXK_POWER_DOWN_OFDM:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001602 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001603 break;
1604 case DRXK_POWER_DOWN_CORE:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001605 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001606 break;
1607 case DRXK_POWER_DOWN_PLL:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001608 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001609 break;
1610 case DRX_POWER_DOWN:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001611 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001612 break;
1613 default:
1614 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001615 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001616 }
1617
1618 /* If already in requested power mode, do nothing */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001619 if (state->m_current_power_mode == *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001620 return 0;
1621
1622 /* For next steps make sure to start from DRX_POWER_UP mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001623 if (state->m_current_power_mode != DRX_POWER_UP) {
1624 status = power_up_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001625 if (status < 0)
1626 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001627 status = dvbt_enable_ofdm_token_ring(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001628 if (status < 0)
1629 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001630 }
1631
1632 if (*mode == DRX_POWER_UP) {
1633 /* Restore analog & pin configuartion */
1634 } else {
1635 /* Power down to requested mode */
1636 /* Backup some register settings */
1637 /* Set pins with possible pull-ups connected
1638 to them in input mode */
1639 /* Analog power down */
1640 /* ADC power down */
1641 /* Power down device */
1642 /* stop all comm_exec */
1643 /* Stop and power down previous standard */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001644 switch (state->m_operation_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001645 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001646 status = mpegts_stop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001647 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001648 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001649 status = power_down_dvbt(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001650 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001651 goto error;
1652 break;
1653 case OM_QAM_ITU_A:
1654 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001655 status = mpegts_stop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001656 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001657 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001658 status = power_down_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001659 if (status < 0)
1660 goto error;
1661 break;
1662 default:
1663 break;
1664 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001665 status = dvbt_enable_ofdm_token_ring(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001666 if (status < 0)
1667 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001668 status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001669 if (status < 0)
1670 goto error;
1671 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1672 if (status < 0)
1673 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001674
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001675 if (*mode != DRXK_POWER_DOWN_OFDM) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001676 state->m_hi_cfg_ctrl |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001677 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001678 status = hi_cfg_command(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001679 if (status < 0)
1680 goto error;
1681 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001682 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001683 state->m_current_power_mode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001684
1685error:
1686 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001687 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001688
Oliver Endrissebc7de22011-07-03 13:49:44 -03001689 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001690}
1691
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001692static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001693{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001694 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1695 u16 cmd_result = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001696 u16 data = 0;
1697 int status;
1698
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001699 dprintk(1, "\n");
1700
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001701 status = read16(state, SCU_COMM_EXEC__A, &data);
1702 if (status < 0)
1703 goto error;
1704 if (data == SCU_COMM_EXEC_ACTIVE) {
1705 /* Send OFDM stop command */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001706 status = scu_command(state,
1707 SCU_RAM_COMMAND_STANDARD_OFDM
1708 | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1709 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001710 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001711 goto error;
1712 /* Send OFDM reset command */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001713 status = scu_command(state,
1714 SCU_RAM_COMMAND_STANDARD_OFDM
1715 | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1716 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001717 if (status < 0)
1718 goto error;
1719 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001721 /* Reset datapath for OFDM, processors first */
1722 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1723 if (status < 0)
1724 goto error;
1725 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1726 if (status < 0)
1727 goto error;
1728 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1729 if (status < 0)
1730 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001731
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001732 /* powerdown AFE */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001733 status = set_iqm_af(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001734 if (status < 0)
1735 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001736
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001737 /* powerdown to OFDM mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001738 if (set_power_mode) {
1739 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001740 if (status < 0)
1741 goto error;
1742 }
1743error:
1744 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001745 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001746 return status;
1747}
1748
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001749static int setoperation_mode(struct drxk_state *state,
1750 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001751{
1752 int status = 0;
1753
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001754 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001755 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001756 Stop and power down previous standard
1757 TODO investigate total power down instead of partial
1758 power down depending on "previous" standard.
1759 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001760
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001761 /* disable HW lock indicator */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03001762 status = write16(state, SCU_RAM_GPIO__A,
1763 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001764 if (status < 0)
1765 goto error;
1766
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001767 /* Device is already at the required mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001768 if (state->m_operation_mode == o_mode)
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001769 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001770
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001771 switch (state->m_operation_mode) {
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001772 /* OM_NONE was added for start up */
1773 case OM_NONE:
1774 break;
1775 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001776 status = mpegts_stop(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001777 if (status < 0)
1778 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001779 status = power_down_dvbt(state, true);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001780 if (status < 0)
1781 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001782 state->m_operation_mode = OM_NONE;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001783 break;
1784 case OM_QAM_ITU_A: /* fallthrough */
1785 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001786 status = mpegts_stop(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001787 if (status < 0)
1788 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001789 status = power_down_qam(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001790 if (status < 0)
1791 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001792 state->m_operation_mode = OM_NONE;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001793 break;
1794 case OM_QAM_ITU_B:
1795 default:
1796 status = -EINVAL;
1797 goto error;
1798 }
1799
1800 /*
1801 Power up new standard
1802 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001803 switch (o_mode) {
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001804 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001805 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001806 state->m_operation_mode = o_mode;
1807 status = set_dvbt_standard(state, o_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001808 if (status < 0)
1809 goto error;
1810 break;
1811 case OM_QAM_ITU_A: /* fallthrough */
1812 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001813 dprintk(1, ": DVB-C Annex %c\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001814 (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1815 state->m_operation_mode = o_mode;
1816 status = set_qam_standard(state, o_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001817 if (status < 0)
1818 goto error;
1819 break;
1820 case OM_QAM_ITU_B:
1821 default:
1822 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001823 }
1824error:
1825 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001826 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001827 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001828}
1829
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001830static int start(struct drxk_state *state, s32 offset_freq,
1831 s32 intermediate_frequency)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001832{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001833 int status = -EINVAL;
1834
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001835 u16 i_freqk_hz;
1836 s32 offsetk_hz = offset_freq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001837
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001838 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001839 if (state->m_drxk_state != DRXK_STOPPED &&
1840 state->m_drxk_state != DRXK_DTV_STARTED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001841 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001842
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001843 state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001844
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001845 if (intermediate_frequency < 0) {
1846 state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1847 intermediate_frequency = -intermediate_frequency;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001848 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001849
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001850 switch (state->m_operation_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001851 case OM_QAM_ITU_A:
1852 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001853 i_freqk_hz = (intermediate_frequency / 1000);
1854 status = set_qam(state, i_freqk_hz, offsetk_hz);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001855 if (status < 0)
1856 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001857 state->m_drxk_state = DRXK_DTV_STARTED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001858 break;
1859 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001860 i_freqk_hz = (intermediate_frequency / 1000);
1861 status = mpegts_stop(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001862 if (status < 0)
1863 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001864 status = set_dvbt(state, i_freqk_hz, offsetk_hz);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001865 if (status < 0)
1866 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001867 status = dvbt_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001868 if (status < 0)
1869 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001870 state->m_drxk_state = DRXK_DTV_STARTED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001871 break;
1872 default:
1873 break;
1874 }
1875error:
1876 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001877 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001878 return status;
1879}
1880
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001881static int shut_down(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001882{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001883 dprintk(1, "\n");
1884
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001885 mpegts_stop(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001886 return 0;
1887}
1888
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001889static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001890{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001891 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001892
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001893 dprintk(1, "\n");
1894
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001895 if (p_lock_status == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001896 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001897
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001898 *p_lock_status = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001899
1900 /* define the SCU command code */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001901 switch (state->m_operation_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001902 case OM_QAM_ITU_A:
1903 case OM_QAM_ITU_B:
1904 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001905 status = get_qam_lock_status(state, p_lock_status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001906 break;
1907 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001908 status = get_dvbt_lock_status(state, p_lock_status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001909 break;
1910 default:
1911 break;
1912 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001913error:
1914 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001915 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001916 return status;
1917}
1918
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001919static int mpegts_start(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001920{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001921 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001922
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001923 u16 fec_oc_snc_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001924
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001925 /* Allow OC to sync again */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001926 status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001927 if (status < 0)
1928 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001929 fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1930 status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001931 if (status < 0)
1932 goto error;
1933 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1934error:
1935 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001936 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001937 return status;
1938}
1939
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001940static int mpegts_dto_init(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001941{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001942 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001943
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001944 dprintk(1, "\n");
1945
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001946 /* Rate integration settings */
1947 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1948 if (status < 0)
1949 goto error;
1950 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1951 if (status < 0)
1952 goto error;
1953 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1954 if (status < 0)
1955 goto error;
1956 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1957 if (status < 0)
1958 goto error;
1959 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1960 if (status < 0)
1961 goto error;
1962 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1963 if (status < 0)
1964 goto error;
1965 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1966 if (status < 0)
1967 goto error;
1968 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1969 if (status < 0)
1970 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001971
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001972 /* Additional configuration */
1973 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
1974 if (status < 0)
1975 goto error;
1976 status = write16(state, FEC_OC_SNC_LWM__A, 2);
1977 if (status < 0)
1978 goto error;
1979 status = write16(state, FEC_OC_SNC_HWM__A, 12);
1980error:
1981 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001982 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001983
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001984 return status;
1985}
1986
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001987static int mpegts_dto_setup(struct drxk_state *state,
1988 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001989{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001990 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001991
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001992 u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */
1993 u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */
1994 u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */
1995 u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */
1996 u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */
1997 u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */
1998 u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */
1999 u16 fec_oc_tmd_mode = 0;
2000 u16 fec_oc_tmd_int_upd_rate = 0;
2001 u32 max_bit_rate = 0;
2002 bool static_clk = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002003
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002004 dprintk(1, "\n");
2005
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002006 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002007 status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002008 if (status < 0)
2009 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002010 status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002011 if (status < 0)
2012 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002013 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2014 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2015 if (state->m_insert_rs_byte == true) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002016 /* enable parity symbol forward */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002017 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002018 /* MVAL disable during parity bytes */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002019 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002020 /* TS burst length to 204 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002021 fec_oc_dto_burst_len = 204;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002022 }
2023
2024 /* Check serial or parrallel output */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002025 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2026 if (state->m_enable_parallel == false) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002027 /* MPEG data output is serial -> set ipr_mode[0] */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002028 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002029 }
2030
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002031 switch (o_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002032 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002033 max_bit_rate = state->m_dvbt_bitrate;
2034 fec_oc_tmd_mode = 3;
2035 fec_oc_rcn_ctl_rate = 0xC00000;
2036 static_clk = state->m_dvbt_static_clk;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002037 break;
2038 case OM_QAM_ITU_A: /* fallthrough */
2039 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002040 fec_oc_tmd_mode = 0x0004;
2041 fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */
2042 max_bit_rate = state->m_dvbc_bitrate;
2043 static_clk = state->m_dvbc_static_clk;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002044 break;
2045 default:
2046 status = -EINVAL;
2047 } /* switch (standard) */
2048 if (status < 0)
2049 goto error;
2050
2051 /* Configure DTO's */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002052 if (static_clk) {
2053 u32 bit_rate = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002054
2055 /* Rational DTO for MCLK source (static MCLK rate),
2056 Dynamic DTO for optimal grouping
2057 (avoid intra-packet gaps),
2058 DTO offset enable to sync TS burst with MSTRT */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002059 fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002060 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002061 fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002062 FEC_OC_FCT_MODE_VIRT_ENA__M);
2063
2064 /* Check user defined bitrate */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002065 bit_rate = max_bit_rate;
2066 if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */
2067 bit_rate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002068 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002069 /* Rational DTO period:
2070 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002071
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002072 result should be floored,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002073 to make sure >= requested bitrate
2074 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002075 fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2076 * 1000) / bit_rate);
2077 if (fec_oc_dto_period <= 2)
2078 fec_oc_dto_period = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002079 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002080 fec_oc_dto_period -= 2;
2081 fec_oc_tmd_int_upd_rate = 8;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002082 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002083 /* (commonAttr->static_clk == false) => dynamic mode */
2084 fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2085 fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2086 fec_oc_tmd_int_upd_rate = 5;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002087 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002088
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002089 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002090 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002091 if (status < 0)
2092 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002093 status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002094 if (status < 0)
2095 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002096 status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002097 if (status < 0)
2098 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002099 status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002100 if (status < 0)
2101 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002102 status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002103 if (status < 0)
2104 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002105 status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002106 if (status < 0)
2107 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002108
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002109 /* Rate integration settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002110 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002111 if (status < 0)
2112 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002113 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2114 fec_oc_tmd_int_upd_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002115 if (status < 0)
2116 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002117 status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002118error:
2119 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002120 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002121 return status;
2122}
2123
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002124static int mpegts_configure_polarity(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002125{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002126 u16 fec_oc_reg_ipr_invert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127
2128 /* Data mask for the output data byte */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002129 u16 invert_data_mask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002130 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2131 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2132 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2133 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002135 dprintk(1, "\n");
2136
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002137 /* Control selective inversion of output bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002138 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2139 if (state->m_invert_data == true)
2140 fec_oc_reg_ipr_invert |= invert_data_mask;
2141 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2142 if (state->m_invert_err == true)
2143 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2144 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2145 if (state->m_invert_str == true)
2146 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2147 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2148 if (state->m_invert_val == true)
2149 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2150 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2151 if (state->m_invert_clk == true)
2152 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002153
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002154 return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002155}
2156
2157#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2158
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002159static int set_agc_rf(struct drxk_state *state,
2160 struct s_cfg_agc *p_agc_cfg, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002161{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002162 int status = -EINVAL;
2163 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002164 struct s_cfg_agc *p_if_agc_settings;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002165
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002166 dprintk(1, "\n");
2167
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002168 if (p_agc_cfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002169 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002170
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002171 switch (p_agc_cfg->ctrl_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002172 case DRXK_AGC_CTRL_AUTO:
2173 /* Enable RF AGC DAC */
2174 status = read16(state, IQM_AF_STDBY__A, &data);
2175 if (status < 0)
2176 goto error;
2177 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2178 status = write16(state, IQM_AF_STDBY__A, data);
2179 if (status < 0)
2180 goto error;
2181 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2182 if (status < 0)
2183 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002184
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002185 /* Enable SCU RF AGC loop */
2186 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002187
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002188 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002189 if (state->m_rf_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002190 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2191 else
2192 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2193 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2194 if (status < 0)
2195 goto error;
2196
2197 /* Set speed (using complementary reduction value) */
2198 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2199 if (status < 0)
2200 goto error;
2201
2202 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002203 data |= (~(p_agc_cfg->speed <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002204 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2205 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2206
2207 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2208 if (status < 0)
2209 goto error;
2210
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002211 if (is_dvbt(state))
2212 p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2213 else if (is_qam(state))
2214 p_if_agc_settings = &state->m_qam_if_agc_cfg;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002215 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002216 p_if_agc_settings = &state->m_atv_if_agc_cfg;
2217 if (p_if_agc_settings == NULL) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002218 status = -EINVAL;
2219 goto error;
2220 }
2221
2222 /* Set TOP, only if IF-AGC is in AUTO mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002223 if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002224 status = write16(state,
2225 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2226 p_agc_cfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002227 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002228 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002230 /* Cut-Off current */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002231 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2232 p_agc_cfg->cut_off_current);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002233 if (status < 0)
2234 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002235
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002236 /* Max. output level */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002237 status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2238 p_agc_cfg->max_output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002239 if (status < 0)
2240 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002241
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002242 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002243
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002244 case DRXK_AGC_CTRL_USER:
2245 /* Enable RF AGC DAC */
2246 status = read16(state, IQM_AF_STDBY__A, &data);
2247 if (status < 0)
2248 goto error;
2249 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2250 status = write16(state, IQM_AF_STDBY__A, data);
2251 if (status < 0)
2252 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002253
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002254 /* Disable SCU RF AGC loop */
2255 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2256 if (status < 0)
2257 goto error;
2258 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002259 if (state->m_rf_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002260 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2261 else
2262 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2263 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2264 if (status < 0)
2265 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002266
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002267 /* SCU c.o.c. to 0, enabling full control range */
2268 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2269 if (status < 0)
2270 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002271
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002272 /* Write value to output pin */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002273 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2274 p_agc_cfg->output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002275 if (status < 0)
2276 goto error;
2277 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002278
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002279 case DRXK_AGC_CTRL_OFF:
2280 /* Disable RF AGC DAC */
2281 status = read16(state, IQM_AF_STDBY__A, &data);
2282 if (status < 0)
2283 goto error;
2284 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2285 status = write16(state, IQM_AF_STDBY__A, data);
2286 if (status < 0)
2287 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002288
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002289 /* Disable SCU RF AGC loop */
2290 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2291 if (status < 0)
2292 goto error;
2293 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2294 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2295 if (status < 0)
2296 goto error;
2297 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 default:
2300 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002301
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002302 }
2303error:
2304 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002305 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002306 return status;
2307}
2308
2309#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2310
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002311static int set_agc_if(struct drxk_state *state,
2312 struct s_cfg_agc *p_agc_cfg, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002313{
2314 u16 data = 0;
2315 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002316 struct s_cfg_agc *p_rf_agc_settings;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002317
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002318 dprintk(1, "\n");
2319
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002320 switch (p_agc_cfg->ctrl_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002321 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002322
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002323 /* Enable IF AGC DAC */
2324 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002325 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002326 goto error;
2327 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2328 status = write16(state, IQM_AF_STDBY__A, data);
2329 if (status < 0)
2330 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002332 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2333 if (status < 0)
2334 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002335
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002336 /* Enable SCU IF AGC loop */
2337 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2338
2339 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002340 if (state->m_if_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002341 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2342 else
2343 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2344 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2345 if (status < 0)
2346 goto error;
2347
2348 /* Set speed (using complementary reduction value) */
2349 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2350 if (status < 0)
2351 goto error;
2352 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002353 data |= (~(p_agc_cfg->speed <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002354 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2355 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2356
2357 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2358 if (status < 0)
2359 goto error;
2360
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002361 if (is_qam(state))
2362 p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002363 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002364 p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2365 if (p_rf_agc_settings == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002366 return -1;
2367 /* Restore TOP */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002368 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2369 p_rf_agc_settings->top);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002370 if (status < 0)
2371 goto error;
2372 break;
2373
2374 case DRXK_AGC_CTRL_USER:
2375
2376 /* Enable IF AGC DAC */
2377 status = read16(state, IQM_AF_STDBY__A, &data);
2378 if (status < 0)
2379 goto error;
2380 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2381 status = write16(state, IQM_AF_STDBY__A, data);
2382 if (status < 0)
2383 goto error;
2384
2385 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2386 if (status < 0)
2387 goto error;
2388
2389 /* Disable SCU IF AGC loop */
2390 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2391
2392 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002393 if (state->m_if_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002394 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2395 else
2396 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2397 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2398 if (status < 0)
2399 goto error;
2400
2401 /* Write value to output pin */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002402 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2403 p_agc_cfg->output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002404 if (status < 0)
2405 goto error;
2406 break;
2407
2408 case DRXK_AGC_CTRL_OFF:
2409
2410 /* Disable If AGC DAC */
2411 status = read16(state, IQM_AF_STDBY__A, &data);
2412 if (status < 0)
2413 goto error;
2414 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2415 status = write16(state, IQM_AF_STDBY__A, data);
2416 if (status < 0)
2417 goto error;
2418
2419 /* Disable SCU IF AGC loop */
2420 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2421 if (status < 0)
2422 goto error;
2423 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2424 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2425 if (status < 0)
2426 goto error;
2427 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002428 } /* switch (agcSettingsIf->ctrl_mode) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002429
2430 /* always set the top to support
2431 configurations without if-loop */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002432 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002433error:
2434 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002435 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002436 return status;
2437}
2438
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002439static int get_qam_signal_to_noise(struct drxk_state *state,
2440 s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002441{
2442 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002443 u16 qam_sl_err_power = 0; /* accum. error between
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002444 raw and sliced symbols */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002445 u32 qam_sl_sig_power = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002446 QAM modulation */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002447 u32 qam_sl_mer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002448
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002449 dprintk(1, "\n");
2450
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002451 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002452
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002453 /* get the register value needed for MER */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002454 status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002455 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002456 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002457 return -EINVAL;
2458 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002459
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002460 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002461 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002462 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002463 break;
2464 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002465 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002466 break;
2467 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002468 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002469 break;
2470 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002471 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002472 break;
2473 default:
2474 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002475 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002476 break;
2477 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002478
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002479 if (qam_sl_err_power > 0) {
2480 qam_sl_mer = log10times100(qam_sl_sig_power) -
2481 log10times100((u32) qam_sl_err_power);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002482 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002483 *p_signal_to_noise = qam_sl_mer;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002484
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002485 return status;
2486}
2487
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002488static int get_dvbt_signal_to_noise(struct drxk_state *state,
2489 s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002490{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002491 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002492 u16 reg_data = 0;
2493 u32 eq_reg_td_sqr_err_i = 0;
2494 u32 eq_reg_td_sqr_err_q = 0;
2495 u16 eq_reg_td_sqr_err_exp = 0;
2496 u16 eq_reg_td_tps_pwr_ofs = 0;
2497 u16 eq_reg_td_req_smb_cnt = 0;
2498 u32 tps_cnt = 0;
2499 u32 sqr_err_iq = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002500 u32 a = 0;
2501 u32 b = 0;
2502 u32 c = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002503 u32 i_mer = 0;
2504 u16 transmission_params = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002505
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002506 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002508 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2509 &eq_reg_td_tps_pwr_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002510 if (status < 0)
2511 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002512 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2513 &eq_reg_td_req_smb_cnt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002514 if (status < 0)
2515 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002516 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2517 &eq_reg_td_sqr_err_exp);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002518 if (status < 0)
2519 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002520 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2521 &reg_data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002522 if (status < 0)
2523 goto error;
2524 /* Extend SQR_ERR_I operational range */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002525 eq_reg_td_sqr_err_i = (u32) reg_data;
2526 if ((eq_reg_td_sqr_err_exp > 11) &&
2527 (eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2528 eq_reg_td_sqr_err_i += 0x00010000UL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002529 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002530 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002531 if (status < 0)
2532 goto error;
2533 /* Extend SQR_ERR_Q operational range */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002534 eq_reg_td_sqr_err_q = (u32) reg_data;
2535 if ((eq_reg_td_sqr_err_exp > 11) &&
2536 (eq_reg_td_sqr_err_q < 0x00000FFFUL))
2537 eq_reg_td_sqr_err_q += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002538
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002539 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2540 &transmission_params);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002541 if (status < 0)
2542 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002544 /* Check input data for MER */
2545
2546 /* MER calculation (in 0.1 dB) without math.h */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002547 if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2548 i_mer = 0;
2549 else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002550 /* No error at all, this must be the HW reset value
2551 * Apparently no first measurement yet
2552 * Set MER to 0.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002553 i_mer = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002554 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002555 sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2556 eq_reg_td_sqr_err_exp;
2557 if ((transmission_params &
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002558 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2559 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002560 tps_cnt = 17;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002561 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002562 tps_cnt = 68;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002563
2564 /* IMER = 100 * log10 (x)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002565 where x = (eq_reg_td_tps_pwr_ofs^2 *
2566 eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002567
2568 => IMER = a + b -c
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002569 where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2570 b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2571 c = 100 * log10 (sqr_err_iq)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002572 */
2573
2574 /* log(x) x = 9bits * 9bits->18 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002575 a = log10times100(eq_reg_td_tps_pwr_ofs *
2576 eq_reg_td_tps_pwr_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002577 /* log(x) x = 16bits * 7bits->23 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002578 b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002579 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002580 c = log10times100(sqr_err_iq);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002581
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002582 i_mer = a + b - c;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002583 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002584 *p_signal_to_noise = i_mer;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002585
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002586error:
2587 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002588 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002589 return status;
2590}
2591
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002592static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002593{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002594 dprintk(1, "\n");
2595
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002596 *p_signal_to_noise = 0;
2597 switch (state->m_operation_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002598 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002599 return get_dvbt_signal_to_noise(state, p_signal_to_noise);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002600 case OM_QAM_ITU_A:
2601 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002602 return get_qam_signal_to_noise(state, p_signal_to_noise);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002603 default:
2604 break;
2605 }
2606 return 0;
2607}
2608
2609#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002610static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002611{
2612 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2613 int status = 0;
2614
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002615 dprintk(1, "\n");
2616
Oliver Endrissebc7de22011-07-03 13:49:44 -03002617 static s32 QE_SN[] = {
2618 51, /* QPSK 1/2 */
2619 69, /* QPSK 2/3 */
2620 79, /* QPSK 3/4 */
2621 89, /* QPSK 5/6 */
2622 97, /* QPSK 7/8 */
2623 108, /* 16-QAM 1/2 */
2624 131, /* 16-QAM 2/3 */
2625 146, /* 16-QAM 3/4 */
2626 156, /* 16-QAM 5/6 */
2627 160, /* 16-QAM 7/8 */
2628 165, /* 64-QAM 1/2 */
2629 187, /* 64-QAM 2/3 */
2630 202, /* 64-QAM 3/4 */
2631 216, /* 64-QAM 5/6 */
2632 225, /* 64-QAM 7/8 */
2633 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002634
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002635 *p_quality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002636
2637 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002638 s32 signal_to_noise = 0;
2639 u16 constellation = 0;
2640 u16 code_rate = 0;
2641 u32 signal_to_noise_rel;
2642 u32 ber_quality;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002643
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002644 status = get_dvbt_signal_to_noise(state, &signal_to_noise);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002645 if (status < 0)
2646 break;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002647 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2648 &constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002649 if (status < 0)
2650 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002651 constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002652
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002653 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2654 &code_rate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002655 if (status < 0)
2656 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002657 code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002659 if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2660 code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002661 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002662 signal_to_noise_rel = signal_to_noise -
2663 QE_SN[constellation * 5 + code_rate];
2664 ber_quality = 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002665
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002666 if (signal_to_noise_rel < -70)
2667 *p_quality = 0;
2668 else if (signal_to_noise_rel < 30)
2669 *p_quality = ((signal_to_noise_rel + 70) *
2670 ber_quality) / 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002671 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002672 *p_quality = ber_quality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002673 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002674 return 0;
2675};
2676
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002677static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678{
2679 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002680 *p_quality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002681
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002682 dprintk(1, "\n");
2683
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002684 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002685 u32 signal_to_noise = 0;
2686 u32 ber_quality = 100;
2687 u32 signal_to_noise_rel = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002688
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002689 status = get_qam_signal_to_noise(state, &signal_to_noise);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002690 if (status < 0)
2691 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002692
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002693 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002694 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002695 signal_to_noise_rel = signal_to_noise - 200;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002696 break;
2697 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002698 signal_to_noise_rel = signal_to_noise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002699 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002700 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002701 signal_to_noise_rel = signal_to_noise - 260;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002702 break;
2703 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002704 signal_to_noise_rel = signal_to_noise - 290;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002705 break;
2706 default:
2707 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002708 signal_to_noise_rel = signal_to_noise - 320;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002709 break;
2710 }
2711
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002712 if (signal_to_noise_rel < -70)
2713 *p_quality = 0;
2714 else if (signal_to_noise_rel < 30)
2715 *p_quality = ((signal_to_noise_rel + 70) *
2716 ber_quality) / 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002717 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002718 *p_quality = ber_quality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002719 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002720
2721 return status;
2722}
2723
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002724static int get_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002726 dprintk(1, "\n");
2727
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002728 switch (state->m_operation_mode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002729 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002730 return get_dvbt_quality(state, p_quality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002731 case OM_QAM_ITU_A:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002732 return get_dvbc_quality(state, p_quality);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002733 default:
2734 break;
2735 }
2736
2737 return 0;
2738}
2739#endif
2740
2741/* Free data ram in SIO HI */
2742#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2743#define SIO_HI_RA_RAM_USR_END__A 0x420060
2744
2745#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2746#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2747#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2748#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2749
2750#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2751#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2752#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2753
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002754static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002755{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002756 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002758 dprintk(1, "\n");
2759
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002760 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002761 return 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002762 if (state->m_drxk_state == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002763 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002764
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002765 if (state->no_i2c_bridge)
2766 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002768 status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2769 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002770 if (status < 0)
2771 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002772 if (b_enable_bridge) {
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002773 status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2774 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002775 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002776 goto error;
2777 } else {
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03002778 status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2779 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002780 if (status < 0)
2781 goto error;
2782 }
2783
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002784 status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002785
2786error:
2787 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002788 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002789 return status;
2790}
2791
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002792static int set_pre_saw(struct drxk_state *state,
2793 struct s_cfg_pre_saw *p_pre_saw_cfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002795 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002796
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002797 dprintk(1, "\n");
2798
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002799 if ((p_pre_saw_cfg == NULL)
2800 || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002801 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002802
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002803 status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002804error:
2805 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002806 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002807 return status;
2808}
2809
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002810static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2811 u16 rom_offset, u16 nr_of_elements, u32 time_out)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002812{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002813 u16 bl_status = 0;
2814 u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2815 u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002816 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817 unsigned long end;
2818
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002819 dprintk(1, "\n");
2820
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002822 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2823 if (status < 0)
2824 goto error;
2825 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2826 if (status < 0)
2827 goto error;
2828 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2829 if (status < 0)
2830 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002831 status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002832 if (status < 0)
2833 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002834 status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002835 if (status < 0)
2836 goto error;
2837 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2838 if (status < 0)
2839 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002840
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002841 end = jiffies + msecs_to_jiffies(time_out);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002842 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002843 status = read16(state, SIO_BL_STATUS__A, &bl_status);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002844 if (status < 0)
2845 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002846 } while ((bl_status == 0x1) && time_is_after_jiffies(end));
2847 if (bl_status == 0x1) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002848 pr_err("SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002849 status = -EINVAL;
2850 goto error2;
2851 }
2852error:
2853 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002854 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002855error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002856 mutex_unlock(&state->mutex);
2857 return status;
2858
2859}
2860
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002861static int adc_sync_measurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002862{
2863 u16 data = 0;
2864 int status;
2865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002866 dprintk(1, "\n");
2867
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002868 /* start measurement */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002869 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2870 if (status < 0)
2871 goto error;
2872 status = write16(state, IQM_AF_START_LOCK__A, 1);
2873 if (status < 0)
2874 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002875
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002876 *count = 0;
2877 status = read16(state, IQM_AF_PHASE0__A, &data);
2878 if (status < 0)
2879 goto error;
2880 if (data == 127)
2881 *count = *count + 1;
2882 status = read16(state, IQM_AF_PHASE1__A, &data);
2883 if (status < 0)
2884 goto error;
2885 if (data == 127)
2886 *count = *count + 1;
2887 status = read16(state, IQM_AF_PHASE2__A, &data);
2888 if (status < 0)
2889 goto error;
2890 if (data == 127)
2891 *count = *count + 1;
2892
2893error:
2894 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002895 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002896 return status;
2897}
2898
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002899static int adc_synchronization(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002900{
2901 u16 count = 0;
2902 int status;
2903
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002904 dprintk(1, "\n");
2905
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002906 status = adc_sync_measurement(state, &count);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002907 if (status < 0)
2908 goto error;
2909
2910 if (count == 1) {
2911 /* Try sampling on a diffrent edge */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002912 u16 clk_neg = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002913
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002914 status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002915 if (status < 0)
2916 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002917 if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002918 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002919 clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2920 clk_neg |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002921 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2922 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002923 clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2924 clk_neg |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002925 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2926 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002927 status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002928 if (status < 0)
2929 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002930 status = adc_sync_measurement(state, &count);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002931 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002932 goto error;
2933 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002934
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002935 if (count < 2)
2936 status = -EINVAL;
2937error:
2938 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002939 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002940 return status;
2941}
2942
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002943static int set_frequency_shifter(struct drxk_state *state,
2944 u16 intermediate_freqk_hz,
2945 s32 tuner_freq_offset, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002946{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002947 bool select_pos_image = false;
2948 u32 rf_freq_residual = tuner_freq_offset;
2949 u32 fm_frequency_shift = 0;
2950 bool tuner_mirror = !state->m_b_mirror_freq_spect;
2951 u32 adc_freq;
2952 bool adc_flip;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002953 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002954 u32 if_freq_actual;
2955 u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2956 u32 frequency_shift;
2957 bool image_to_select;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002958
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002959 dprintk(1, "\n");
2960
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002961 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002962 Program frequency shifter
2963 No need to account for mirroring on RF
2964 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002965 if (is_dtv) {
2966 if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2967 (state->m_operation_mode == OM_QAM_ITU_C) ||
2968 (state->m_operation_mode == OM_DVBT))
2969 select_pos_image = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002970 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002971 select_pos_image = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002972 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002973 if (tuner_mirror)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002974 /* tuner doesn't mirror */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002975 if_freq_actual = intermediate_freqk_hz +
2976 rf_freq_residual + fm_frequency_shift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002977 else
2978 /* tuner mirrors */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002979 if_freq_actual = intermediate_freqk_hz -
2980 rf_freq_residual - fm_frequency_shift;
2981 if (if_freq_actual > sampling_frequency / 2) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002982 /* adc mirrors */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002983 adc_freq = sampling_frequency - if_freq_actual;
2984 adc_flip = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002985 } else {
2986 /* adc doesn't mirror */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002987 adc_freq = if_freq_actual;
2988 adc_flip = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002989 }
2990
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002991 frequency_shift = adc_freq;
2992 image_to_select = state->m_rfmirror ^ tuner_mirror ^
2993 adc_flip ^ select_pos_image;
2994 state->m_iqm_fs_rate_ofs =
2995 Frac28a((frequency_shift), sampling_frequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002996
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002997 if (image_to_select)
2998 state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002999
3000 /* Program frequency shifter with tuner offset compensation */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003001 /* frequency_shift += tuner_freq_offset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003002 status = write32(state, IQM_FS_RATE_OFS_LO__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003003 state->m_iqm_fs_rate_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003004 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003005 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003006 return status;
3007}
3008
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003009static int init_agc(struct drxk_state *state, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003010{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003011 u16 ingain_tgt = 0;
3012 u16 ingain_tgt_min = 0;
3013 u16 ingain_tgt_max = 0;
3014 u16 clp_cyclen = 0;
3015 u16 clp_sum_min = 0;
3016 u16 clp_dir_to = 0;
3017 u16 sns_sum_min = 0;
3018 u16 sns_sum_max = 0;
3019 u16 clp_sum_max = 0;
3020 u16 sns_dir_to = 0;
3021 u16 ki_innergain_min = 0;
3022 u16 if_iaccu_hi_tgt = 0;
3023 u16 if_iaccu_hi_tgt_min = 0;
3024 u16 if_iaccu_hi_tgt_max = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003025 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003026 u16 fast_clp_ctrl_delay = 0;
3027 u16 clp_ctrl_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003028 int status = 0;
3029
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003030 dprintk(1, "\n");
3031
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003032 /* Common settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003033 sns_sum_max = 1023;
3034 if_iaccu_hi_tgt_min = 2047;
3035 clp_cyclen = 500;
3036 clp_sum_max = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003037
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003038 /* AGCInit() not available for DVBT; init done in microcode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003039 if (!is_qam(state)) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003040 pr_err("%s: mode %d is not DVB-C\n",
3041 __func__, state->m_operation_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003042 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003043 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003044
3045 /* FIXME: Analog TV AGC require different settings */
3046
3047 /* Standard specific settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003048 clp_sum_min = 8;
3049 clp_dir_to = (u16) -9;
3050 clp_ctrl_mode = 0;
3051 sns_sum_min = 8;
3052 sns_dir_to = (u16) -9;
3053 ki_innergain_min = (u16) -1030;
3054 if_iaccu_hi_tgt_max = 0x2380;
3055 if_iaccu_hi_tgt = 0x2380;
3056 ingain_tgt_min = 0x0511;
3057 ingain_tgt = 0x0511;
3058 ingain_tgt_max = 5119;
3059 fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003060
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003061 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3062 fast_clp_ctrl_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003063 if (status < 0)
3064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003065
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003066 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003067 if (status < 0)
3068 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003069 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003070 if (status < 0)
3071 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003072 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003073 if (status < 0)
3074 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003075 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003076 if (status < 0)
3077 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003078 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3079 if_iaccu_hi_tgt_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003080 if (status < 0)
3081 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003082 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3083 if_iaccu_hi_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003084 if (status < 0)
3085 goto error;
3086 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3087 if (status < 0)
3088 goto error;
3089 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3090 if (status < 0)
3091 goto error;
3092 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3093 if (status < 0)
3094 goto error;
3095 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3096 if (status < 0)
3097 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003098 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003099 if (status < 0)
3100 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003101 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003102 if (status < 0)
3103 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003104
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003105 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3106 ki_innergain_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003107 if (status < 0)
3108 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003109 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3110 if_iaccu_hi_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003111 if (status < 0)
3112 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003113 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003114 if (status < 0)
3115 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003117 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3118 if (status < 0)
3119 goto error;
3120 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3121 if (status < 0)
3122 goto error;
3123 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3124 if (status < 0)
3125 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003126
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003127 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3128 if (status < 0)
3129 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003130 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003131 if (status < 0)
3132 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003133 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003134 if (status < 0)
3135 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003136 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003137 if (status < 0)
3138 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003139 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003140 if (status < 0)
3141 goto error;
3142 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3143 if (status < 0)
3144 goto error;
3145 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3146 if (status < 0)
3147 goto error;
3148 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3149 if (status < 0)
3150 goto error;
3151 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3152 if (status < 0)
3153 goto error;
3154 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3155 if (status < 0)
3156 goto error;
3157 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3158 if (status < 0)
3159 goto error;
3160 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3161 if (status < 0)
3162 goto error;
3163 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3164 if (status < 0)
3165 goto error;
3166 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3173 if (status < 0)
3174 goto error;
3175 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3176 if (status < 0)
3177 goto error;
3178 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3179 if (status < 0)
3180 goto error;
3181 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3182 if (status < 0)
3183 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003184
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003185 /* Initialize inner-loop KI gain factors */
3186 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3187 if (status < 0)
3188 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003189
3190 data = 0x0657;
3191 data &= ~SCU_RAM_AGC_KI_RF__M;
3192 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3193 data &= ~SCU_RAM_AGC_KI_IF__M;
3194 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3195
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003196 status = write16(state, SCU_RAM_AGC_KI__A, data);
3197error:
3198 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003199 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003200 return status;
3201}
3202
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003203static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003204{
3205 int status;
3206
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003207 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003208 if (packet_err == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003209 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3210 else
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003211 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3212 packet_err);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003213 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003214 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003215 return status;
3216}
3217
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003218static int dvbt_sc_command(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003219 u16 cmd, u16 subcmd,
3220 u16 param0, u16 param1, u16 param2,
3221 u16 param3, u16 param4)
3222{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003223 u16 cur_cmd = 0;
3224 u16 err_code = 0;
3225 u16 retry_cnt = 0;
3226 u16 sc_exec = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003227 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003228
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003229 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003230 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3231 if (sc_exec != 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003232 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003233 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003234 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003235 if (status < 0)
3236 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237
3238 /* Wait until sc is ready to receive command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003239 retry_cnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003240 do {
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03003241 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003242 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3243 retry_cnt++;
3244 } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3245 if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003246 goto error;
3247
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248 /* Write sub-command */
3249 switch (cmd) {
3250 /* All commands using sub-cmd */
3251 case OFDM_SC_RA_RAM_CMD_PROC_START:
3252 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3253 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003254 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3255 if (status < 0)
3256 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257 break;
3258 default:
3259 /* Do nothing */
3260 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003261 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003262
3263 /* Write needed parameters and the command */
3264 switch (cmd) {
3265 /* All commands using 5 parameters */
3266 /* All commands using 4 parameters */
3267 /* All commands using 3 parameters */
3268 /* All commands using 2 parameters */
3269 case OFDM_SC_RA_RAM_CMD_PROC_START:
3270 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3271 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003272 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003273 /* All commands using 1 parameters */
3274 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3275 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003276 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003277 /* All commands using 0 parameters */
3278 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3279 case OFDM_SC_RA_RAM_CMD_NULL:
3280 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003281 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282 break;
3283 default:
3284 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003285 status = -EINVAL;
3286 }
3287 if (status < 0)
3288 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289
3290 /* Wait until sc is ready processing command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003291 retry_cnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003292 do {
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03003293 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003294 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3295 retry_cnt++;
3296 } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3297 if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003298 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299
3300 /* Check for illegal cmd */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003301 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3302 if (err_code == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003303 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003304 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003305 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003306 if (status < 0)
3307 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003308
3309 /* Retreive results parameters from SC */
3310 switch (cmd) {
3311 /* All commands yielding 5 results */
3312 /* All commands yielding 4 results */
3313 /* All commands yielding 3 results */
3314 /* All commands yielding 2 results */
3315 /* All commands yielding 1 result */
3316 case OFDM_SC_RA_RAM_CMD_USER_IO:
3317 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003318 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003319 /* All commands yielding 0 results */
3320 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3321 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3322 case OFDM_SC_RA_RAM_CMD_PROC_START:
3323 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3324 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3325 case OFDM_SC_RA_RAM_CMD_NULL:
3326 break;
3327 default:
3328 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003329 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003330 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003331 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003332error:
3333 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003334 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003335 return status;
3336}
3337
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003338static int power_up_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003340 enum drx_power_mode power_mode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003341 int status;
3342
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003343 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003344 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003345 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003346 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 return status;
3348}
3349
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003350static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003351{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003352 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003353
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003354 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003355 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003356 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003357 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003358 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003360 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003361 return status;
3362}
3363
3364#define DEFAULT_FR_THRES_8K 4000
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003365static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003366{
3367
3368 int status;
3369
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003370 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003371 if (*enabled == true) {
3372 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003373 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003374 DEFAULT_FR_THRES_8K);
3375 } else {
3376 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003377 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003378 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003379 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003380 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003381
3382 return status;
3383}
3384
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003385static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003386 struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003387{
3388 u16 data = 0;
3389 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003390
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003391 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003392 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3393 if (status < 0)
3394 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003396 switch (echo_thres->fft_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003397 case DRX_FFTMODE_2K:
3398 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003399 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003400 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3401 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003402 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003403 case DRX_FFTMODE_8K:
3404 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003405 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003406 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3407 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003408 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003409 default:
3410 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003411 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003412
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003413 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3414error:
3415 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003416 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003417 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003418}
3419
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003420static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3421 enum drxk_cfg_dvbt_sqi_speed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003422{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003423 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003424
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003425 dprintk(1, "\n");
3426
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003427 switch (*speed) {
3428 case DRXK_DVBT_SQI_SPEED_FAST:
3429 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3430 case DRXK_DVBT_SQI_SPEED_SLOW:
3431 break;
3432 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003433 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003434 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003435 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003436 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003437error:
3438 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003439 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003440 return status;
3441}
3442
3443/*============================================================================*/
3444
3445/**
3446* \brief Activate DVBT specific presets
3447* \param demod instance of demodulator.
3448* \return DRXStatus_t.
3449*
3450* Called in DVBTSetStandard
3451*
3452*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003453static int dvbt_activate_presets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003454{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003455 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003456 bool setincenable = false;
3457 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003458
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003459 struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3460 struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003461
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003462 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003463 status = dvbt_ctrl_set_inc_enable(state, &setincenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003464 if (status < 0)
3465 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003466 status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003467 if (status < 0)
3468 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003469 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003470 if (status < 0)
3471 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003472 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003473 if (status < 0)
3474 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003475 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3476 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003477error:
3478 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003479 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003480 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003482
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003483/*============================================================================*/
3484
3485/**
3486* \brief Initialize channelswitch-independent settings for DVBT.
3487* \param demod instance of demodulator.
3488* \return DRXStatus_t.
3489*
3490* For ROM code channel filter taps are loaded from the bootloader. For microcode
3491* the DVB-T taps from the drxk_filters.h are used.
3492*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003493static int set_dvbt_standard(struct drxk_state *state,
3494 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003495{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003496 u16 cmd_result = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003497 u16 data = 0;
3498 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003499
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003500 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003501
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003502 power_up_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003503 /* added antenna switch */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003504 switch_antenna_to_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003505 /* send OFDM reset command */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003506 status = scu_command(state,
3507 SCU_RAM_COMMAND_STANDARD_OFDM
3508 | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3509 0, NULL, 1, &cmd_result);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003510 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003511 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003512
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003513 /* send OFDM setenv command */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003514 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3515 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3516 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003517 if (status < 0)
3518 goto error;
3519
3520 /* reset datapath for OFDM, processors first */
3521 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3522 if (status < 0)
3523 goto error;
3524 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3525 if (status < 0)
3526 goto error;
3527 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3528 if (status < 0)
3529 goto error;
3530
3531 /* IQM setup */
3532 /* synchronize on ofdstate->m_festart */
3533 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3534 if (status < 0)
3535 goto error;
3536 /* window size for clipping ADC detection */
3537 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3538 if (status < 0)
3539 goto error;
3540 /* window size for for sense pre-SAW detection */
3541 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3542 if (status < 0)
3543 goto error;
3544 /* sense threshold for sense pre-SAW detection */
3545 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3546 if (status < 0)
3547 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003548 status = set_iqm_af(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003549 if (status < 0)
3550 goto error;
3551
3552 status = write16(state, IQM_AF_AGC_RF__A, 0);
3553 if (status < 0)
3554 goto error;
3555
3556 /* Impulse noise cruncher setup */
3557 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3558 if (status < 0)
3559 goto error;
3560 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3561 if (status < 0)
3562 goto error;
3563 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3564 if (status < 0)
3565 goto error;
3566
3567 status = write16(state, IQM_RC_STRETCH__A, 16);
3568 if (status < 0)
3569 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003570 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003571 if (status < 0)
3572 goto error;
3573 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3574 if (status < 0)
3575 goto error;
3576 status = write16(state, IQM_CF_SCALE__A, 1600);
3577 if (status < 0)
3578 goto error;
3579 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3580 if (status < 0)
3581 goto error;
3582
3583 /* virtual clipping threshold for clipping ADC detection */
3584 status = write16(state, IQM_AF_CLP_TH__A, 448);
3585 if (status < 0)
3586 goto error;
3587 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3588 if (status < 0)
3589 goto error;
3590
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003591 status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3592 DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003593 if (status < 0)
3594 goto error;
3595
3596 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3597 if (status < 0)
3598 goto error;
3599 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3600 if (status < 0)
3601 goto error;
3602 /* enable power measurement interrupt */
3603 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3604 if (status < 0)
3605 goto error;
3606 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3607 if (status < 0)
3608 goto error;
3609
3610 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003611 status = adc_synchronization(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003612 if (status < 0)
3613 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003614 status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003615 if (status < 0)
3616 goto error;
3617
3618 /* Halt SCU to enable safe non-atomic accesses */
3619 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3620 if (status < 0)
3621 goto error;
3622
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003623 status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003624 if (status < 0)
3625 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003626 status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003627 if (status < 0)
3628 goto error;
3629
3630 /* Set Noise Estimation notch width and enable DC fix */
3631 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3632 if (status < 0)
3633 goto error;
3634 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3635 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3636 if (status < 0)
3637 goto error;
3638
3639 /* Activate SCU to enable SCU commands */
3640 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3641 if (status < 0)
3642 goto error;
3643
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003644 if (!state->m_drxk_a3_rom_code) {
3645 /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003646 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3647 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003648 if (status < 0)
3649 goto error;
3650 }
3651
3652 /* OFDM_SC setup */
3653#ifdef COMPILE_FOR_NONRT
3654 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3655 if (status < 0)
3656 goto error;
3657 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3658 if (status < 0)
3659 goto error;
3660#endif
3661
3662 /* FEC setup */
3663 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3664 if (status < 0)
3665 goto error;
3666
3667
3668#ifdef COMPILE_FOR_NONRT
3669 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3670 if (status < 0)
3671 goto error;
3672#else
3673 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3674 if (status < 0)
3675 goto error;
3676#endif
3677 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3678 if (status < 0)
3679 goto error;
3680
3681 /* Setup MPEG bus */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003682 status = mpegts_dto_setup(state, OM_DVBT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003683 if (status < 0)
3684 goto error;
3685 /* Set DVBT Presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003686 status = dvbt_activate_presets(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003687 if (status < 0)
3688 goto error;
3689
3690error:
3691 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003692 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003693 return status;
3694}
3695
3696/*============================================================================*/
3697/**
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003698* \brief start dvbt demodulating for channel.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003699* \param demod instance of demodulator.
3700* \return DRXStatus_t.
3701*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003702static int dvbt_start(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003703{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003704 u16 param1;
3705 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003706 /* drxk_ofdm_sc_cmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003707
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003708 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003709 /* start correct processes to get in lock */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003710 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003711 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003712 status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3713 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3714 0, 0, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003715 if (status < 0)
3716 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003717 /* start FEC OC */
3718 status = mpegts_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003719 if (status < 0)
3720 goto error;
3721 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3722 if (status < 0)
3723 goto error;
3724error:
3725 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003726 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003727 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728}
3729
3730
3731/*============================================================================*/
3732
3733/**
3734* \brief Set up dvbt demodulator for channel.
3735* \param demod instance of demodulator.
3736* \return DRXStatus_t.
3737* // original DVBTSetChannel()
3738*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003739static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3740 s32 tuner_freq_offset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003741{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003742 u16 cmd_result = 0;
3743 u16 transmission_params = 0;
3744 u16 operation_mode = 0;
3745 u32 iqm_rc_rate_ofs = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003746 u32 bandwidth = 0;
3747 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003748 int status;
3749
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003750 dprintk(1, "IF =%d, TFO = %d\n",
3751 intermediate_freqk_hz, tuner_freq_offset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003752
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003753 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3754 | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3755 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003756 if (status < 0)
3757 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003758
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003759 /* Halt SCU to enable safe non-atomic accesses */
3760 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3761 if (status < 0)
3762 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003763
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003764 /* Stop processors */
3765 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3766 if (status < 0)
3767 goto error;
3768 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3769 if (status < 0)
3770 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003771
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003772 /* Mandatory fix, always stop CP, required to set spl offset back to
3773 hardware default (is set to 0 by ucode during pilot detection */
3774 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3775 if (status < 0)
3776 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003777
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003778 /*== Write channel settings to device ================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003780 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003781 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003782 case TRANSMISSION_MODE_AUTO:
3783 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003784 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003785 /* fall through , try first guess DRX_FFTMODE_8K */
3786 case TRANSMISSION_MODE_8K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003787 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003788 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003789 case TRANSMISSION_MODE_2K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003790 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003791 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003792 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003795 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 default:
3797 case GUARD_INTERVAL_AUTO:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003798 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 /* fall through , try first guess DRX_GUARD_1DIV4 */
3800 case GUARD_INTERVAL_1_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003801 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003802 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003803 case GUARD_INTERVAL_1_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003804 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003805 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003806 case GUARD_INTERVAL_1_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003807 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003808 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003809 case GUARD_INTERVAL_1_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003810 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003811 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003812 }
3813
3814 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003815 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003816 case HIERARCHY_AUTO:
3817 case HIERARCHY_NONE:
3818 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003819 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003820 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003821 /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003822 /* break; */
3823 case HIERARCHY_1:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003824 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003825 break;
3826 case HIERARCHY_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003827 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 break;
3829 case HIERARCHY_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003830 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003831 break;
3832 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003833
3834
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003835 /* modulation */
3836 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003837 case QAM_AUTO:
3838 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003839 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003840 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3841 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003842 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003843 break;
3844 case QPSK:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003845 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003846 break;
3847 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003848 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 break;
3850 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003851#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 /* No hierachical channels support in BDA */
3853 /* Priority (only for hierarchical channels) */
3854 switch (channel->priority) {
3855 case DRX_PRIORITY_LOW:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003856 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3857 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003858 OFDM_EC_SB_PRIOR_LO);
3859 break;
3860 case DRX_PRIORITY_HIGH:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003861 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3862 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003863 OFDM_EC_SB_PRIOR_HI));
3864 break;
3865 case DRX_PRIORITY_UNKNOWN: /* fall through */
3866 default:
3867 status = -EINVAL;
3868 goto error;
3869 }
3870#else
3871 /* Set Priorty high */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003872 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003873 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3874 if (status < 0)
3875 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003876#endif
3877
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003878 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003879 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003880 case FEC_AUTO:
3881 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003882 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003883 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3884 case FEC_2_3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003885 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 break;
3887 case FEC_1_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003888 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003889 break;
3890 case FEC_3_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003891 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003892 break;
3893 case FEC_5_6:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003894 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003895 break;
3896 case FEC_7_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003897 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003898 break;
3899 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003900
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003901 /*
3902 * SAW filter selection: normaly not necesarry, but if wanted
3903 * the application can select a SAW filter via the driver by
3904 * using UIOs
3905 */
3906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003907 /* First determine real bandwidth (Hz) */
3908 /* Also set delay for impulse noise cruncher */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003909 /*
3910 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3911 * changed by SC for fix for some 8K,1/8 guard but is restored by
3912 * InitEC and ResetEC functions
3913 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003914 switch (state->props.bandwidth_hz) {
3915 case 0:
3916 state->props.bandwidth_hz = 8000000;
3917 /* fall though */
3918 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003919 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003920 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3921 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003922 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003923 goto error;
3924 /* cochannel protection for PAL 8 MHz */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003925 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3926 7);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003927 if (status < 0)
3928 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003929 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3930 7);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003931 if (status < 0)
3932 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003933 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3934 7);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003935 if (status < 0)
3936 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003937 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3938 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003939 if (status < 0)
3940 goto error;
3941 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003942 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003943 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003944 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3945 3491);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003946 if (status < 0)
3947 goto error;
3948 /* cochannel protection for PAL 7 MHz */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003949 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3950 8);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003951 if (status < 0)
3952 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003953 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3954 8);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003955 if (status < 0)
3956 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3958 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003959 if (status < 0)
3960 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003961 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3962 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003963 if (status < 0)
3964 goto error;
3965 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003966 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003967 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003968 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3969 4073);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003970 if (status < 0)
3971 goto error;
3972 /* cochannel protection for NTSC 6 MHz */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3974 19);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003975 if (status < 0)
3976 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003977 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3978 19);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003979 if (status < 0)
3980 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003981 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3982 14);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003983 if (status < 0)
3984 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03003985 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3986 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003987 if (status < 0)
3988 goto error;
3989 break;
3990 default:
3991 status = -EINVAL;
3992 goto error;
3993 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003994
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003995 if (iqm_rc_rate_ofs == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003996 /* Now compute IQM_RC_RATE_OFS
3997 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3998 =>
3999 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4000 */
4001 /* (SysFreq / BandWidth) * (2^28) */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004002 /*
4003 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
4004 * => assert(MAX(sysClk) < 16*MIN(bandwidth))
4005 * => assert(109714272 > 48000000) = true
4006 * so Frac 28 can be used
4007 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004008 iqm_rc_rate_ofs = Frac28a((u32)
4009 ((state->m_sys_clock_freq *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004010 1000) / 3), bandwidth);
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004011 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004012 if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
4013 iqm_rc_rate_ofs += 0x80L;
4014 iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004015 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004016 iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004017 }
4018
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004019 iqm_rc_rate_ofs &=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004020 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4021 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004022 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004023 if (status < 0)
4024 goto error;
4025
4026 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004027
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004028#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004029 status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004030 if (status < 0)
4031 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004032#endif
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004033 status = set_frequency_shifter(state, intermediate_freqk_hz,
4034 tuner_freq_offset, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004035 if (status < 0)
4036 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004038 /*== start SC, write channel settings to SC ==========================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004039
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004040 /* Activate SCU to enable SCU commands */
4041 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4042 if (status < 0)
4043 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004045 /* Enable SC after setting all other parameters */
4046 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4047 if (status < 0)
4048 goto error;
4049 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4050 if (status < 0)
4051 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004052
4053
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004054 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4055 | SCU_RAM_COMMAND_CMD_DEMOD_START,
4056 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004057 if (status < 0)
4058 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004060 /* Write SC parameter registers, set all AUTO flags in operation mode */
4061 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4062 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4063 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4064 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4065 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004066 status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4067 0, transmission_params, param1, 0, 0, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004068 if (status < 0)
4069 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004070
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004071 if (!state->m_drxk_a3_rom_code)
4072 status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004073error:
4074 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004075 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004076
4077 return status;
4078}
4079
4080
4081/*============================================================================*/
4082
4083/**
4084* \brief Retreive lock status .
4085* \param demod Pointer to demodulator instance.
4086* \param lockStat Pointer to lock status structure.
4087* \return DRXStatus_t.
4088*
4089*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004090static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004091{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004092 int status;
4093 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4094 OFDM_SC_RA_RAM_LOCK_FEC__M);
4095 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4096 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004097
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004098 u16 sc_ra_ram_lock = 0;
4099 u16 sc_comm_exec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004100
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004101 dprintk(1, "\n");
4102
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004103 *p_lock_status = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004104 /* driver 0.9.0 */
4105 /* Check if SC is running */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004106 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004107 if (status < 0)
4108 goto end;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004109 if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004110 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004112 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004113 if (status < 0)
4114 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004115
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004116 if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4117 *p_lock_status = MPEG_LOCK;
4118 else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4119 *p_lock_status = FEC_LOCK;
4120 else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4121 *p_lock_status = DEMOD_LOCK;
4122 else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4123 *p_lock_status = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004124end:
4125 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004126 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004127
Oliver Endrissebc7de22011-07-03 13:49:44 -03004128 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004129}
4130
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004131static int power_up_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004132{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004133 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004134 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004135
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004136 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004137 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004138 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004139 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004140
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004142}
4143
4144
Oliver Endrissebc7de22011-07-03 13:49:44 -03004145/** Power Down QAM */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004146static int power_down_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004147{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004148 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004149 u16 cmd_result;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004150 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004151
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004152 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004153 status = read16(state, SCU_COMM_EXEC__A, &data);
4154 if (status < 0)
4155 goto error;
4156 if (data == SCU_COMM_EXEC_ACTIVE) {
4157 /*
4158 STOP demodulator
4159 QAM and HW blocks
4160 */
4161 /* stop all comstate->m_exec */
4162 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004163 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004164 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004165 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4166 | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4167 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004168 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004169 goto error;
4170 }
4171 /* powerdown AFE */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004172 status = set_iqm_af(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004173
4174error:
4175 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004176 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177
Oliver Endrissebc7de22011-07-03 13:49:44 -03004178 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004179}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004180
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004181/*============================================================================*/
4182
4183/**
4184* \brief Setup of the QAM Measurement intervals for signal quality
4185* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004186* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004187* \return DRXStatus_t.
4188*
4189* NOTE:
4190* Take into account that for certain settings the errorcounters can overflow.
4191* The implementation does not check this.
4192*
4193*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004194static int set_qam_measurement(struct drxk_state *state,
4195 enum e_drxk_constellation modulation,
4196 u32 symbol_rate)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004197{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004198 u32 fec_bits_desired = 0; /* BER accounting period */
4199 u32 fec_rs_period_total = 0; /* Total period */
4200 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
4201 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004202 int status = 0;
4203
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004204 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004205
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004206 fec_rs_prescale = 1;
4207 /* fec_bits_desired = symbol_rate [kHz] *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004208 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004209 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004210 SyncLoss (== 1) *
4211 ViterbiLoss (==1)
4212 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004213 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004214 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004215 fec_bits_desired = 4 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004216 break;
4217 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004218 fec_bits_desired = 5 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004219 break;
4220 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004221 fec_bits_desired = 6 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004222 break;
4223 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004224 fec_bits_desired = 7 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004225 break;
4226 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004227 fec_bits_desired = 8 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004228 break;
4229 default:
4230 status = -EINVAL;
4231 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004232 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004233 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004234
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004235 fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004236 fec_bits_desired *= 500; /* meas. period [ms] */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004237
4238 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004239 /* fec_rs_period_total = fec_bits_desired / 1632 */
4240 fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004241
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004242 /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */
4243 fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4244 if (fec_rs_prescale == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004245 /* Divide by zero (though impossible) */
4246 status = -EINVAL;
4247 if (status < 0)
4248 goto error;
4249 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004250 fec_rs_period =
4251 ((u16) fec_rs_period_total +
4252 (fec_rs_prescale >> 1)) / fec_rs_prescale;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004253
4254 /* write corresponding registers */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004255 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004256 if (status < 0)
4257 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004258 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4259 fec_rs_prescale);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004260 if (status < 0)
4261 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004262 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004263error:
4264 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004265 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004266 return status;
4267}
4268
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004269static int set_qam16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004270{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004271 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004272
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004273 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004274 /* QAM Equalizer Setup */
4275 /* Equalizer */
4276 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4277 if (status < 0)
4278 goto error;
4279 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 /* Decision Feedback Equalizer */
4295 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4296 if (status < 0)
4297 goto error;
4298 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4311 if (status < 0)
4312 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004313
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004314 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4315 if (status < 0)
4316 goto error;
4317 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4321 if (status < 0)
4322 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004323
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004324 /* QAM Slicer Settings */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004325 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4326 DRXK_QAM_SL_SIG_POWER_QAM16);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004327 if (status < 0)
4328 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004330 /* QAM Loop Controller Coeficients */
4331 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4332 if (status < 0)
4333 goto error;
4334 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4335 if (status < 0)
4336 goto error;
4337 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4338 if (status < 0)
4339 goto error;
4340 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4341 if (status < 0)
4342 goto error;
4343 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4344 if (status < 0)
4345 goto error;
4346 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4347 if (status < 0)
4348 goto error;
4349 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4350 if (status < 0)
4351 goto error;
4352 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4353 if (status < 0)
4354 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004355
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004356 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4357 if (status < 0)
4358 goto error;
4359 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4360 if (status < 0)
4361 goto error;
4362 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4363 if (status < 0)
4364 goto error;
4365 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4366 if (status < 0)
4367 goto error;
4368 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4369 if (status < 0)
4370 goto error;
4371 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4372 if (status < 0)
4373 goto error;
4374 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4375 if (status < 0)
4376 goto error;
4377 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4378 if (status < 0)
4379 goto error;
4380 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4381 if (status < 0)
4382 goto error;
4383 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4384 if (status < 0)
4385 goto error;
4386 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4387 if (status < 0)
4388 goto error;
4389 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4390 if (status < 0)
4391 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004392
4393
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004394 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004395
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004396 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4397 if (status < 0)
4398 goto error;
4399 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4400 if (status < 0)
4401 goto error;
4402 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4403 if (status < 0)
4404 goto error;
4405 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4412 if (status < 0)
4413 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004414
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004415 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4419 if (status < 0)
4420 goto error;
4421 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4422 if (status < 0)
4423 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004424
4425
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004426 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004427
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004428 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4429 if (status < 0)
4430 goto error;
4431 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4432 if (status < 0)
4433 goto error;
4434 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4435 if (status < 0)
4436 goto error;
4437 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4444 if (status < 0)
4445 goto error;
4446 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4447 if (status < 0)
4448 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004449
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004450error:
4451 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004452 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004453 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004454}
4455
4456/*============================================================================*/
4457
4458/**
4459* \brief QAM32 specific setup
4460* \param demod instance of demod.
4461* \return DRXStatus_t.
4462*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004463static int set_qam32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004464{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004465 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004466
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004467 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004468
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004469 /* QAM Equalizer Setup */
4470 /* Equalizer */
4471 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4472 if (status < 0)
4473 goto error;
4474 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4475 if (status < 0)
4476 goto error;
4477 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4478 if (status < 0)
4479 goto error;
4480 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4481 if (status < 0)
4482 goto error;
4483 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4487 if (status < 0)
4488 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004489
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004490 /* Decision Feedback Equalizer */
4491 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4492 if (status < 0)
4493 goto error;
4494 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4495 if (status < 0)
4496 goto error;
4497 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4498 if (status < 0)
4499 goto error;
4500 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4501 if (status < 0)
4502 goto error;
4503 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4504 if (status < 0)
4505 goto error;
4506 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4507 if (status < 0)
4508 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004509
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004510 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4514 if (status < 0)
4515 goto error;
4516 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4517 if (status < 0)
4518 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004519
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004520 /* QAM Slicer Settings */
4521
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004522 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4523 DRXK_QAM_SL_SIG_POWER_QAM32);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004524 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 Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004530 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4552 if (status < 0)
4553 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004554
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004555 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4556 if (status < 0)
4557 goto error;
4558 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4559 if (status < 0)
4560 goto error;
4561 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4562 if (status < 0)
4563 goto error;
4564 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4589 if (status < 0)
4590 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004591
4592
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004593 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004594
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004595 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4596 if (status < 0)
4597 goto error;
4598 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4605 if (status < 0)
4606 goto error;
4607 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4608 if (status < 0)
4609 goto error;
4610 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4611 if (status < 0)
4612 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004613
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004614 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4615 if (status < 0)
4616 goto error;
4617 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4618 if (status < 0)
4619 goto error;
4620 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4621 if (status < 0)
4622 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004623
4624
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004625 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004627 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4628 if (status < 0)
4629 goto error;
4630 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4646error:
4647 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004648 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004649 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004650}
4651
4652/*============================================================================*/
4653
4654/**
4655* \brief QAM64 specific setup
4656* \param demod instance of demod.
4657* \return DRXStatus_t.
4658*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004659static int set_qam64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004660{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004661 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004662
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004663 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004664 /* QAM Equalizer Setup */
4665 /* Equalizer */
4666 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4667 if (status < 0)
4668 goto error;
4669 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4682 if (status < 0)
4683 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004684
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004685 /* Decision Feedback Equalizer */
4686 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4687 if (status < 0)
4688 goto error;
4689 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4690 if (status < 0)
4691 goto error;
4692 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4702 if (status < 0)
4703 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004704
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004705 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4706 if (status < 0)
4707 goto error;
4708 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4709 if (status < 0)
4710 goto error;
4711 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4712 if (status < 0)
4713 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004715 /* QAM Slicer Settings */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004716 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4717 DRXK_QAM_SL_SIG_POWER_QAM64);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004718 if (status < 0)
4719 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004720
4721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004722 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004724 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4746 if (status < 0)
4747 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004748
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004749 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4783 if (status < 0)
4784 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004785
4786
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004787 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004788
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004789 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4805 if (status < 0)
4806 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004807
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004808 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4815 if (status < 0)
4816 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004817
4818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004819 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004821 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4837 if (status < 0)
4838 goto error;
4839 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4840error:
4841 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004842 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004843
Oliver Endrissebc7de22011-07-03 13:49:44 -03004844 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004845}
4846
4847/*============================================================================*/
4848
4849/**
4850* \brief QAM128 specific setup
4851* \param demod: instance of demod.
4852* \return DRXStatus_t.
4853*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004854static int set_qam128(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004855{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004856 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004858 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004859 /* QAM Equalizer Setup */
4860 /* Equalizer */
4861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4877 if (status < 0)
4878 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004879
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004880 /* Decision Feedback Equalizer */
4881 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4897 if (status < 0)
4898 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004899
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004900 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4907 if (status < 0)
4908 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004909
4910
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004911 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03004913 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4914 DRXK_QAM_SL_SIG_POWER_QAM128);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004915 if (status < 0)
4916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004917
4918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004921 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4922 if (status < 0)
4923 goto error;
4924 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4925 if (status < 0)
4926 goto error;
4927 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4928 if (status < 0)
4929 goto error;
4930 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4931 if (status < 0)
4932 goto error;
4933 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4934 if (status < 0)
4935 goto error;
4936 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4937 if (status < 0)
4938 goto error;
4939 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4940 if (status < 0)
4941 goto error;
4942 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4943 if (status < 0)
4944 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004945
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004946 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4947 if (status < 0)
4948 goto error;
4949 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4950 if (status < 0)
4951 goto error;
4952 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4953 if (status < 0)
4954 goto error;
4955 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4956 if (status < 0)
4957 goto error;
4958 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4959 if (status < 0)
4960 goto error;
4961 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4962 if (status < 0)
4963 goto error;
4964 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4965 if (status < 0)
4966 goto error;
4967 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4968 if (status < 0)
4969 goto error;
4970 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4971 if (status < 0)
4972 goto error;
4973 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4974 if (status < 0)
4975 goto error;
4976 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4977 if (status < 0)
4978 goto error;
4979 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4980 if (status < 0)
4981 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004982
4983
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004984 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004985
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004986 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4987 if (status < 0)
4988 goto error;
4989 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4990 if (status < 0)
4991 goto error;
4992 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4996 if (status < 0)
4997 goto error;
4998 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5002 if (status < 0)
5003 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005005 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5006 if (status < 0)
5007 goto error;
5008 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5009 if (status < 0)
5010 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005012 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5013 if (status < 0)
5014 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005016 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005018 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5019 if (status < 0)
5020 goto error;
5021 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5022 if (status < 0)
5023 goto error;
5024 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5025 if (status < 0)
5026 goto error;
5027 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5031 if (status < 0)
5032 goto error;
5033 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5034 if (status < 0)
5035 goto error;
5036 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5037error:
5038 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005039 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005040
Oliver Endrissebc7de22011-07-03 13:49:44 -03005041 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005042}
5043
5044/*============================================================================*/
5045
5046/**
5047* \brief QAM256 specific setup
5048* \param demod: instance of demod.
5049* \return DRXStatus_t.
5050*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005051static int set_qam256(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005052{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005053 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005054
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005055 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005056 /* QAM Equalizer Setup */
5057 /* Equalizer */
5058 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5059 if (status < 0)
5060 goto error;
5061 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5062 if (status < 0)
5063 goto error;
5064 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5065 if (status < 0)
5066 goto error;
5067 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5074 if (status < 0)
5075 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005077 /* Decision Feedback Equalizer */
5078 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5079 if (status < 0)
5080 goto error;
5081 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5082 if (status < 0)
5083 goto error;
5084 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5085 if (status < 0)
5086 goto error;
5087 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5088 if (status < 0)
5089 goto error;
5090 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5091 if (status < 0)
5092 goto error;
5093 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5094 if (status < 0)
5095 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005096
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005097 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5098 if (status < 0)
5099 goto error;
5100 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5101 if (status < 0)
5102 goto error;
5103 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5104 if (status < 0)
5105 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005107 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005108
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005109 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5110 DRXK_QAM_SL_SIG_POWER_QAM256);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005111 if (status < 0)
5112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
5114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005115 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005117 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5139 if (status < 0)
5140 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005141
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005142 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5143 if (status < 0)
5144 goto error;
5145 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5146 if (status < 0)
5147 goto error;
5148 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5173 if (status < 0)
5174 goto error;
5175 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5176 if (status < 0)
5177 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005178
5179
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005180 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005182 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5183 if (status < 0)
5184 goto error;
5185 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5186 if (status < 0)
5187 goto error;
5188 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5189 if (status < 0)
5190 goto error;
5191 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5192 if (status < 0)
5193 goto error;
5194 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5195 if (status < 0)
5196 goto error;
5197 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5198 if (status < 0)
5199 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005200
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005201 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5202 if (status < 0)
5203 goto error;
5204 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5205 if (status < 0)
5206 goto error;
5207 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5208 if (status < 0)
5209 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005210
5211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005212 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005213
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005214 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5215 if (status < 0)
5216 goto error;
5217 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5218 if (status < 0)
5219 goto error;
5220 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5233error:
5234 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005235 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005236 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005237}
5238
5239
5240/*============================================================================*/
5241/**
5242* \brief Reset QAM block.
5243* \param demod: instance of demod.
5244* \param channel: pointer to channel data.
5245* \return DRXStatus_t.
5246*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005247static int qam_reset_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005249 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005250 u16 cmd_result;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005251
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005252 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005253 /* Stop QAM comstate->m_exec */
5254 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5255 if (status < 0)
5256 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005257
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005258 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5259 | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5260 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005261error:
5262 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005263 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005264 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005265}
5266
5267/*============================================================================*/
5268
5269/**
5270* \brief Set QAM symbolrate.
5271* \param demod: instance of demod.
5272* \param channel: pointer to channel data.
5273* \return DRXStatus_t.
5274*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005275static int qam_set_symbolrate(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005276{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005277 u32 adc_frequency = 0;
5278 u32 symb_freq = 0;
5279 u32 iqm_rc_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005280 u16 ratesel = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005281 u32 lc_symb_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005282 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005283
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005284 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005285 /* Select & calculate correct IQM rate */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005286 adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005287 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005288 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5289 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005290 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005291 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005292 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005293 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005294 ratesel = 1;
5295 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5296 if (status < 0)
5297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005299 /*
5300 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5301 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005302 symb_freq = state->props.symbol_rate * (1 << ratesel);
5303 if (symb_freq == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005304 /* Divide by zero */
5305 status = -EINVAL;
5306 goto error;
5307 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005308 iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5309 (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005310 (1 << 23);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005311 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005312 if (status < 0)
5313 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005314 state->m_iqm_rc_rate = iqm_rc_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005315 /*
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005316 LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005317 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005318 symb_freq = state->props.symbol_rate;
5319 if (adc_frequency == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005320 /* Divide by zero */
5321 status = -EINVAL;
5322 goto error;
5323 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005324 lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5325 (Frac28a((symb_freq % adc_frequency), adc_frequency) >>
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005326 16);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005327 if (lc_symb_rate > 511)
5328 lc_symb_rate = 511;
5329 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005331error:
5332 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005333 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005334 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005335}
5336
5337/*============================================================================*/
5338
5339/**
5340* \brief Get QAM lock status.
5341* \param demod: instance of demod.
5342* \param channel: pointer to channel data.
5343* \return DRXStatus_t.
5344*/
5345
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005346static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005347{
5348 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005349 u16 result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005350
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005351 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005352 *p_lock_status = NOT_LOCKED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005353 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 SCU_RAM_COMMAND_STANDARD_QAM |
5355 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005356 result);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005357 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005358 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005359
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005360 if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005361 /* 0x0000 NOT LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005362 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005363 /* 0x4000 DEMOD LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005364 *p_lock_status = DEMOD_LOCK;
5365 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005366 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005367 *p_lock_status = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005368 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005369 /* 0xC000 NEVER LOCKED */
5370 /* (system will never be able to lock to the signal) */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005371 /*
5372 * TODO: check this, intermediate & standard specific lock
5373 * states are not taken into account here
5374 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005375 *p_lock_status = NEVER_LOCK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005376 }
5377 return status;
5378}
5379
5380#define QAM_MIRROR__M 0x03
5381#define QAM_MIRROR_NORMAL 0x00
5382#define QAM_MIRRORED 0x01
5383#define QAM_MIRROR_AUTO_ON 0x02
5384#define QAM_LOCKRANGE__M 0x10
5385#define QAM_LOCKRANGE_NORMAL 0x10
5386
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005387static int qam_demodulator_command(struct drxk_state *state,
5388 int number_of_parameters)
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005389{
5390 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005391 u16 cmd_result;
5392 u16 set_param_parameters[4] = { 0, 0, 0, 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005393
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005394 set_param_parameters[0] = state->m_constellation; /* modulation */
5395 set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005396
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005397 if (number_of_parameters == 2) {
5398 u16 set_env_parameters[1] = { 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005399
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005400 if (state->m_operation_mode == OM_QAM_ITU_C)
5401 set_env_parameters[0] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005402 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005403 set_env_parameters[0] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005404
5405 status = scu_command(state,
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005406 SCU_RAM_COMMAND_STANDARD_QAM
5407 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005408 1, set_env_parameters, 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005409 if (status < 0)
5410 goto error;
5411
5412 status = scu_command(state,
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005413 SCU_RAM_COMMAND_STANDARD_QAM
5414 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005415 number_of_parameters, set_param_parameters,
5416 1, &cmd_result);
5417 } else if (number_of_parameters == 4) {
5418 if (state->m_operation_mode == OM_QAM_ITU_C)
5419 set_param_parameters[2] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005420 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005421 set_param_parameters[2] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005422
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005423 set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005424 /* Env parameters */
5425 /* check for LOCKRANGE Extented */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005426 /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005427
5428 status = scu_command(state,
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005429 SCU_RAM_COMMAND_STANDARD_QAM
5430 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005431 number_of_parameters, set_param_parameters,
5432 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005433 } else {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005434 pr_warn("Unknown QAM demodulator parameter count %d\n",
5435 number_of_parameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005436 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005437 }
5438
5439error:
5440 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005441 pr_warn("Warning %d on %s\n", status, __func__);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005442 return status;
5443}
5444
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005445static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5446 s32 tuner_freq_offset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005447{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005448 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005449 u16 cmd_result;
5450 int qam_demod_param_count = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005451
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005452 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005453 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005454 * STEP 1: reset demodulator
5455 * resets FEC DI and FEC RS
5456 * resets QAM block
5457 * resets SCU variables
5458 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005459 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005460 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005461 goto error;
5462 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5463 if (status < 0)
5464 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005465 status = qam_reset_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005466 if (status < 0)
5467 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005468
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005469 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005470 * STEP 2: configure demodulator
5471 * -set params; resets IQM,QAM,FEC HW; initializes some
5472 * SCU variables
5473 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005474 status = qam_set_symbolrate(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005475 if (status < 0)
5476 goto error;
5477
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005478 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005479 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005480 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005481 state->m_constellation = DRX_CONSTELLATION_QAM256;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005482 break;
5483 case QAM_AUTO:
5484 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005485 state->m_constellation = DRX_CONSTELLATION_QAM64;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005486 break;
5487 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005488 state->m_constellation = DRX_CONSTELLATION_QAM16;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005489 break;
5490 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005491 state->m_constellation = DRX_CONSTELLATION_QAM32;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005492 break;
5493 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005494 state->m_constellation = DRX_CONSTELLATION_QAM128;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005495 break;
5496 default:
5497 status = -EINVAL;
5498 break;
5499 }
5500 if (status < 0)
5501 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005502
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005503 /* Use the 4-parameter if it's requested or we're probing for
5504 * the correct command. */
5505 if (state->qam_demod_parameter_count == 4
5506 || !state->qam_demod_parameter_count) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005507 qam_demod_param_count = 4;
5508 status = qam_demodulator_command(state, qam_demod_param_count);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005509 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005510
5511 /* Use the 2-parameter command if it was requested or if we're
5512 * probing for the correct command and the 4-parameter command
5513 * failed. */
5514 if (state->qam_demod_parameter_count == 2
5515 || (!state->qam_demod_parameter_count && status < 0)) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005516 qam_demod_param_count = 2;
5517 status = qam_demodulator_command(state, qam_demod_param_count);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005518 }
5519
5520 if (status < 0) {
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -03005521 dprintk(1, "Could not set demodulator parameters.\n");
5522 dprintk(1,
5523 "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005524 state->qam_demod_parameter_count,
5525 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005526 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005527 } else if (!state->qam_demod_parameter_count) {
Mauro Carvalho Chehab0fb220f2013-04-28 11:47:46 -03005528 dprintk(1,
5529 "Auto-probing the QAM command parameters was successful - using %d parameters.\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005530 qam_demod_param_count);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005531
Mauro Carvalho Chehab7eaf7182012-07-06 14:53:51 -03005532 /*
5533 * One of our commands was successful. We don't need to
5534 * auto-probe anymore, now that we got the correct command.
5535 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005536 state->qam_demod_parameter_count = qam_demod_param_count;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005537 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005538
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005539 /*
5540 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005541 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005542 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005543#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005544 status = set_frequency(channel, tuner_freq_offset));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005545 if (status < 0)
5546 goto error;
5547#endif
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005548 status = set_frequency_shifter(state, intermediate_freqk_hz,
5549 tuner_freq_offset, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005550 if (status < 0)
5551 goto error;
5552
5553 /* Setup BER measurement */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005554 status = set_qam_measurement(state, state->m_constellation,
5555 state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005556 if (status < 0)
5557 goto error;
5558
5559 /* Reset default values */
5560 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5561 if (status < 0)
5562 goto error;
5563 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5564 if (status < 0)
5565 goto error;
5566
5567 /* Reset default LC values */
5568 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5569 if (status < 0)
5570 goto error;
5571 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5572 if (status < 0)
5573 goto error;
5574 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5575 if (status < 0)
5576 goto error;
5577 status = write16(state, QAM_LC_MODE__A, 7);
5578 if (status < 0)
5579 goto error;
5580
5581 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5582 if (status < 0)
5583 goto error;
5584 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5585 if (status < 0)
5586 goto error;
5587 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5588 if (status < 0)
5589 goto error;
5590 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5591 if (status < 0)
5592 goto error;
5593 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5594 if (status < 0)
5595 goto error;
5596 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5597 if (status < 0)
5598 goto error;
5599 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5600 if (status < 0)
5601 goto error;
5602 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5603 if (status < 0)
5604 goto error;
5605 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5606 if (status < 0)
5607 goto error;
5608 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5609 if (status < 0)
5610 goto error;
5611 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5612 if (status < 0)
5613 goto error;
5614 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5615 if (status < 0)
5616 goto error;
5617 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5618 if (status < 0)
5619 goto error;
5620 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5621 if (status < 0)
5622 goto error;
5623 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5624 if (status < 0)
5625 goto error;
5626
5627 /* Mirroring, QAM-block starting point not inverted */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005628 status = write16(state, QAM_SY_SP_INV__A,
5629 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005630 if (status < 0)
5631 goto error;
5632
5633 /* Halt SCU to enable safe non-atomic accesses */
5634 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5635 if (status < 0)
5636 goto error;
5637
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005638 /* STEP 4: modulation specific setup */
5639 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005640 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005641 status = set_qam16(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005642 break;
5643 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005644 status = set_qam32(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005645 break;
5646 case QAM_AUTO:
5647 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005648 status = set_qam64(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005649 break;
5650 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005651 status = set_qam128(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005652 break;
5653 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005654 status = set_qam256(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005655 break;
5656 default:
5657 status = -EINVAL;
5658 break;
5659 }
5660 if (status < 0)
5661 goto error;
5662
5663 /* Activate SCU to enable SCU commands */
5664 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5665 if (status < 0)
5666 goto error;
5667
5668 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005669 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005670 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005671 status = mpegts_dto_setup(state, state->m_operation_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005672 if (status < 0)
5673 goto error;
5674
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005675 /* start processes */
5676 status = mpegts_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005677 if (status < 0)
5678 goto error;
5679 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5686 if (status < 0)
5687 goto error;
5688
5689 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005690 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5691 | SCU_RAM_COMMAND_CMD_DEMOD_START,
5692 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005693 if (status < 0)
5694 goto error;
5695
5696 /* update global DRXK data container */
5697/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5698
5699error:
5700 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005701 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005702 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005703}
5704
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005705static int set_qam_standard(struct drxk_state *state,
5706 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005707{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005708 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005709#ifdef DRXK_QAM_TAPS
5710#define DRXK_QAMA_TAPS_SELECT
5711#include "drxk_filters.h"
5712#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005713#endif
5714
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005715 dprintk(1, "\n");
5716
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005717 /* added antenna switch */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005718 switch_antenna_to_qam(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005720 /* Ensure correct power-up mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005721 status = power_up_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005722 if (status < 0)
5723 goto error;
5724 /* Reset QAM block */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005725 status = qam_reset_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005726 if (status < 0)
5727 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005729 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005730
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005731 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5735 if (status < 0)
5736 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005737
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005738 /* Upload IQM Channel Filter settings by
5739 boot loader from ROM table */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005740 switch (o_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005741 case OM_QAM_ITU_A:
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005742 status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5743 DRXK_BLCC_NR_ELEMENTS_TAPS,
5744 DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 break;
5746 case OM_QAM_ITU_C:
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005747 status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5748 DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5749 DRXK_BLDC_NR_ELEMENTS_TAPS,
5750 DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005751 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005752 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005753 status = bl_direct_cmd(state,
5754 IQM_CF_TAP_IM0__A,
5755 DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5756 DRXK_BLDC_NR_ELEMENTS_TAPS,
5757 DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005758 break;
5759 default:
5760 status = -EINVAL;
5761 }
5762 if (status < 0)
5763 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005764
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005765 status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005766 if (status < 0)
5767 goto error;
5768 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5769 if (status < 0)
5770 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005771 status = write16(state, IQM_CF_MIDTAP__A,
5772 ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005773 if (status < 0)
5774 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005775
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005776 status = write16(state, IQM_RC_STRETCH__A, 21);
5777 if (status < 0)
5778 goto error;
5779 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5780 if (status < 0)
5781 goto error;
5782 status = write16(state, IQM_AF_CLP_TH__A, 448);
5783 if (status < 0)
5784 goto error;
5785 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5786 if (status < 0)
5787 goto error;
5788 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5789 if (status < 0)
5790 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005791
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005792 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5793 if (status < 0)
5794 goto error;
5795 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5796 if (status < 0)
5797 goto error;
5798 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5799 if (status < 0)
5800 goto error;
5801 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5802 if (status < 0)
5803 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005805 /* IQM Impulse Noise Processing Unit */
5806 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5807 if (status < 0)
5808 goto error;
5809 status = write16(state, IQM_CF_DATATH__A, 1000);
5810 if (status < 0)
5811 goto error;
5812 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5813 if (status < 0)
5814 goto error;
5815 status = write16(state, IQM_CF_DET_LCT__A, 0);
5816 if (status < 0)
5817 goto error;
5818 status = write16(state, IQM_CF_WND_LEN__A, 1);
5819 if (status < 0)
5820 goto error;
5821 status = write16(state, IQM_CF_PKDTH__A, 1);
5822 if (status < 0)
5823 goto error;
5824 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5825 if (status < 0)
5826 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005827
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005828 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005829 status = set_iqm_af(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005830 if (status < 0)
5831 goto error;
5832 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5833 if (status < 0)
5834 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005835
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005836 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005837 status = adc_synchronization(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005838 if (status < 0)
5839 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005840
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005841 /* Set the FSM step period */
5842 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5843 if (status < 0)
5844 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005845
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005846 /* Halt SCU to enable safe non-atomic accesses */
5847 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5848 if (status < 0)
5849 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005850
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005851 /* No more resets of the IQM, current standard correctly set =>
5852 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005853
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005854 status = init_agc(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005855 if (status < 0)
5856 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005857 status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005858 if (status < 0)
5859 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005860
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005861 /* Configure AGC's */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005862 status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005863 if (status < 0)
5864 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005865 status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005866 if (status < 0)
5867 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005868
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005869 /* Activate SCU to enable SCU commands */
5870 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5871error:
5872 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005873 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005874 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005875}
5876
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005877static int write_gpio(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005878{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005879 int status;
5880 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005881
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005882 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005883 /* stop lock indicator process */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005884 status = write16(state, SCU_RAM_GPIO__A,
5885 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005886 if (status < 0)
5887 goto error;
5888
5889 /* Write magic word to enable pdr reg write */
5890 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5891 if (status < 0)
5892 goto error;
5893
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005894 if (state->m_has_sawsw) {
5895 if (state->uio_mask & 0x0001) { /* UIO-1 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005896 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005897 status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5898 state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005899 if (status < 0)
5900 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005901
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005902 /* use corresponding bit in io data output registar */
5903 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5904 if (status < 0)
5905 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005906 if ((state->m_gpio & 0x0001) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005907 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5908 else
5909 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5910 /* write back to io data output register */
5911 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5912 if (status < 0)
5913 goto error;
5914 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005915 if (state->uio_mask & 0x0002) { /* UIO-2 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005916 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005917 status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5918 state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005919 if (status < 0)
5920 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005921
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005922 /* use corresponding bit in io data output registar */
5923 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5924 if (status < 0)
5925 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005926 if ((state->m_gpio & 0x0002) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005927 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5928 else
5929 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5930 /* write back to io data output register */
5931 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5932 if (status < 0)
5933 goto error;
5934 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005935 if (state->uio_mask & 0x0004) { /* UIO-3 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005936 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03005937 status = write16(state, SIO_PDR_GPIO_CFG__A,
5938 state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005939 if (status < 0)
5940 goto error;
5941
5942 /* use corresponding bit in io data output registar */
5943 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5944 if (status < 0)
5945 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005946 if ((state->m_gpio & 0x0004) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005947 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5948 else
5949 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5950 /* write back to io data output register */
5951 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5952 if (status < 0)
5953 goto error;
5954 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005955 }
5956 /* Write magic word to disable pdr reg write */
5957 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5958error:
5959 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005960 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005961 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005962}
5963
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005964static int switch_antenna_to_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005965{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005966 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005967 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005968
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005969 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005970
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005971 if (!state->antenna_gpio)
5972 return 0;
5973
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005974 gpio_state = state->m_gpio & state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005975
5976 if (state->antenna_dvbt ^ gpio_state) {
5977 /* Antenna is on DVB-T mode. Switch */
5978 if (state->antenna_dvbt)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005979 state->m_gpio &= ~state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005980 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005981 state->m_gpio |= state->antenna_gpio;
5982 status = write_gpio(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005983 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005984 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005985 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005986 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005987}
5988
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005989static int switch_antenna_to_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005990{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005991 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005992 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005993
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005994 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005995
5996 if (!state->antenna_gpio)
5997 return 0;
5998
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005999 gpio_state = state->m_gpio & state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006000
6001 if (!(state->antenna_dvbt ^ gpio_state)) {
6002 /* Antenna is on DVB-C mode. Switch */
6003 if (state->antenna_dvbt)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006004 state->m_gpio |= state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006005 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006006 state->m_gpio &= ~state->antenna_gpio;
6007 status = write_gpio(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006008 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006009 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006010 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006011 return status;
6012}
6013
6014
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006015static int power_down_device(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006016{
6017 /* Power down to requested mode */
6018 /* Backup some register settings */
6019 /* Set pins with possible pull-ups connected to them in input mode */
6020 /* Analog power down */
6021 /* ADC power down */
6022 /* Power down device */
6023 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006024
6025 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006026 if (state->m_b_p_down_open_bridge) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006027 /* Open I2C bridge before power down of DRXK */
6028 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03006029 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 goto error;
6031 }
6032 /* driver 0.9.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006033 status = dvbt_enable_ofdm_token_ring(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006034 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006035 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006036
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006037 status = write16(state, SIO_CC_PWD_MODE__A,
6038 SIO_CC_PWD_MODE_LEVEL_CLOCK);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006039 if (status < 0)
6040 goto error;
6041 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6042 if (status < 0)
6043 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006044 state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6045 status = hi_cfg_command(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006046error:
6047 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006048 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006049
6050 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006051}
6052
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006053static int init_drxk(struct drxk_state *state)
6054{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006055 int status = 0, n = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006056 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6057 u16 driver_version;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006058
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006059 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006060 if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006061 drxk_i2c_lock(state);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006062 status = power_up_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 if (status < 0)
6064 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006065 status = drxx_open(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006066 if (status < 0)
6067 goto error;
6068 /* Soft reset of OFDM-, sys- and osc-clockdomain */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006069 status = write16(state, SIO_CC_SOFT_RST__A,
6070 SIO_CC_SOFT_RST_OFDM__M
6071 | SIO_CC_SOFT_RST_SYS__M
6072 | SIO_CC_SOFT_RST_OSC__M);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006073 if (status < 0)
6074 goto error;
6075 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6076 if (status < 0)
6077 goto error;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006078 /*
6079 * TODO is this needed? If yes, how much delay in
6080 * worst case scenario
6081 */
Mauro Carvalho Chehabb72852b2013-04-28 11:47:47 -03006082 usleep_range(1000, 2000);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006083 state->m_drxk_a3_patch_code = true;
6084 status = get_device_capabilities(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006085 if (status < 0)
6086 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006087
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006088 /* Bridge delay, uses oscilator clock */
6089 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6090 /* SDA brdige delay */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006091 state->m_hi_cfg_bridge_delay =
6092 (u16) ((state->m_osc_clock_freq / 1000) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006093 HI_I2C_BRIDGE_DELAY) / 1000;
6094 /* Clipping */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006095 if (state->m_hi_cfg_bridge_delay >
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006096 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006097 state->m_hi_cfg_bridge_delay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006098 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6099 }
6100 /* SCL bridge delay, same as SDA for now */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006101 state->m_hi_cfg_bridge_delay +=
6102 state->m_hi_cfg_bridge_delay <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006103 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006104
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006105 status = init_hi(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006106 if (status < 0)
6107 goto error;
6108 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006109#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006110 if (!(state->m_DRXK_A1_ROM_CODE)
6111 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006112#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006113 {
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006114 status = write16(state, SCU_RAM_GPIO__A,
6115 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006116 if (status < 0)
6117 goto error;
6118 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 /* disable MPEG port */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006121 status = mpegts_disable(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006122 if (status < 0)
6123 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006125 /* Stop AUD and SCU */
6126 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6127 if (status < 0)
6128 goto error;
6129 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6130 if (status < 0)
6131 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006132
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006133 /* enable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006134 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6135 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006136 if (status < 0)
6137 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006138
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006139 /* include boot loader section */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006140 status = write16(state, SIO_BL_COMM_EXEC__A,
6141 SIO_BL_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006142 if (status < 0)
6143 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006144 status = bl_chain_cmd(state, 0, 6, 100);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006145 if (status < 0)
6146 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006147
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006148 if (state->fw) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006149 status = download_microcode(state, state->fw->data,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006150 state->fw->size);
6151 if (status < 0)
6152 goto error;
6153 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006154
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006155 /* disable token-ring bus through OFDM block for possible ucode upload */
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006156 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6157 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006158 if (status < 0)
6159 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006160
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006161 /* Run SCU for a little while to initialize microcode version numbers */
6162 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6163 if (status < 0)
6164 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006165 status = drxx_open(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006166 if (status < 0)
6167 goto error;
6168 /* added for test */
6169 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006170
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006171 power_mode = DRXK_POWER_DOWN_OFDM;
6172 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006173 if (status < 0)
6174 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006175
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006176 /* Stamp driver version number in SCU data RAM in BCD code
6177 Done to enable field application engineers to retreive drxdriver version
6178 via I2C from SCU RAM.
6179 Not using SCU command interface for SCU register access since no
6180 microcode may be present.
6181 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006182 driver_version =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006183 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6184 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6185 ((DRXK_VERSION_MAJOR % 10) << 4) +
6186 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006187 status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6188 driver_version);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006189 if (status < 0)
6190 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006191 driver_version =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006192 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6193 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6194 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6195 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006196 status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6197 driver_version);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006198 if (status < 0)
6199 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006200
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006201 pr_info("DRXK driver version %d.%d.%d\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006202 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6203 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006204
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006205 /*
6206 * Dirty fix of default values for ROM/PATCH microcode
6207 * Dirty because this fix makes it impossible to setup
6208 * suitable values before calling DRX_Open. This solution
6209 * requires changes to RF AGC speed to be done via the CTRL
6210 * function after calling DRX_Open
6211 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006212
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006213 /* m_dvbt_rf_agc_cfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006214
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006215 /* Reset driver debug flags to 0 */
6216 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6217 if (status < 0)
6218 goto error;
6219 /* driver 0.9.0 */
6220 /* Setup FEC OC:
6221 NOTE: No more full FEC resets allowed afterwards!! */
6222 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6223 if (status < 0)
6224 goto error;
6225 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006226 status = mpegts_dto_init(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006227 if (status < 0)
6228 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006229 status = mpegts_stop(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006230 if (status < 0)
6231 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006232 status = mpegts_configure_polarity(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006233 if (status < 0)
6234 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006235 status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006236 if (status < 0)
6237 goto error;
6238 /* added: configure GPIO */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006239 status = write_gpio(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006240 if (status < 0)
6241 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006242
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006243 state->m_drxk_state = DRXK_STOPPED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006244
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006245 if (state->m_b_power_down) {
6246 status = power_down_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006247 if (status < 0)
6248 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006249 state->m_drxk_state = DRXK_POWERED_DOWN;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006250 } else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006251 state->m_drxk_state = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006252
6253 /* Initialize the supported delivery systems */
6254 n = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006255 if (state->m_has_dvbc) {
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006256 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6257 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6258 strlcat(state->frontend.ops.info.name, " DVB-C",
6259 sizeof(state->frontend.ops.info.name));
6260 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006261 if (state->m_has_dvbt) {
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006262 state->frontend.ops.delsys[n++] = SYS_DVBT;
6263 strlcat(state->frontend.ops.info.name, " DVB-T",
6264 sizeof(state->frontend.ops.info.name));
6265 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006266 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006267 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006268error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006269 if (status < 0) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006270 state->m_drxk_state = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006271 drxk_i2c_unlock(state);
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006272 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006273 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006274
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006275 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006276}
6277
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006278static void load_firmware_cb(const struct firmware *fw,
6279 void *context)
6280{
6281 struct drxk_state *state = context;
6282
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006283 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006284 if (!fw) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006285 pr_err("Could not load firmware file %s.\n",
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006286 state->microcode_name);
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006287 pr_info("Copy %s to your hotplug directory!\n",
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006288 state->microcode_name);
6289 state->microcode_name = NULL;
6290
6291 /*
6292 * As firmware is now load asynchronous, it is not possible
6293 * anymore to fail at frontend attach. We might silently
6294 * return here, and hope that the driver won't crash.
6295 * We might also change all DVB callbacks to return -ENODEV
6296 * if the device is not initialized.
6297 * As the DRX-K devices have their own internal firmware,
6298 * let's just hope that it will match a firmware revision
6299 * compatible with this driver and proceed.
6300 */
6301 }
6302 state->fw = fw;
6303
6304 init_drxk(state);
6305}
6306
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006307static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006308{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006309 struct drxk_state *state = fe->demodulator_priv;
6310
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006311 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006312 if (state->fw)
6313 release_firmware(state->fw);
6314
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006315 kfree(state);
6316}
6317
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006318static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006319{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006320 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006321
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006322 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006323
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006324 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006325 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006326 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006327 return 0;
6328
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006329 shut_down(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006330 return 0;
6331}
6332
Oliver Endrissebc7de22011-07-03 13:49:44 -03006333static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006334{
6335 struct drxk_state *state = fe->demodulator_priv;
6336
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006337 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006338
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006339 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006340 return -ENODEV;
6341
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006342 return ConfigureI2CBridge(state, enable ? true : false);
6343}
6344
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006345static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006346{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006347 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006348 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006349 struct drxk_state *state = fe->demodulator_priv;
6350 u32 IF;
6351
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006352 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006353
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006354 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006355 return -ENODEV;
6356
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006357 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006358 return -EAGAIN;
6359
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006360 if (!fe->ops.tuner_ops.get_if_frequency) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006361 pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006362 return -EINVAL;
6363 }
6364
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006365 if (fe->ops.i2c_gate_ctrl)
6366 fe->ops.i2c_gate_ctrl(fe, 1);
6367 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006368 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006369 if (fe->ops.i2c_gate_ctrl)
6370 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006371
6372 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006373 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006374
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006375 if (old_delsys != delsys) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006376 shut_down(state);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006377 switch (delsys) {
6378 case SYS_DVBC_ANNEX_A:
6379 case SYS_DVBC_ANNEX_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006380 if (!state->m_has_dvbc)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006381 return -EINVAL;
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006382 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6383 true : false;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006384 if (state->m_itut_annex_c)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006385 setoperation_mode(state, OM_QAM_ITU_C);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006386 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006387 setoperation_mode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006388 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006389 case SYS_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006390 if (!state->m_has_dvbt)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006391 return -EINVAL;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006392 setoperation_mode(state, OM_DVBT);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006393 break;
6394 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006395 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006396 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006397 }
6398
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006399 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006400 start(state, 0, IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006401
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006402 /* After set_frontend, stats aren't avaliable */
6403 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6404 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6405 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6406 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6407 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6408 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6409 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6410 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6411
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006412 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006413
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006414 return 0;
6415}
6416
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006417static int get_strength(struct drxk_state *state, u64 *strength)
6418{
6419 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006420 struct s_cfg_agc rf_agc, if_agc;
6421 u32 total_gain = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006422 u32 atten = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006423 u32 agc_range = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006424 u16 scu_lvl = 0;
6425 u16 scu_coc = 0;
6426 /* FIXME: those are part of the tuner presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006427 u16 tuner_rf_gain = 50; /* Default value on az6007 driver */
6428 u16 tuner_if_gain = 40; /* Default value on az6007 driver */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006429
6430 *strength = 0;
6431
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006432 if (is_dvbt(state)) {
6433 rf_agc = state->m_dvbt_rf_agc_cfg;
6434 if_agc = state->m_dvbt_if_agc_cfg;
6435 } else if (is_qam(state)) {
6436 rf_agc = state->m_qam_rf_agc_cfg;
6437 if_agc = state->m_qam_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006438 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006439 rf_agc = state->m_atv_rf_agc_cfg;
6440 if_agc = state->m_atv_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006441 }
6442
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006443 if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6444 /* SCU output_level */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006445 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6446 if (status < 0)
6447 return status;
6448
6449 /* SCU c.o.c. */
6450 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6451 if (status < 0)
6452 return status;
6453
6454 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006455 rf_agc.output_level = scu_lvl + scu_coc;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006456 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006457 rf_agc.output_level = 0xffff;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006458
6459 /* Take RF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006460 total_gain += tuner_rf_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006461
6462 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006463 if (rf_agc.output_level < rf_agc.min_output_level)
6464 rf_agc.output_level = rf_agc.min_output_level;
6465 if (rf_agc.output_level > rf_agc.max_output_level)
6466 rf_agc.output_level = rf_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006467
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006468 agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6469 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006470 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006471 ((u32)(tuner_rf_gain)) *
6472 ((u32)(rf_agc.output_level - rf_agc.min_output_level))
6473 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006474 }
6475 }
6476
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006477 if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006478 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006479 &if_agc.output_level);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006480 if (status < 0)
6481 return status;
6482
6483 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006484 &if_agc.top);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006485 if (status < 0)
6486 return status;
6487
6488 /* Take IF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006489 total_gain += (u32) tuner_if_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006490
6491 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006492 if (if_agc.output_level < if_agc.min_output_level)
6493 if_agc.output_level = if_agc.min_output_level;
6494 if (if_agc.output_level > if_agc.max_output_level)
6495 if_agc.output_level = if_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006496
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006497 agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006498 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006499 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006500 ((u32)(tuner_if_gain)) *
6501 ((u32)(if_agc.output_level - if_agc.min_output_level))
6502 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006503 }
6504 }
6505
6506 /*
6507 * Convert to 0..65535 scale.
6508 * If it can't be measured (AGC is disabled), just show 100%.
6509 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006510 if (total_gain > 0)
6511 *strength = (65535UL * atten / total_gain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006512 else
6513 *strength = 65535;
6514
6515 return 0;
6516}
6517
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006518static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006519{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006520 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006521 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006522 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006523 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006524 u16 reg16;
6525 u32 post_bit_count;
6526 u32 post_bit_err_count;
6527 u32 post_bit_error_scale;
6528 u32 pre_bit_err_count;
6529 u32 pre_bit_count;
6530 u32 pkt_count;
6531 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006532 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006533
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006534 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006535 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006536 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006537 return -EAGAIN;
6538
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006539 /* get status */
6540 state->fe_status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006541 get_lock_status(state, &stat);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006542 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006543 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006544 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006545 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006546 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006547 state->fe_status |= 0x07;
6548
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006549 /*
6550 * Estimate signal strength from AGC
6551 */
6552 get_strength(state, &c->strength.stat[0].uvalue);
6553 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6554
6555
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006556 if (stat >= DEMOD_LOCK) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006557 get_signal_to_noise(state, &cnr);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006558 c->cnr.stat[0].svalue = cnr * 100;
6559 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6560 } else {
6561 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6562 }
6563
6564 if (stat < FEC_LOCK) {
6565 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6566 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6567 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6568 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6569 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6570 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6571 return 0;
6572 }
6573
6574 /* Get post BER */
6575
6576 /* BER measurement is valid if at least FEC lock is achieved */
6577
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006578 /*
6579 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6580 * written to set nr of symbols or bits over which to measure
6581 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6582 */
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006583
6584 /* Read registers for post/preViterbi BER calculation */
6585 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6586 if (status < 0)
6587 goto error;
6588 pre_bit_err_count = reg16;
6589
6590 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6591 if (status < 0)
6592 goto error;
6593 pre_bit_count = reg16;
6594
6595 /* Number of bit-errors */
6596 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6597 if (status < 0)
6598 goto error;
6599 post_bit_err_count = reg16;
6600
6601 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6602 if (status < 0)
6603 goto error;
6604 post_bit_error_scale = reg16;
6605
6606 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6607 if (status < 0)
6608 goto error;
6609 pkt_count = reg16;
6610
6611 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6612 if (status < 0)
6613 goto error;
6614 pkt_error_count = reg16;
6615 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6616
6617 post_bit_err_count *= post_bit_error_scale;
6618
6619 post_bit_count = pkt_count * 204 * 8;
6620
6621 /* Store the results */
6622 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6623 c->block_error.stat[0].uvalue += pkt_error_count;
6624 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6625 c->block_count.stat[0].uvalue += pkt_count;
6626
6627 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6628 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6629 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6630 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6631
6632 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6633 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6634 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6635 c->post_bit_count.stat[0].uvalue += post_bit_count;
6636
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006637error:
6638 return status;
6639}
6640
6641
6642static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6643{
6644 struct drxk_state *state = fe->demodulator_priv;
6645 int rc;
6646
6647 dprintk(1, "\n");
6648
6649 rc = drxk_get_stats(fe);
6650 if (rc < 0)
6651 return rc;
6652
6653 *status = state->fe_status;
6654
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006655 return 0;
6656}
6657
Oliver Endrissebc7de22011-07-03 13:49:44 -03006658static int drxk_read_signal_strength(struct dvb_frontend *fe,
6659 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006660{
6661 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006662 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006663
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006664 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006665
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006666 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006667 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006668 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006669 return -EAGAIN;
6670
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006671 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006672 return 0;
6673}
6674
6675static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6676{
6677 struct drxk_state *state = fe->demodulator_priv;
6678 s32 snr2;
6679
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006680 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006681
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006682 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006683 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006684 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006685 return -EAGAIN;
6686
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006687 get_signal_to_noise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006688
6689 /* No negative SNR, clip to zero */
6690 if (snr2 < 0)
6691 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006692 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006693 return 0;
6694}
6695
6696static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6697{
6698 struct drxk_state *state = fe->demodulator_priv;
6699 u16 err;
6700
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006701 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006702
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006703 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006704 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006705 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006706 return -EAGAIN;
6707
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006708 dvbtqam_get_acc_pkt_err(state, &err);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006709 *ucblocks = (u32) err;
6710 return 0;
6711}
6712
Mauro Carvalho Chehabab5060c2013-04-28 11:47:51 -03006713static int drxk_get_tune_settings(struct dvb_frontend *fe,
6714 struct dvb_frontend_tune_settings *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006715{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006716 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006717 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006718
6719 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006720
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006721 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006722 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006723 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006724 return -EAGAIN;
6725
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006726 switch (p->delivery_system) {
6727 case SYS_DVBC_ANNEX_A:
6728 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006729 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006730 sets->min_delay_ms = 3000;
6731 sets->max_drift = 0;
6732 sets->step_size = 0;
6733 return 0;
6734 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006735 return -EINVAL;
6736 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006737}
6738
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006739static struct dvb_frontend_ops drxk_ops = {
6740 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006741 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006742 .name = "DRXK",
6743 .frequency_min = 47000000,
6744 .frequency_max = 865000000,
6745 /* For DVB-C */
6746 .symbol_rate_min = 870000,
6747 .symbol_rate_max = 11700000,
6748 /* For DVB-T */
6749 .frequency_stepsize = 166667,
6750
6751 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6752 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6753 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6754 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6755 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6756 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6757 },
6758
6759 .release = drxk_release,
6760 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006761 .i2c_gate_ctrl = drxk_gate_ctrl,
6762
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006763 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006764 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006765
6766 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006767 .read_signal_strength = drxk_read_signal_strength,
6768 .read_snr = drxk_read_snr,
6769 .read_ucblocks = drxk_read_ucblocks,
6770};
6771
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006772struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006773 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006774{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006775 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006776 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006777 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006778 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006779
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006780 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006781 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006782 if (!state)
6783 return NULL;
6784
Oliver Endrissebc7de22011-07-03 13:49:44 -03006785 state->i2c = i2c;
6786 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006787 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006788 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006789 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006790 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006791 state->antenna_gpio = config->antenna_gpio;
6792 state->antenna_dvbt = config->antenna_dvbt;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006793 state->m_chunk_size = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006794 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006795
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006796 if (config->dynamic_clk) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006797 state->m_dvbt_static_clk = 0;
6798 state->m_dvbc_static_clk = 0;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006799 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006800 state->m_dvbt_static_clk = 1;
6801 state->m_dvbc_static_clk = 1;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006802 }
6803
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006804
6805 if (config->mpeg_out_clk_strength)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006806 state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006807 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006808 state->m_ts_clockk_strength = 0x06;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006809
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006810 if (config->parallel_ts)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006811 state->m_enable_parallel = true;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006812 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006813 state->m_enable_parallel = false;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006814
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006815 /* NOTE: as more UIO bits will be used, add them to the mask */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006816 state->uio_mask = config->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006817
6818 /* Default gpio to DVB-C */
6819 if (!state->antenna_dvbt && state->antenna_gpio)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006820 state->m_gpio |= state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006821 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006822 state->m_gpio &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006823
6824 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006825
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006826 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6827 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006828
6829 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006830
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006831 /* Load firmware and initialize DRX-K */
6832 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006833 if (config->load_firmware_sync) {
6834 const struct firmware *fw = NULL;
6835
6836 status = request_firmware(&fw, state->microcode_name,
6837 state->i2c->dev.parent);
6838 if (status < 0)
6839 fw = NULL;
6840 load_firmware_cb(fw, state);
6841 } else {
6842 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006843 state->microcode_name,
6844 state->i2c->dev.parent,
6845 GFP_KERNEL,
6846 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006847 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006848 pr_err("failed to request a firmware\n");
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006849 return NULL;
6850 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006851 }
6852 } else if (init_drxk(state) < 0)
6853 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006854
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006855
6856 /* Initialize stats */
6857 p = &state->frontend.dtv_property_cache;
6858 p->strength.len = 1;
6859 p->cnr.len = 1;
6860 p->block_error.len = 1;
6861 p->block_count.len = 1;
6862 p->pre_bit_error.len = 1;
6863 p->pre_bit_count.len = 1;
6864 p->post_bit_error.len = 1;
6865 p->post_bit_count.len = 1;
6866
6867 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6868 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6869 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6870 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6871 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6872 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6873 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6874 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6875
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006876 pr_info("frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006877 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006878
6879error:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006880 pr_err("not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006881 kfree(state);
6882 return NULL;
6883}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006884EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006885
6886MODULE_DESCRIPTION("DRX-K driver");
6887MODULE_AUTHOR("Ralph Metzler");
6888MODULE_LICENSE("GPL");