blob: d2b331a46a6de36b8039312c318b7c81b10374bc [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -030031#include <linux/hardirq.h>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030032#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -030037#include "dvb_math.h"
Ralph Metzler43dd07f2011-07-03 13:42:18 -030038
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030039static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
40static int power_down_qam(struct drxk_state *state);
41static int set_dvbt_standard(struct drxk_state *state,
42 enum operation_mode o_mode);
43static int set_qam_standard(struct drxk_state *state,
44 enum operation_mode o_mode);
45static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
46 s32 tuner_freq_offset);
47static int set_dvbt_standard(struct drxk_state *state,
48 enum operation_mode o_mode);
49static int dvbt_start(struct drxk_state *state);
50static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
51 s32 tuner_freq_offset);
52static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
53static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
54static int switch_antenna_to_qam(struct drxk_state *state);
55static int switch_antenna_to_dvbt(struct drxk_state *state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030056
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030057static bool is_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030058{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030059 return state->m_operation_mode == OM_DVBT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030060}
61
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030062static bool is_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030063{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030064 return state->m_operation_mode == OM_QAM_ITU_A ||
65 state->m_operation_mode == OM_QAM_ITU_B ||
66 state->m_operation_mode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030067}
68
Ralph Metzler43dd07f2011-07-03 13:42:18 -030069#define NOA1ROM 0
70
Ralph Metzler43dd07f2011-07-03 13:42:18 -030071#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
72#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
73
74#define DEFAULT_MER_83 165
75#define DEFAULT_MER_93 250
76
77#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
78#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
79#endif
80
81#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
82#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
83#endif
84
Ralph Metzler43dd07f2011-07-03 13:42:18 -030085#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
86#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
87
88#ifndef DRXK_KI_RAGC_ATV
89#define DRXK_KI_RAGC_ATV 4
90#endif
91#ifndef DRXK_KI_IAGC_ATV
92#define DRXK_KI_IAGC_ATV 6
93#endif
94#ifndef DRXK_KI_DAGC_ATV
95#define DRXK_KI_DAGC_ATV 7
96#endif
97
98#ifndef DRXK_KI_RAGC_QAM
99#define DRXK_KI_RAGC_QAM 3
100#endif
101#ifndef DRXK_KI_IAGC_QAM
102#define DRXK_KI_IAGC_QAM 4
103#endif
104#ifndef DRXK_KI_DAGC_QAM
105#define DRXK_KI_DAGC_QAM 7
106#endif
107#ifndef DRXK_KI_RAGC_DVBT
108#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
109#endif
110#ifndef DRXK_KI_IAGC_DVBT
111#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
112#endif
113#ifndef DRXK_KI_DAGC_DVBT
114#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
115#endif
116
117#ifndef DRXK_AGC_DAC_OFFSET
118#define DRXK_AGC_DAC_OFFSET (0x800)
119#endif
120
121#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
122#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
123#endif
124
125#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
126#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
127#endif
128
129#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
130#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
131#endif
132
133#ifndef DRXK_QAM_SYMBOLRATE_MAX
134#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
135#endif
136
137#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
138#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
139#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
140#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
141#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
142#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
143#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
144#define DRXK_BL_ROM_OFFSET_UCODE 0
145
146#define DRXK_BLC_TIMEOUT 100
147
148#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
149#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
150
151#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
152
153#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
154#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
155#endif
156
157#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
158#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
159#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
160#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
161#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
162
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300163static unsigned int debug;
164module_param(debug, int, 0644);
165MODULE_PARM_DESC(debug, "enable debug messages");
166
167#define dprintk(level, fmt, arg...) do { \
168if (debug >= level) \
169 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
170} while (0)
171
172
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300173static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300174{
175 u64 tmp64;
176
Oliver Endrissebc7de22011-07-03 13:49:44 -0300177 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300178 do_div(tmp64, c);
179
180 return (u32) tmp64;
181}
182
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200183static inline u32 Frac28a(u32 a, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300184{
185 int i = 0;
186 u32 Q1 = 0;
187 u32 R0 = 0;
188
Oliver Endrissebc7de22011-07-03 13:49:44 -0300189 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
190 Q1 = a / c; /* integer part, only the 4 least significant bits
191 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300192
193 /* division using radix 16, 7 nibbles in the result */
194 for (i = 0; i < 7; i++) {
195 Q1 = (Q1 << 4) | (R0 / c);
196 R0 = (R0 % c) << 4;
197 }
198 /* rounding */
199 if ((R0 >> 3) >= c)
200 Q1++;
201
202 return Q1;
203}
204
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300205static inline u32 log10times100(u32 value)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300206{
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300207 return (100L * intlog10(value)) >> 24;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300208}
209
210/****************************************************************************/
211/* I2C **********************************************************************/
212/****************************************************************************/
213
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300214static int drxk_i2c_lock(struct drxk_state *state)
215{
216 i2c_lock_adapter(state->i2c);
217 state->drxk_i2c_exclusive_lock = true;
218
219 return 0;
220}
221
222static void drxk_i2c_unlock(struct drxk_state *state)
223{
224 if (!state->drxk_i2c_exclusive_lock)
225 return;
226
227 i2c_unlock_adapter(state->i2c);
228 state->drxk_i2c_exclusive_lock = false;
229}
230
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300231static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
232 unsigned len)
233{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300234 if (state->drxk_i2c_exclusive_lock)
235 return __i2c_transfer(state->i2c, msgs, len);
236 else
237 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300238}
239
240static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300241{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300242 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
243 .buf = val, .len = 1}
244 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300245
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300246 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300247}
248
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300249static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300250{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300251 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300252 struct i2c_msg msg = {
253 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300254
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300255 dprintk(3, ":");
256 if (debug > 2) {
257 int i;
258 for (i = 0; i < len; i++)
259 printk(KERN_CONT " %02x", data[i]);
260 printk(KERN_CONT "\n");
261 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300262 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300263 if (status >= 0 && status != 1)
264 status = -EIO;
265
266 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300267 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300268
269 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300270}
271
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300272static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300273 u8 adr, u8 *msg, int len, u8 *answ, int alen)
274{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300275 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300276 struct i2c_msg msgs[2] = {
277 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300278 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300279 {.addr = adr, .flags = I2C_M_RD,
280 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300281 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300282
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300283 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300284 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300285 if (debug > 2)
286 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300287 if (status >= 0)
288 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300289
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300290 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300291 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300292 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300293 if (debug > 2) {
294 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300295 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300296 for (i = 0; i < len; i++)
297 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300298 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300299 for (i = 0; i < alen; i++)
300 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300301 printk(KERN_CONT "\n");
302 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 return 0;
304}
305
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300306static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300307{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300308 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300309 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300310
311 if (state->single_master)
312 flags |= 0xC0;
313
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300314 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
315 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
316 mm1[1] = ((reg >> 16) & 0xFF);
317 mm1[2] = ((reg >> 24) & 0xFF) | flags;
318 mm1[3] = ((reg >> 7) & 0xFF);
319 len = 4;
320 } else {
321 mm1[0] = ((reg << 1) & 0xFF);
322 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
323 len = 2;
324 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300325 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300326 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300327 if (status < 0)
328 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300329 if (data)
330 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300331
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300332 return 0;
333}
334
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300335static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300336{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300337 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338}
339
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300340static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300341{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300342 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300343 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300344
345 if (state->single_master)
346 flags |= 0xC0;
347
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300348 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
349 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
350 mm1[1] = ((reg >> 16) & 0xFF);
351 mm1[2] = ((reg >> 24) & 0xFF) | flags;
352 mm1[3] = ((reg >> 7) & 0xFF);
353 len = 4;
354 } else {
355 mm1[0] = ((reg << 1) & 0xFF);
356 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
357 len = 2;
358 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300359 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300360 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300361 if (status < 0)
362 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 if (data)
364 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300365 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300366
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300367 return 0;
368}
369
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300370static int read32(struct drxk_state *state, u32 reg, u32 *data)
371{
372 return read32_flags(state, reg, data, 0);
373}
374
375static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300376{
377 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300378
379 if (state->single_master)
380 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300381 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
382 mm[0] = (((reg << 1) & 0xFF) | 0x01);
383 mm[1] = ((reg >> 16) & 0xFF);
384 mm[2] = ((reg >> 24) & 0xFF) | flags;
385 mm[3] = ((reg >> 7) & 0xFF);
386 len = 4;
387 } else {
388 mm[0] = ((reg << 1) & 0xFF);
389 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
390 len = 2;
391 }
392 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300393 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300394
395 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300396 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300397}
398
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300399static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300400{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300401 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300402}
403
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300404static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300405{
406 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300407
408 if (state->single_master)
409 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300410 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
411 mm[0] = (((reg << 1) & 0xFF) | 0x01);
412 mm[1] = ((reg >> 16) & 0xFF);
413 mm[2] = ((reg >> 24) & 0xFF) | flags;
414 mm[3] = ((reg >> 7) & 0xFF);
415 len = 4;
416 } else {
417 mm[0] = ((reg << 1) & 0xFF);
418 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
419 len = 2;
420 }
421 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300422 mm[len + 1] = (data >> 8) & 0xff;
423 mm[len + 2] = (data >> 16) & 0xff;
424 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300425 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300426
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300427 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300428}
429
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300430static int write32(struct drxk_state *state, u32 reg, u32 data)
431{
432 return write32_flags(state, reg, data, 0);
433}
434
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300435static int write_block(struct drxk_state *state, u32 address,
436 const int block_size, const u8 p_block[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300437{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300438 int status = 0, blk_size = block_size;
439 u8 flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300440
441 if (state->single_master)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300442 flags |= 0xC0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300443
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300444 while (blk_size > 0) {
445 int chunk = blk_size > state->m_chunk_size ?
446 state->m_chunk_size : blk_size;
447 u8 *adr_buf = &state->chunk[0];
448 u32 adr_length = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300449
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300450 if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
451 adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
452 adr_buf[1] = ((address >> 16) & 0xFF);
453 adr_buf[2] = ((address >> 24) & 0xFF);
454 adr_buf[3] = ((address >> 7) & 0xFF);
455 adr_buf[2] |= flags;
456 adr_length = 4;
457 if (chunk == state->m_chunk_size)
458 chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300459 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300460 adr_buf[0] = ((address << 1) & 0xFF);
461 adr_buf[1] = (((address >> 16) & 0x0F) |
462 ((address >> 18) & 0xF0));
463 adr_length = 2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300464 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300465 memcpy(&state->chunk[adr_length], p_block, chunk);
466 dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300467 if (debug > 1) {
468 int i;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300469 if (p_block)
470 for (i = 0; i < chunk; i++)
471 printk(KERN_CONT " %02x", p_block[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300472 printk(KERN_CONT "\n");
473 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300474 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300475 &state->chunk[0], chunk + adr_length);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300476 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300477 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300478 __func__, address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300479 break;
480 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300481 p_block += chunk;
482 address += (chunk >> 1);
483 blk_size -= chunk;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300484 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300485 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300486}
487
488#ifndef DRXK_MAX_RETRIES_POWERUP
489#define DRXK_MAX_RETRIES_POWERUP 20
490#endif
491
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300492static int power_up_device(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300493{
494 int status;
495 u8 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300496 u16 retry_count = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300497
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300498 dprintk(1, "\n");
499
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300500 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300501 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300502 do {
503 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300504 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300505 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300506 msleep(10);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300507 retry_count++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300508 if (status < 0)
509 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300510 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300511 &data);
512 } while (status < 0 &&
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300513 (retry_count < DRXK_MAX_RETRIES_POWERUP));
514 if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300515 goto error;
516 }
517
518 /* Make sure all clk domains are active */
519 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
520 if (status < 0)
521 goto error;
522 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
523 if (status < 0)
524 goto error;
525 /* Enable pll lock tests */
526 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
527 if (status < 0)
528 goto error;
529
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300530 state->m_current_power_mode = DRX_POWER_UP;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300531
532error:
533 if (status < 0)
534 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
535
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300536 return status;
537}
538
539
540static int init_state(struct drxk_state *state)
541{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300542 /*
543 * FIXME: most (all?) of the values bellow should be moved into
544 * struct drxk_config, as they are probably board-specific
545 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300546 u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
547 u32 ul_vsb_if_agc_output_level = 0;
548 u32 ul_vsb_if_agc_min_level = 0;
549 u32 ul_vsb_if_agc_max_level = 0x7FFF;
550 u32 ul_vsb_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300551
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300552 u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
553 u32 ul_vsb_rf_agc_output_level = 0;
554 u32 ul_vsb_rf_agc_min_level = 0;
555 u32 ul_vsb_rf_agc_max_level = 0x7FFF;
556 u32 ul_vsb_rf_agc_speed = 3;
557 u32 ul_vsb_rf_agc_top = 9500;
558 u32 ul_vsb_rf_agc_cut_off_current = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300559
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300560 u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
561 u32 ul_atv_if_agc_output_level = 0;
562 u32 ul_atv_if_agc_min_level = 0;
563 u32 ul_atv_if_agc_max_level = 0;
564 u32 ul_atv_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300565
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300566 u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
567 u32 ul_atv_rf_agc_output_level = 0;
568 u32 ul_atv_rf_agc_min_level = 0;
569 u32 ul_atv_rf_agc_max_level = 0;
570 u32 ul_atv_rf_agc_top = 9500;
571 u32 ul_atv_rf_agc_cut_off_current = 4000;
572 u32 ul_atv_rf_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300573
574 u32 ulQual83 = DEFAULT_MER_83;
575 u32 ulQual93 = DEFAULT_MER_93;
576
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300577 u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
578 u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300579
580 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
581 /* io_pad_cfg_mode output mode is drive always */
582 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300583 u32 ul_gpio_cfg = 0x0113;
584 u32 ul_invert_ts_clock = 0;
585 u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
586 u32 ul_dvbt_bitrate = 50000000;
587 u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300588
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300589 u32 ul_insert_rs_byte = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300590
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300591 u32 ul_rf_mirror = 1;
592 u32 ul_power_down = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300593
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300594 dprintk(1, "\n");
595
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300596 state->m_has_lna = false;
597 state->m_has_dvbt = false;
598 state->m_has_dvbc = false;
599 state->m_has_atv = false;
600 state->m_has_oob = false;
601 state->m_has_audio = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300602
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300603 if (!state->m_chunk_size)
604 state->m_chunk_size = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300605
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300606 state->m_osc_clock_freq = 0;
607 state->m_smart_ant_inverted = false;
608 state->m_b_p_down_open_bridge = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300609
610 /* real system clock frequency in kHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300611 state->m_sys_clock_freq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300612 /* Timing div, 250ns/Psys */
613 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300614 state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300615 HI_I2C_DELAY) / 1000;
616 /* Clipping */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300617 if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
618 state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
619 state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300620 /* port/bridge/power down ctrl */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300621 state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300622
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300623 state->m_b_power_down = (ul_power_down != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300624
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300625 state->m_drxk_a3_patch_code = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300626
627 /* Init AGC and PGA parameters */
628 /* VSB IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300629 state->m_vsb_if_agc_cfg.ctrl_mode = (ul_vsb_if_agc_mode);
630 state->m_vsb_if_agc_cfg.output_level = (ul_vsb_if_agc_output_level);
631 state->m_vsb_if_agc_cfg.min_output_level = (ul_vsb_if_agc_min_level);
632 state->m_vsb_if_agc_cfg.max_output_level = (ul_vsb_if_agc_max_level);
633 state->m_vsb_if_agc_cfg.speed = (ul_vsb_if_agc_speed);
634 state->m_vsb_pga_cfg = 140;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300635
636 /* VSB RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300637 state->m_vsb_rf_agc_cfg.ctrl_mode = (ul_vsb_rf_agc_mode);
638 state->m_vsb_rf_agc_cfg.output_level = (ul_vsb_rf_agc_output_level);
639 state->m_vsb_rf_agc_cfg.min_output_level = (ul_vsb_rf_agc_min_level);
640 state->m_vsb_rf_agc_cfg.max_output_level = (ul_vsb_rf_agc_max_level);
641 state->m_vsb_rf_agc_cfg.speed = (ul_vsb_rf_agc_speed);
642 state->m_vsb_rf_agc_cfg.top = (ul_vsb_rf_agc_top);
643 state->m_vsb_rf_agc_cfg.cut_off_current = (ul_vsb_rf_agc_cut_off_current);
644 state->m_vsb_pre_saw_cfg.reference = 0x07;
645 state->m_vsb_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300646
647 state->m_Quality83percent = DEFAULT_MER_83;
648 state->m_Quality93percent = DEFAULT_MER_93;
649 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
650 state->m_Quality83percent = ulQual83;
651 state->m_Quality93percent = ulQual93;
652 }
653
654 /* ATV IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300655 state->m_atv_if_agc_cfg.ctrl_mode = (ul_atv_if_agc_mode);
656 state->m_atv_if_agc_cfg.output_level = (ul_atv_if_agc_output_level);
657 state->m_atv_if_agc_cfg.min_output_level = (ul_atv_if_agc_min_level);
658 state->m_atv_if_agc_cfg.max_output_level = (ul_atv_if_agc_max_level);
659 state->m_atv_if_agc_cfg.speed = (ul_atv_if_agc_speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300660
661 /* ATV RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300662 state->m_atv_rf_agc_cfg.ctrl_mode = (ul_atv_rf_agc_mode);
663 state->m_atv_rf_agc_cfg.output_level = (ul_atv_rf_agc_output_level);
664 state->m_atv_rf_agc_cfg.min_output_level = (ul_atv_rf_agc_min_level);
665 state->m_atv_rf_agc_cfg.max_output_level = (ul_atv_rf_agc_max_level);
666 state->m_atv_rf_agc_cfg.speed = (ul_atv_rf_agc_speed);
667 state->m_atv_rf_agc_cfg.top = (ul_atv_rf_agc_top);
668 state->m_atv_rf_agc_cfg.cut_off_current = (ul_atv_rf_agc_cut_off_current);
669 state->m_atv_pre_saw_cfg.reference = 0x04;
670 state->m_atv_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300671
672
673 /* DVBT RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300674 state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
675 state->m_dvbt_rf_agc_cfg.output_level = 0;
676 state->m_dvbt_rf_agc_cfg.min_output_level = 0;
677 state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
678 state->m_dvbt_rf_agc_cfg.top = 0x2100;
679 state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
680 state->m_dvbt_rf_agc_cfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300681
682
683 /* DVBT IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300684 state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
685 state->m_dvbt_if_agc_cfg.output_level = 0;
686 state->m_dvbt_if_agc_cfg.min_output_level = 0;
687 state->m_dvbt_if_agc_cfg.max_output_level = 9000;
688 state->m_dvbt_if_agc_cfg.top = 13424;
689 state->m_dvbt_if_agc_cfg.cut_off_current = 0;
690 state->m_dvbt_if_agc_cfg.speed = 3;
691 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
692 state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300693 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300694
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300695 state->m_dvbt_pre_saw_cfg.reference = 4;
696 state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300697
698 /* QAM RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300699 state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
700 state->m_qam_rf_agc_cfg.output_level = 0;
701 state->m_qam_rf_agc_cfg.min_output_level = 6023;
702 state->m_qam_rf_agc_cfg.max_output_level = 27000;
703 state->m_qam_rf_agc_cfg.top = 0x2380;
704 state->m_qam_rf_agc_cfg.cut_off_current = 4000;
705 state->m_qam_rf_agc_cfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300706
707 /* QAM IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300708 state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
709 state->m_qam_if_agc_cfg.output_level = 0;
710 state->m_qam_if_agc_cfg.min_output_level = 0;
711 state->m_qam_if_agc_cfg.max_output_level = 9000;
712 state->m_qam_if_agc_cfg.top = 0x0511;
713 state->m_qam_if_agc_cfg.cut_off_current = 0;
714 state->m_qam_if_agc_cfg.speed = 3;
715 state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
716 state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300717
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300718 state->m_qam_pga_cfg = 140;
719 state->m_qam_pre_saw_cfg.reference = 4;
720 state->m_qam_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300721
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300722 state->m_operation_mode = OM_NONE;
723 state->m_drxk_state = DRXK_UNINITIALIZED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300724
725 /* MPEG output configuration */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300726 state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */
727 state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */
728 state->m_invert_data = false; /* If TRUE; invert DATA signals */
729 state->m_invert_err = false; /* If TRUE; invert ERR signal */
730 state->m_invert_str = false; /* If TRUE; invert STR signals */
731 state->m_invert_val = false; /* If TRUE; invert VAL signals */
732 state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300733
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300734 /* If TRUE; static MPEG clockrate will be used;
735 otherwise clockrate will adapt to the bitrate of the TS */
736
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300737 state->m_dvbt_bitrate = ul_dvbt_bitrate;
738 state->m_dvbc_bitrate = ul_dvbc_bitrate;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300739
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300740 state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300741
742 /* Maximum bitrate in b/s in case static clockrate is selected */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300743 state->m_mpeg_ts_static_bitrate = 19392658;
744 state->m_disable_te_ihandling = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300745
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300746 if (ul_insert_rs_byte)
747 state->m_insert_rs_byte = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300748
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300749 state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
750 if (ul_mpeg_lock_time_out < 10000)
751 state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
752 state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
753 if (ul_demod_lock_time_out < 10000)
754 state->m_demod_lock_time_out = ul_demod_lock_time_out;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300755
Oliver Endrissebc7de22011-07-03 13:49:44 -0300756 /* QAM defaults */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300757 state->m_constellation = DRX_CONSTELLATION_AUTO;
758 state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
759 state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */
760 state->m_fec_rs_prescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300761
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300762 state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
763 state->m_agcfast_clip_ctrl_delay = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300764
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300765 state->m_gpio_cfg = (ul_gpio_cfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300766
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300767 state->m_b_power_down = false;
768 state->m_current_power_mode = DRX_POWER_DOWN;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300769
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300770 state->m_rfmirror = (ul_rf_mirror == 0);
771 state->m_if_agc_pol = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300772 return 0;
773}
774
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300775static int drxx_open(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300776{
777 int status = 0;
778 u32 jtag = 0;
779 u16 bid = 0;
780 u16 key = 0;
781
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300782 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300783 /* stop lock indicator process */
784 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
785 if (status < 0)
786 goto error;
787 /* Check device id */
788 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
789 if (status < 0)
790 goto error;
791 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
792 if (status < 0)
793 goto error;
794 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
795 if (status < 0)
796 goto error;
797 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
798 if (status < 0)
799 goto error;
800 status = write16(state, SIO_TOP_COMM_KEY__A, key);
801error:
802 if (status < 0)
803 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300804 return status;
805}
806
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300807static int get_device_capabilities(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300808{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300809 u16 sio_pdr_ohw_cfg = 0;
810 u32 sio_top_jtagid_lo = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300811 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300812 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300813
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300814 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300816 /* driver 0.9.0 */
817 /* stop lock indicator process */
818 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
819 if (status < 0)
820 goto error;
Martin Blumenstingl84183662012-10-04 14:22:55 -0300821 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300822 if (status < 0)
823 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300824 status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300825 if (status < 0)
826 goto error;
827 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
828 if (status < 0)
829 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300830
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300831 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300832 case 0:
833 /* ignore (bypass ?) */
834 break;
835 case 1:
836 /* 27 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300837 state->m_osc_clock_freq = 27000;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300838 break;
839 case 2:
840 /* 20.25 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300841 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300842 break;
843 case 3:
844 /* 4 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300845 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300846 break;
847 default:
Masanari Iida9c768202012-11-30 14:10:25 +0900848 printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300849 return -EINVAL;
850 }
851 /*
852 Determine device capabilities
853 Based on pinning v14
854 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300855 status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300856 if (status < 0)
857 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300858
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300859 printk(KERN_INFO "drxk: status = 0x%08x\n", sio_top_jtagid_lo);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300860
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300861 /* driver 0.9.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300862 switch ((sio_top_jtagid_lo >> 29) & 0xF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300863 case 0:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300864 state->m_device_spin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300865 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300866 break;
867 case 2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300868 state->m_device_spin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300869 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300870 break;
871 case 3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300872 state->m_device_spin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300873 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300874 break;
875 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300876 state->m_device_spin = DRXK_SPIN_UNKNOWN;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300877 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300878 printk(KERN_ERR "drxk: Spin %d unknown\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300879 (sio_top_jtagid_lo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300880 goto error2;
881 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300882 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300883 case 0x13:
884 /* typeId = DRX3913K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300885 state->m_has_lna = false;
886 state->m_has_oob = false;
887 state->m_has_atv = false;
888 state->m_has_audio = false;
889 state->m_has_dvbt = true;
890 state->m_has_dvbc = true;
891 state->m_has_sawsw = true;
892 state->m_has_gpio2 = false;
893 state->m_has_gpio1 = false;
894 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300895 break;
896 case 0x15:
897 /* typeId = DRX3915K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300898 state->m_has_lna = false;
899 state->m_has_oob = false;
900 state->m_has_atv = true;
901 state->m_has_audio = false;
902 state->m_has_dvbt = true;
903 state->m_has_dvbc = false;
904 state->m_has_sawsw = true;
905 state->m_has_gpio2 = true;
906 state->m_has_gpio1 = true;
907 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300908 break;
909 case 0x16:
910 /* typeId = DRX3916K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300911 state->m_has_lna = false;
912 state->m_has_oob = false;
913 state->m_has_atv = true;
914 state->m_has_audio = false;
915 state->m_has_dvbt = true;
916 state->m_has_dvbc = false;
917 state->m_has_sawsw = true;
918 state->m_has_gpio2 = true;
919 state->m_has_gpio1 = true;
920 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300921 break;
922 case 0x18:
923 /* typeId = DRX3918K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300924 state->m_has_lna = false;
925 state->m_has_oob = false;
926 state->m_has_atv = true;
927 state->m_has_audio = true;
928 state->m_has_dvbt = true;
929 state->m_has_dvbc = false;
930 state->m_has_sawsw = true;
931 state->m_has_gpio2 = true;
932 state->m_has_gpio1 = true;
933 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300934 break;
935 case 0x21:
936 /* typeId = DRX3921K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300937 state->m_has_lna = false;
938 state->m_has_oob = false;
939 state->m_has_atv = true;
940 state->m_has_audio = true;
941 state->m_has_dvbt = true;
942 state->m_has_dvbc = true;
943 state->m_has_sawsw = true;
944 state->m_has_gpio2 = true;
945 state->m_has_gpio1 = true;
946 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300947 break;
948 case 0x23:
949 /* typeId = DRX3923K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300950 state->m_has_lna = false;
951 state->m_has_oob = false;
952 state->m_has_atv = true;
953 state->m_has_audio = true;
954 state->m_has_dvbt = true;
955 state->m_has_dvbc = true;
956 state->m_has_sawsw = true;
957 state->m_has_gpio2 = true;
958 state->m_has_gpio1 = true;
959 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300960 break;
961 case 0x25:
962 /* typeId = DRX3925K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300963 state->m_has_lna = false;
964 state->m_has_oob = false;
965 state->m_has_atv = true;
966 state->m_has_audio = true;
967 state->m_has_dvbt = true;
968 state->m_has_dvbc = true;
969 state->m_has_sawsw = true;
970 state->m_has_gpio2 = true;
971 state->m_has_gpio1 = true;
972 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300973 break;
974 case 0x26:
975 /* typeId = DRX3926K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300976 state->m_has_lna = false;
977 state->m_has_oob = false;
978 state->m_has_atv = true;
979 state->m_has_audio = false;
980 state->m_has_dvbt = true;
981 state->m_has_dvbc = true;
982 state->m_has_sawsw = true;
983 state->m_has_gpio2 = true;
984 state->m_has_gpio1 = true;
985 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300986 break;
987 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300988 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300989 ((sio_top_jtagid_lo >> 12) & 0xFF));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300990 status = -EINVAL;
991 goto error2;
992 }
993
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300994 printk(KERN_INFO
995 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300996 ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
997 state->m_osc_clock_freq / 1000,
998 state->m_osc_clock_freq % 1000);
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001000error:
1001 if (status < 0)
1002 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1003
1004error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001005 return status;
1006}
1007
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001008static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001009{
1010 int status;
1011 bool powerdown_cmd;
1012
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001013 dprintk(1, "\n");
1014
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001015 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001016 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001017 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001019 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1020 msleep(1);
1021
1022 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001023 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001024 ((state->m_hi_cfg_ctrl) &
Oliver Endrissebc7de22011-07-03 13:49:44 -03001025 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1026 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001027 if (powerdown_cmd == false) {
1028 /* Wait until command rdy */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001029 u32 retry_count = 0;
1030 u16 wait_cmd;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001031
1032 do {
1033 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001034 retry_count += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001035 status = read16(state, SIO_HI_RA_RAM_CMD__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001036 &wait_cmd);
1037 } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
1038 && (wait_cmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001039 if (status < 0)
1040 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001041 status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001042 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001043error:
1044 if (status < 0)
1045 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1046
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001047 return status;
1048}
1049
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001050static int hi_cfg_command(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001051{
1052 int status;
1053
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001054 dprintk(1, "\n");
1055
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001056 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001057
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001058 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_hi_cfg_timeout);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001059 if (status < 0)
1060 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001061 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_hi_cfg_ctrl);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001062 if (status < 0)
1063 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001064 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_hi_cfg_wake_up_key);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001065 if (status < 0)
1066 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001067 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_hi_cfg_bridge_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001068 if (status < 0)
1069 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001070 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_hi_cfg_timing_div);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001071 if (status < 0)
1072 goto error;
1073 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1074 if (status < 0)
1075 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001076 status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001077 if (status < 0)
1078 goto error;
1079
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001080 state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001081error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001082 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001083 if (status < 0)
1084 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001085 return status;
1086}
1087
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001088static int init_hi(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001089{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001090 dprintk(1, "\n");
1091
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001092 state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1093 state->m_hi_cfg_timeout = 0x96FF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001094 /* port/bridge/power down ctrl */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001095 state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001096
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001097 return hi_cfg_command(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001098}
1099
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001100static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001101{
1102 int status = -1;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001103 u16 sio_pdr_mclk_cfg = 0;
1104 u16 sio_pdr_mdx_cfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001105 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001106
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001107 dprintk(1, ": mpeg %s, %s mode\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001108 mpeg_enable ? "enable" : "disable",
1109 state->m_enable_parallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001110
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001111 /* stop lock indicator process */
1112 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1113 if (status < 0)
1114 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001116 /* MPEG TS pad configuration */
Martin Blumenstingl84183662012-10-04 14:22:55 -03001117 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001118 if (status < 0)
1119 goto error;
1120
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001121 if (mpeg_enable == false) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001122 /* Set MPEG TS pads to inputmode */
1123 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1124 if (status < 0)
1125 goto error;
1126 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1127 if (status < 0)
1128 goto error;
1129 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1130 if (status < 0)
1131 goto error;
1132 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1133 if (status < 0)
1134 goto error;
1135 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1136 if (status < 0)
1137 goto error;
1138 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1139 if (status < 0)
1140 goto error;
1141 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1142 if (status < 0)
1143 goto error;
1144 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1145 if (status < 0)
1146 goto error;
1147 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1148 if (status < 0)
1149 goto error;
1150 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1151 if (status < 0)
1152 goto error;
1153 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1154 if (status < 0)
1155 goto error;
1156 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1157 if (status < 0)
1158 goto error;
1159 } else {
1160 /* Enable MPEG output */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001161 sio_pdr_mdx_cfg =
1162 ((state->m_ts_data_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001163 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001164 sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001165 SIO_PDR_MCLK_CFG_DRIVE__B) |
1166 0x0003);
1167
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001168 status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001169 if (status < 0)
1170 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001171
1172 if (state->enable_merr_cfg)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001173 err_cfg = sio_pdr_mdx_cfg;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001174
1175 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001176 if (status < 0)
1177 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001178 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001179 if (status < 0)
1180 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001181
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001182 if (state->m_enable_parallel == true) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001183 /* paralel -> enable MD1 to MD7 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001184 status = write16(state, SIO_PDR_MD1_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001185 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001186 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001187 status = write16(state, SIO_PDR_MD2_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001188 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001189 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001190 status = write16(state, SIO_PDR_MD3_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001191 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001192 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001193 status = write16(state, SIO_PDR_MD4_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001194 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001195 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001196 status = write16(state, SIO_PDR_MD5_CFG__A, 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 Chehabcd7a67a2013-04-28 11:47:44 -03001199 status = write16(state, SIO_PDR_MD6_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001200 if (status < 0)
1201 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001202 status = write16(state, SIO_PDR_MD7_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001203 if (status < 0)
1204 goto error;
1205 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001206 sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001207 SIO_PDR_MD0_CFG_DRIVE__B)
1208 | 0x0003);
1209 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001210 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001211 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001212 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001213 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001214 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001215 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001216 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001217 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001218 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001219 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001220 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001221 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001222 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001223 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001224 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001225 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001226 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001227 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001228 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001229 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001230 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001231 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001232 status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001233 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001234 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001235 status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001236 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001237 goto error;
1238 }
1239 /* Enable MB output over MPEG pads and ctl input */
1240 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1241 if (status < 0)
1242 goto error;
1243 /* Write nomagic word to enable pdr reg write */
1244 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1245error:
1246 if (status < 0)
1247 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001248 return status;
1249}
1250
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001251static int mpegts_disable(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001252{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001253 dprintk(1, "\n");
1254
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001255 return mpegts_configure_pins(state, false);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001256}
1257
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001258static int bl_chain_cmd(struct drxk_state *state,
1259 u16 rom_offset, u16 nr_of_elements, u32 time_out)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001260{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001261 u16 bl_status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001262 int status;
1263 unsigned long end;
1264
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001265 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001266 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001267 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1268 if (status < 0)
1269 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001270 status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001271 if (status < 0)
1272 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001273 status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001274 if (status < 0)
1275 goto error;
1276 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1277 if (status < 0)
1278 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001279
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001280 end = jiffies + msecs_to_jiffies(time_out);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001281 do {
1282 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001283 status = read16(state, SIO_BL_STATUS__A, &bl_status);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001284 if (status < 0)
1285 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001286 } while ((bl_status == 0x1) &&
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001287 ((time_is_after_jiffies(end))));
1288
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001289 if (bl_status == 0x1) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001290 printk(KERN_ERR "drxk: SIO not ready\n");
1291 status = -EINVAL;
1292 goto error2;
1293 }
1294error:
1295 if (status < 0)
1296 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1297error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001298 mutex_unlock(&state->mutex);
1299 return status;
1300}
1301
1302
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001303static int download_microcode(struct drxk_state *state,
1304 const u8 p_mc_image[], u32 length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001305{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001306 const u8 *p_src = p_mc_image;
1307 u32 address;
1308 u16 n_blocks;
1309 u16 block_size;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001310 u32 offset = 0;
1311 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001312 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001313
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001314 dprintk(1, "\n");
1315
Hans Verkuil5becbc52012-05-14 10:22:58 -03001316 /* down the drain (we don't care about MAGIC_WORD) */
1317#if 0
1318 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001319 drain = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001320#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001321 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001322 offset += sizeof(u16);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001323 n_blocks = (p_src[0] << 8) | p_src[1];
1324 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001325 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001326
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001327 for (i = 0; i < n_blocks; i += 1) {
1328 address = (p_src[0] << 24) | (p_src[1] << 16) |
1329 (p_src[2] << 8) | p_src[3];
1330 p_src += sizeof(u32);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001331 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001332
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001333 block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1334 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001335 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001336
Hans Verkuil5becbc52012-05-14 10:22:58 -03001337#if 0
1338 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001339 flags = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001340#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001341 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001342 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001343
Hans Verkuil5becbc52012-05-14 10:22:58 -03001344#if 0
1345 /* For future reference */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001346 block_crc = (p_src[0] << 8) | p_src[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001347#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001348 p_src += sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001349 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001350
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001351 if (offset + block_size > length) {
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001352 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1353 return -EINVAL;
1354 }
1355
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001356 status = write_block(state, address, block_size, p_src);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001357 if (status < 0) {
1358 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001359 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001360 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001361 p_src += block_size;
1362 offset += block_size;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001363 }
1364 return status;
1365}
1366
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001367static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001368{
1369 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001370 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001371 u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1372 u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001373 unsigned long end;
1374
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001375 dprintk(1, "\n");
1376
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001377 if (enable == false) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001378 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1379 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001380 }
1381
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001382 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001383 if (status >= 0 && data == desired_status) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001384 /* tokenring already has correct status */
1385 return status;
1386 }
1387 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001388 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001389
Oliver Endrissebc7de22011-07-03 13:49:44 -03001390 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001391 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001392 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001393 if ((status >= 0 && data == desired_status) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001394 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001395 msleep(1);
1396 } while (1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001397 if (data != desired_status) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001398 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001399 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001400 }
1401 return status;
1402}
1403
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001404static int mpegts_stop(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001405{
1406 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001407 u16 fec_oc_snc_mode = 0;
1408 u16 fec_oc_ipr_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001410 dprintk(1, "\n");
1411
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001412 /* Gracefull shutdown (byte boundaries) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001413 status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001414 if (status < 0)
1415 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001416 fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1417 status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001418 if (status < 0)
1419 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001420
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001421 /* Suppress MCLK during absence of data */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001422 status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001423 if (status < 0)
1424 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001425 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1426 status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001427
1428error:
1429 if (status < 0)
1430 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1431
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001432 return status;
1433}
1434
1435static int scu_command(struct drxk_state *state,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001436 u16 cmd, u8 parameter_len,
1437 u16 *parameter, u8 result_len, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001438{
1439#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1440#error DRXK register mapping no longer compatible with this routine!
1441#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001442 u16 cur_cmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001443 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001444 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001445 u8 buffer[34];
1446 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001447 const char *p;
1448 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001449
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001450 dprintk(1, "\n");
1451
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001452 if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1453 ((result_len > 0) && (result == NULL))) {
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001454 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1455 return status;
1456 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001457
1458 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001459
1460 /* assume that the command register is ready
1461 since it is checked afterwards */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001462 for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001463 buffer[cnt++] = (parameter[ii] & 0xFF);
1464 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1465 }
1466 buffer[cnt++] = (cmd & 0xFF);
1467 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1468
1469 write_block(state, SCU_RAM_PARAM_0__A -
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001470 (parameter_len - 1), cnt, buffer);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001471 /* Wait until SCU has processed command */
1472 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001474 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001475 status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001476 if (status < 0)
1477 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001478 } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1479 if (cur_cmd != DRX_SCU_READY) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001480 printk(KERN_ERR "drxk: SCU not ready\n");
1481 status = -EIO;
1482 goto error2;
1483 }
1484 /* read results */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001485 if ((result_len > 0) && (result != NULL)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001486 s16 err;
1487 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001488
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001489 for (ii = result_len - 1; ii >= 0; ii -= 1) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001490 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001491 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001492 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001493 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001494
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001495 /* Check if an error was reported by SCU */
1496 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001497 if (err >= 0)
1498 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001499
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001500 /* check for the known error codes */
1501 switch (err) {
1502 case SCU_RESULT_UNKCMD:
1503 p = "SCU_RESULT_UNKCMD";
1504 break;
1505 case SCU_RESULT_UNKSTD:
1506 p = "SCU_RESULT_UNKSTD";
1507 break;
1508 case SCU_RESULT_SIZE:
1509 p = "SCU_RESULT_SIZE";
1510 break;
1511 case SCU_RESULT_INVPAR:
1512 p = "SCU_RESULT_INVPAR";
1513 break;
1514 default: /* Other negative values are errors */
1515 sprintf(errname, "ERROR: %d\n", err);
1516 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001517 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001518 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1519 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1520 status = -EINVAL;
1521 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001522 }
1523
1524error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001525 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001526 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001527error2:
1528 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001529 return status;
1530}
1531
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001532static int set_iqm_af(struct drxk_state *state, bool active)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001533{
1534 u16 data = 0;
1535 int status;
1536
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001537 dprintk(1, "\n");
1538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001539 /* Configure IQM */
1540 status = read16(state, IQM_AF_STDBY__A, &data);
1541 if (status < 0)
1542 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001543
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001544 if (!active) {
1545 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1546 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1547 | IQM_AF_STDBY_STDBY_PD_STANDBY
1548 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1549 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1550 } else {
1551 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1552 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1553 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1554 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1555 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1556 );
1557 }
1558 status = write16(state, IQM_AF_STDBY__A, data);
1559
1560error:
1561 if (status < 0)
1562 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001563 return status;
1564}
1565
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001566static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567{
1568 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001569 u16 sio_cc_pwd_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001570
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001571 dprintk(1, "\n");
1572
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001573 /* Check arguments */
1574 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001575 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001576
1577 switch (*mode) {
1578 case DRX_POWER_UP:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001579 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001580 break;
1581 case DRXK_POWER_DOWN_OFDM:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001582 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001583 break;
1584 case DRXK_POWER_DOWN_CORE:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001585 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001586 break;
1587 case DRXK_POWER_DOWN_PLL:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001588 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001589 break;
1590 case DRX_POWER_DOWN:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001591 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001592 break;
1593 default:
1594 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001595 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001596 }
1597
1598 /* If already in requested power mode, do nothing */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001599 if (state->m_current_power_mode == *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001600 return 0;
1601
1602 /* For next steps make sure to start from DRX_POWER_UP mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001603 if (state->m_current_power_mode != DRX_POWER_UP) {
1604 status = power_up_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001605 if (status < 0)
1606 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001607 status = dvbt_enable_ofdm_token_ring(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001608 if (status < 0)
1609 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001610 }
1611
1612 if (*mode == DRX_POWER_UP) {
1613 /* Restore analog & pin configuartion */
1614 } else {
1615 /* Power down to requested mode */
1616 /* Backup some register settings */
1617 /* Set pins with possible pull-ups connected
1618 to them in input mode */
1619 /* Analog power down */
1620 /* ADC power down */
1621 /* Power down device */
1622 /* stop all comm_exec */
1623 /* Stop and power down previous standard */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001624 switch (state->m_operation_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001625 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001626 status = mpegts_stop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001627 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001628 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001629 status = power_down_dvbt(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001630 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001631 goto error;
1632 break;
1633 case OM_QAM_ITU_A:
1634 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001635 status = mpegts_stop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001636 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001637 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001638 status = power_down_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001639 if (status < 0)
1640 goto error;
1641 break;
1642 default:
1643 break;
1644 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001645 status = dvbt_enable_ofdm_token_ring(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001646 if (status < 0)
1647 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001648 status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001649 if (status < 0)
1650 goto error;
1651 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1652 if (status < 0)
1653 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001654
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001655 if (*mode != DRXK_POWER_DOWN_OFDM) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001656 state->m_hi_cfg_ctrl |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001657 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001658 status = hi_cfg_command(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001659 if (status < 0)
1660 goto error;
1661 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001662 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001663 state->m_current_power_mode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001664
1665error:
1666 if (status < 0)
1667 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1668
Oliver Endrissebc7de22011-07-03 13:49:44 -03001669 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670}
1671
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001672static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001673{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001674 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1675 u16 cmd_result = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001676 u16 data = 0;
1677 int status;
1678
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001679 dprintk(1, "\n");
1680
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001681 status = read16(state, SCU_COMM_EXEC__A, &data);
1682 if (status < 0)
1683 goto error;
1684 if (data == SCU_COMM_EXEC_ACTIVE) {
1685 /* Send OFDM stop command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001686 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001687 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001688 goto error;
1689 /* Send OFDM reset command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001690 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001691 if (status < 0)
1692 goto error;
1693 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001695 /* Reset datapath for OFDM, processors first */
1696 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1697 if (status < 0)
1698 goto error;
1699 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1700 if (status < 0)
1701 goto error;
1702 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1703 if (status < 0)
1704 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001705
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001706 /* powerdown AFE */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001707 status = set_iqm_af(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001708 if (status < 0)
1709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001711 /* powerdown to OFDM mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001712 if (set_power_mode) {
1713 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001714 if (status < 0)
1715 goto error;
1716 }
1717error:
1718 if (status < 0)
1719 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001720 return status;
1721}
1722
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001723static int setoperation_mode(struct drxk_state *state,
1724 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001725{
1726 int status = 0;
1727
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001728 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001729 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001730 Stop and power down previous standard
1731 TODO investigate total power down instead of partial
1732 power down depending on "previous" standard.
1733 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001734
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001735 /* disable HW lock indicator */
1736 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1737 if (status < 0)
1738 goto error;
1739
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001740 /* Device is already at the required mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001741 if (state->m_operation_mode == o_mode)
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001742 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001743
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001744 switch (state->m_operation_mode) {
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001745 /* OM_NONE was added for start up */
1746 case OM_NONE:
1747 break;
1748 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001749 status = mpegts_stop(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001750 if (status < 0)
1751 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001752 status = power_down_dvbt(state, true);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001753 if (status < 0)
1754 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001755 state->m_operation_mode = OM_NONE;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001756 break;
1757 case OM_QAM_ITU_A: /* fallthrough */
1758 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001759 status = mpegts_stop(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001760 if (status < 0)
1761 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001762 status = power_down_qam(state);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001763 if (status < 0)
1764 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001765 state->m_operation_mode = OM_NONE;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001766 break;
1767 case OM_QAM_ITU_B:
1768 default:
1769 status = -EINVAL;
1770 goto error;
1771 }
1772
1773 /*
1774 Power up new standard
1775 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001776 switch (o_mode) {
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001777 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001778 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001779 state->m_operation_mode = o_mode;
1780 status = set_dvbt_standard(state, o_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001781 if (status < 0)
1782 goto error;
1783 break;
1784 case OM_QAM_ITU_A: /* fallthrough */
1785 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001786 dprintk(1, ": DVB-C Annex %c\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001787 (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1788 state->m_operation_mode = o_mode;
1789 status = set_qam_standard(state, o_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001790 if (status < 0)
1791 goto error;
1792 break;
1793 case OM_QAM_ITU_B:
1794 default:
1795 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001796 }
1797error:
1798 if (status < 0)
1799 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1800 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001801}
1802
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001803static int start(struct drxk_state *state, s32 offset_freq,
1804 s32 intermediate_frequency)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001805{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001806 int status = -EINVAL;
1807
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001808 u16 i_freqk_hz;
1809 s32 offsetk_hz = offset_freq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001810
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001811 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001812 if (state->m_drxk_state != DRXK_STOPPED &&
1813 state->m_drxk_state != DRXK_DTV_STARTED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001815
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001816 state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001817
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001818 if (intermediate_frequency < 0) {
1819 state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1820 intermediate_frequency = -intermediate_frequency;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001821 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001822
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001823 switch (state->m_operation_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001824 case OM_QAM_ITU_A:
1825 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001826 i_freqk_hz = (intermediate_frequency / 1000);
1827 status = set_qam(state, i_freqk_hz, offsetk_hz);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001828 if (status < 0)
1829 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001830 state->m_drxk_state = DRXK_DTV_STARTED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001831 break;
1832 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001833 i_freqk_hz = (intermediate_frequency / 1000);
1834 status = mpegts_stop(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001835 if (status < 0)
1836 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001837 status = set_dvbt(state, i_freqk_hz, offsetk_hz);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001838 if (status < 0)
1839 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001840 status = dvbt_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001841 if (status < 0)
1842 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001843 state->m_drxk_state = DRXK_DTV_STARTED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001844 break;
1845 default:
1846 break;
1847 }
1848error:
1849 if (status < 0)
1850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001851 return status;
1852}
1853
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001854static int shut_down(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001855{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001856 dprintk(1, "\n");
1857
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001858 mpegts_stop(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001859 return 0;
1860}
1861
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001862static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001863{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001864 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001866 dprintk(1, "\n");
1867
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001868 if (p_lock_status == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001869 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001870
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001871 *p_lock_status = NOT_LOCKED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001872
1873 /* define the SCU command code */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001874 switch (state->m_operation_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001875 case OM_QAM_ITU_A:
1876 case OM_QAM_ITU_B:
1877 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001878 status = get_qam_lock_status(state, p_lock_status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001879 break;
1880 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001881 status = get_dvbt_lock_status(state, p_lock_status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001882 break;
1883 default:
1884 break;
1885 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886error:
1887 if (status < 0)
1888 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889 return status;
1890}
1891
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001892static int mpegts_start(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001893{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001894 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001895
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001896 u16 fec_oc_snc_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001897
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001898 /* Allow OC to sync again */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001899 status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001900 if (status < 0)
1901 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001902 fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1903 status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001904 if (status < 0)
1905 goto error;
1906 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1907error:
1908 if (status < 0)
1909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001910 return status;
1911}
1912
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001913static int mpegts_dto_init(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001914{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001915 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001916
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001917 dprintk(1, "\n");
1918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001919 /* Rate integration settings */
1920 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1921 if (status < 0)
1922 goto error;
1923 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1924 if (status < 0)
1925 goto error;
1926 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1927 if (status < 0)
1928 goto error;
1929 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1930 if (status < 0)
1931 goto error;
1932 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
1933 if (status < 0)
1934 goto error;
1935 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
1936 if (status < 0)
1937 goto error;
1938 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
1939 if (status < 0)
1940 goto error;
1941 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
1942 if (status < 0)
1943 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001944
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001945 /* Additional configuration */
1946 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
1947 if (status < 0)
1948 goto error;
1949 status = write16(state, FEC_OC_SNC_LWM__A, 2);
1950 if (status < 0)
1951 goto error;
1952 status = write16(state, FEC_OC_SNC_HWM__A, 12);
1953error:
1954 if (status < 0)
1955 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1956
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001957 return status;
1958}
1959
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001960static int mpegts_dto_setup(struct drxk_state *state,
1961 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001962{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001963 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001964
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001965 u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */
1966 u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */
1967 u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */
1968 u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */
1969 u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */
1970 u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */
1971 u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */
1972 u16 fec_oc_tmd_mode = 0;
1973 u16 fec_oc_tmd_int_upd_rate = 0;
1974 u32 max_bit_rate = 0;
1975 bool static_clk = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001976
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001977 dprintk(1, "\n");
1978
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001979 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001980 status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001981 if (status < 0)
1982 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001983 status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001984 if (status < 0)
1985 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001986 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
1987 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
1988 if (state->m_insert_rs_byte == true) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001989 /* enable parity symbol forward */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001990 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001991 /* MVAL disable during parity bytes */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001992 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001993 /* TS burst length to 204 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001994 fec_oc_dto_burst_len = 204;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001995 }
1996
1997 /* Check serial or parrallel output */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03001998 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
1999 if (state->m_enable_parallel == false) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002000 /* MPEG data output is serial -> set ipr_mode[0] */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002001 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002002 }
2003
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002004 switch (o_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002005 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002006 max_bit_rate = state->m_dvbt_bitrate;
2007 fec_oc_tmd_mode = 3;
2008 fec_oc_rcn_ctl_rate = 0xC00000;
2009 static_clk = state->m_dvbt_static_clk;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002010 break;
2011 case OM_QAM_ITU_A: /* fallthrough */
2012 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002013 fec_oc_tmd_mode = 0x0004;
2014 fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */
2015 max_bit_rate = state->m_dvbc_bitrate;
2016 static_clk = state->m_dvbc_static_clk;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002017 break;
2018 default:
2019 status = -EINVAL;
2020 } /* switch (standard) */
2021 if (status < 0)
2022 goto error;
2023
2024 /* Configure DTO's */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002025 if (static_clk) {
2026 u32 bit_rate = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002027
2028 /* Rational DTO for MCLK source (static MCLK rate),
2029 Dynamic DTO for optimal grouping
2030 (avoid intra-packet gaps),
2031 DTO offset enable to sync TS burst with MSTRT */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002032 fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002033 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002034 fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002035 FEC_OC_FCT_MODE_VIRT_ENA__M);
2036
2037 /* Check user defined bitrate */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002038 bit_rate = max_bit_rate;
2039 if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */
2040 bit_rate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002041 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002042 /* Rational DTO period:
2043 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002044
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002045 result should be floored,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002046 to make sure >= requested bitrate
2047 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002048 fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2049 * 1000) / bit_rate);
2050 if (fec_oc_dto_period <= 2)
2051 fec_oc_dto_period = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002052 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002053 fec_oc_dto_period -= 2;
2054 fec_oc_tmd_int_upd_rate = 8;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002055 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002056 /* (commonAttr->static_clk == false) => dynamic mode */
2057 fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2058 fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2059 fec_oc_tmd_int_upd_rate = 5;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002060 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002061
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002062 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002063 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002064 if (status < 0)
2065 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002066 status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002067 if (status < 0)
2068 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002069 status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002070 if (status < 0)
2071 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002072 status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002073 if (status < 0)
2074 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002075 status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002076 if (status < 0)
2077 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002078 status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002079 if (status < 0)
2080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002082 /* Rate integration settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002083 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002084 if (status < 0)
2085 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002086 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fec_oc_tmd_int_upd_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002087 if (status < 0)
2088 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002089 status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002090error:
2091 if (status < 0)
2092 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002093 return status;
2094}
2095
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002096static int mpegts_configure_polarity(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002097{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002098 u16 fec_oc_reg_ipr_invert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002099
2100 /* Data mask for the output data byte */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002101 u16 invert_data_mask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002102 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2103 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2104 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2105 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002106
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002107 dprintk(1, "\n");
2108
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002109 /* Control selective inversion of output bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002110 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2111 if (state->m_invert_data == true)
2112 fec_oc_reg_ipr_invert |= invert_data_mask;
2113 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2114 if (state->m_invert_err == true)
2115 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2116 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2117 if (state->m_invert_str == true)
2118 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2119 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2120 if (state->m_invert_val == true)
2121 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2122 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2123 if (state->m_invert_clk == true)
2124 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002125
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002126 return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002127}
2128
2129#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2130
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002131static int set_agc_rf(struct drxk_state *state,
2132 struct s_cfg_agc *p_agc_cfg, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002133{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002134 int status = -EINVAL;
2135 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002136 struct s_cfg_agc *p_if_agc_settings;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002137
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002138 dprintk(1, "\n");
2139
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002140 if (p_agc_cfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002141 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002142
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002143 switch (p_agc_cfg->ctrl_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002144 case DRXK_AGC_CTRL_AUTO:
2145 /* Enable RF AGC DAC */
2146 status = read16(state, IQM_AF_STDBY__A, &data);
2147 if (status < 0)
2148 goto error;
2149 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2150 status = write16(state, IQM_AF_STDBY__A, data);
2151 if (status < 0)
2152 goto error;
2153 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2154 if (status < 0)
2155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002157 /* Enable SCU RF AGC loop */
2158 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002159
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002160 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002161 if (state->m_rf_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002162 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2163 else
2164 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2165 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2166 if (status < 0)
2167 goto error;
2168
2169 /* Set speed (using complementary reduction value) */
2170 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2171 if (status < 0)
2172 goto error;
2173
2174 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002175 data |= (~(p_agc_cfg->speed <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002176 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2177 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2178
2179 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2180 if (status < 0)
2181 goto error;
2182
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002183 if (is_dvbt(state))
2184 p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2185 else if (is_qam(state))
2186 p_if_agc_settings = &state->m_qam_if_agc_cfg;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002187 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002188 p_if_agc_settings = &state->m_atv_if_agc_cfg;
2189 if (p_if_agc_settings == NULL) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002190 status = -EINVAL;
2191 goto error;
2192 }
2193
2194 /* Set TOP, only if IF-AGC is in AUTO mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002195 if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
2196 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_cfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002197 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002198 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002199
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002200 /* Cut-Off current */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002201 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, p_agc_cfg->cut_off_current);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002202 if (status < 0)
2203 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002204
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002205 /* Max. output level */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002206 status = write16(state, SCU_RAM_AGC_RF_MAX__A, p_agc_cfg->max_output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002207 if (status < 0)
2208 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002209
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002210 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002212 case DRXK_AGC_CTRL_USER:
2213 /* Enable RF AGC DAC */
2214 status = read16(state, IQM_AF_STDBY__A, &data);
2215 if (status < 0)
2216 goto error;
2217 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2218 status = write16(state, IQM_AF_STDBY__A, data);
2219 if (status < 0)
2220 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002221
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002222 /* Disable SCU RF AGC loop */
2223 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2224 if (status < 0)
2225 goto error;
2226 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002227 if (state->m_rf_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002228 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2229 else
2230 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2231 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2232 if (status < 0)
2233 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002234
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002235 /* SCU c.o.c. to 0, enabling full control range */
2236 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2237 if (status < 0)
2238 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002239
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002240 /* Write value to output pin */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002241 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, p_agc_cfg->output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002242 if (status < 0)
2243 goto error;
2244 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002245
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002246 case DRXK_AGC_CTRL_OFF:
2247 /* Disable RF AGC DAC */
2248 status = read16(state, IQM_AF_STDBY__A, &data);
2249 if (status < 0)
2250 goto error;
2251 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2252 status = write16(state, IQM_AF_STDBY__A, data);
2253 if (status < 0)
2254 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002255
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002256 /* Disable SCU RF AGC loop */
2257 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2258 if (status < 0)
2259 goto error;
2260 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2261 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2262 if (status < 0)
2263 goto error;
2264 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002265
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002266 default:
2267 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002268
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002269 }
2270error:
2271 if (status < 0)
2272 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002273 return status;
2274}
2275
2276#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2277
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002278static int set_agc_if(struct drxk_state *state,
2279 struct s_cfg_agc *p_agc_cfg, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002280{
2281 u16 data = 0;
2282 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002283 struct s_cfg_agc *p_rf_agc_settings;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002284
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002285 dprintk(1, "\n");
2286
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002287 switch (p_agc_cfg->ctrl_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002288 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002289
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002290 /* Enable IF AGC DAC */
2291 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002292 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002293 goto error;
2294 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2295 status = write16(state, IQM_AF_STDBY__A, data);
2296 if (status < 0)
2297 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002299 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2300 if (status < 0)
2301 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002302
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002303 /* Enable SCU IF AGC loop */
2304 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2305
2306 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002307 if (state->m_if_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002308 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2309 else
2310 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2311 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2312 if (status < 0)
2313 goto error;
2314
2315 /* Set speed (using complementary reduction value) */
2316 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2317 if (status < 0)
2318 goto error;
2319 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002320 data |= (~(p_agc_cfg->speed <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002321 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2322 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2323
2324 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2325 if (status < 0)
2326 goto error;
2327
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002328 if (is_qam(state))
2329 p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002330 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002331 p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2332 if (p_rf_agc_settings == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002333 return -1;
2334 /* Restore TOP */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002335 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_rf_agc_settings->top);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002336 if (status < 0)
2337 goto error;
2338 break;
2339
2340 case DRXK_AGC_CTRL_USER:
2341
2342 /* Enable IF AGC DAC */
2343 status = read16(state, IQM_AF_STDBY__A, &data);
2344 if (status < 0)
2345 goto error;
2346 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2347 status = write16(state, IQM_AF_STDBY__A, data);
2348 if (status < 0)
2349 goto error;
2350
2351 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2352 if (status < 0)
2353 goto error;
2354
2355 /* Disable SCU IF AGC loop */
2356 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2357
2358 /* Polarity */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002359 if (state->m_if_agc_pol)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002360 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2361 else
2362 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2363 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2364 if (status < 0)
2365 goto error;
2366
2367 /* Write value to output pin */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002368 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_cfg->output_level);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002369 if (status < 0)
2370 goto error;
2371 break;
2372
2373 case DRXK_AGC_CTRL_OFF:
2374
2375 /* Disable If AGC DAC */
2376 status = read16(state, IQM_AF_STDBY__A, &data);
2377 if (status < 0)
2378 goto error;
2379 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2380 status = write16(state, IQM_AF_STDBY__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 /* Disable SCU IF AGC loop */
2385 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2386 if (status < 0)
2387 goto error;
2388 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2389 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2390 if (status < 0)
2391 goto error;
2392 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002393 } /* switch (agcSettingsIf->ctrl_mode) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002394
2395 /* always set the top to support
2396 configurations without if-loop */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002397 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002398error:
2399 if (status < 0)
2400 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002401 return status;
2402}
2403
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002404static int get_qam_signal_to_noise(struct drxk_state *state,
2405 s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002406{
2407 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002408 u16 qam_sl_err_power = 0; /* accum. error between
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002409 raw and sliced symbols */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002410 u32 qam_sl_sig_power = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002411 QAM modulation */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002412 u32 qam_sl_mer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002413
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002414 dprintk(1, "\n");
2415
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002416 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002417
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002418 /* get the register value needed for MER */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002419 status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002420 if (status < 0) {
2421 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2422 return -EINVAL;
2423 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002424
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002425 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002426 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002427 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002428 break;
2429 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002430 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002431 break;
2432 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002433 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002434 break;
2435 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002436 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002437 break;
2438 default:
2439 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002440 qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002441 break;
2442 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002443
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002444 if (qam_sl_err_power > 0) {
2445 qam_sl_mer = log10times100(qam_sl_sig_power) -
2446 log10times100((u32) qam_sl_err_power);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002447 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002448 *p_signal_to_noise = qam_sl_mer;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002449
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002450 return status;
2451}
2452
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002453static int get_dvbt_signal_to_noise(struct drxk_state *state,
2454 s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002455{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002456 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002457 u16 reg_data = 0;
2458 u32 eq_reg_td_sqr_err_i = 0;
2459 u32 eq_reg_td_sqr_err_q = 0;
2460 u16 eq_reg_td_sqr_err_exp = 0;
2461 u16 eq_reg_td_tps_pwr_ofs = 0;
2462 u16 eq_reg_td_req_smb_cnt = 0;
2463 u32 tps_cnt = 0;
2464 u32 sqr_err_iq = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002465 u32 a = 0;
2466 u32 b = 0;
2467 u32 c = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002468 u32 i_mer = 0;
2469 u16 transmission_params = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002470
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002471 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002472
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002473 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &eq_reg_td_tps_pwr_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002474 if (status < 0)
2475 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002476 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &eq_reg_td_req_smb_cnt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002477 if (status < 0)
2478 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002479 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &eq_reg_td_sqr_err_exp);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002480 if (status < 0)
2481 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002482 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &reg_data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002483 if (status < 0)
2484 goto error;
2485 /* Extend SQR_ERR_I operational range */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002486 eq_reg_td_sqr_err_i = (u32) reg_data;
2487 if ((eq_reg_td_sqr_err_exp > 11) &&
2488 (eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2489 eq_reg_td_sqr_err_i += 0x00010000UL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002490 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002491 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002492 if (status < 0)
2493 goto error;
2494 /* Extend SQR_ERR_Q operational range */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002495 eq_reg_td_sqr_err_q = (u32) reg_data;
2496 if ((eq_reg_td_sqr_err_exp > 11) &&
2497 (eq_reg_td_sqr_err_q < 0x00000FFFUL))
2498 eq_reg_td_sqr_err_q += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002499
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002500 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmission_params);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002501 if (status < 0)
2502 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002503
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002504 /* Check input data for MER */
2505
2506 /* MER calculation (in 0.1 dB) without math.h */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002507 if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2508 i_mer = 0;
2509 else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002510 /* No error at all, this must be the HW reset value
2511 * Apparently no first measurement yet
2512 * Set MER to 0.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002513 i_mer = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002514 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002515 sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2516 eq_reg_td_sqr_err_exp;
2517 if ((transmission_params &
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002518 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2519 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002520 tps_cnt = 17;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002521 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002522 tps_cnt = 68;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002523
2524 /* IMER = 100 * log10 (x)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002525 where x = (eq_reg_td_tps_pwr_ofs^2 *
2526 eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002527
2528 => IMER = a + b -c
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002529 where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2530 b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2531 c = 100 * log10 (sqr_err_iq)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002532 */
2533
2534 /* log(x) x = 9bits * 9bits->18 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002535 a = log10times100(eq_reg_td_tps_pwr_ofs *
2536 eq_reg_td_tps_pwr_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002537 /* log(x) x = 16bits * 7bits->23 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002538 b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002539 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002540 c = log10times100(sqr_err_iq);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002541
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002542 i_mer = a + b - c;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002543 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002544 *p_signal_to_noise = i_mer;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002545
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002546error:
2547 if (status < 0)
2548 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002549 return status;
2550}
2551
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002552static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002553{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002554 dprintk(1, "\n");
2555
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002556 *p_signal_to_noise = 0;
2557 switch (state->m_operation_mode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002558 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002559 return get_dvbt_signal_to_noise(state, p_signal_to_noise);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002560 case OM_QAM_ITU_A:
2561 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002562 return get_qam_signal_to_noise(state, p_signal_to_noise);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002563 default:
2564 break;
2565 }
2566 return 0;
2567}
2568
2569#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002570static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002571{
2572 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2573 int status = 0;
2574
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002575 dprintk(1, "\n");
2576
Oliver Endrissebc7de22011-07-03 13:49:44 -03002577 static s32 QE_SN[] = {
2578 51, /* QPSK 1/2 */
2579 69, /* QPSK 2/3 */
2580 79, /* QPSK 3/4 */
2581 89, /* QPSK 5/6 */
2582 97, /* QPSK 7/8 */
2583 108, /* 16-QAM 1/2 */
2584 131, /* 16-QAM 2/3 */
2585 146, /* 16-QAM 3/4 */
2586 156, /* 16-QAM 5/6 */
2587 160, /* 16-QAM 7/8 */
2588 165, /* 64-QAM 1/2 */
2589 187, /* 64-QAM 2/3 */
2590 202, /* 64-QAM 3/4 */
2591 216, /* 64-QAM 5/6 */
2592 225, /* 64-QAM 7/8 */
2593 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002594
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002595 *p_quality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002596
2597 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002598 s32 signal_to_noise = 0;
2599 u16 constellation = 0;
2600 u16 code_rate = 0;
2601 u32 signal_to_noise_rel;
2602 u32 ber_quality;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002603
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002604 status = get_dvbt_signal_to_noise(state, &signal_to_noise);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002605 if (status < 0)
2606 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002607 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002608 if (status < 0)
2609 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002610 constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002611
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002612 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &code_rate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002613 if (status < 0)
2614 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002615 code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002616
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002617 if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2618 code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002619 break;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002620 signal_to_noise_rel = signal_to_noise -
2621 QE_SN[constellation * 5 + code_rate];
2622 ber_quality = 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002623
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002624 if (signal_to_noise_rel < -70)
2625 *p_quality = 0;
2626 else if (signal_to_noise_rel < 30)
2627 *p_quality = ((signal_to_noise_rel + 70) *
2628 ber_quality) / 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002629 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002630 *p_quality = ber_quality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002631 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002632 return 0;
2633};
2634
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002635static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002636{
2637 int status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002638 *p_quality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002639
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002640 dprintk(1, "\n");
2641
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002642 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002643 u32 signal_to_noise = 0;
2644 u32 ber_quality = 100;
2645 u32 signal_to_noise_rel = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002646
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002647 status = get_qam_signal_to_noise(state, &signal_to_noise);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002648 if (status < 0)
2649 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002650
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002651 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002652 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002653 signal_to_noise_rel = signal_to_noise - 200;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002654 break;
2655 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002656 signal_to_noise_rel = signal_to_noise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002657 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002658 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002659 signal_to_noise_rel = signal_to_noise - 260;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002660 break;
2661 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002662 signal_to_noise_rel = signal_to_noise - 290;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002663 break;
2664 default:
2665 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002666 signal_to_noise_rel = signal_to_noise - 320;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002667 break;
2668 }
2669
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002670 if (signal_to_noise_rel < -70)
2671 *p_quality = 0;
2672 else if (signal_to_noise_rel < 30)
2673 *p_quality = ((signal_to_noise_rel + 70) *
2674 ber_quality) / 100;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002675 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002676 *p_quality = ber_quality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002677 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002678
2679 return status;
2680}
2681
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002682static int get_quality(struct drxk_state *state, s32 *p_quality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002683{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002684 dprintk(1, "\n");
2685
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002686 switch (state->m_operation_mode) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03002687 case OM_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002688 return get_dvbt_quality(state, p_quality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002689 case OM_QAM_ITU_A:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002690 return get_dvbc_quality(state, p_quality);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002691 default:
2692 break;
2693 }
2694
2695 return 0;
2696}
2697#endif
2698
2699/* Free data ram in SIO HI */
2700#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2701#define SIO_HI_RA_RAM_USR_END__A 0x420060
2702
2703#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2704#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2705#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2706#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2707
2708#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2709#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2710#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2711
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002712static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002713{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002714 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002715
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002716 dprintk(1, "\n");
2717
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002718 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03002719 return 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002720 if (state->m_drxk_state == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002721 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002722
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002723 if (state->no_i2c_bridge)
2724 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002726 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2727 if (status < 0)
2728 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002729 if (b_enable_bridge) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002730 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002731 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002732 goto error;
2733 } else {
2734 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2735 if (status < 0)
2736 goto error;
2737 }
2738
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002739 status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002740
2741error:
2742 if (status < 0)
2743 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002744 return status;
2745}
2746
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002747static int set_pre_saw(struct drxk_state *state,
2748 struct s_cfg_pre_saw *p_pre_saw_cfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002749{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002750 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002751
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002752 dprintk(1, "\n");
2753
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002754 if ((p_pre_saw_cfg == NULL)
2755 || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002756 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002757
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002758 status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002759error:
2760 if (status < 0)
2761 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002762 return status;
2763}
2764
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002765static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2766 u16 rom_offset, u16 nr_of_elements, u32 time_out)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002767{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002768 u16 bl_status = 0;
2769 u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2770 u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002771 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002772 unsigned long end;
2773
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002774 dprintk(1, "\n");
2775
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002776 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002777 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2778 if (status < 0)
2779 goto error;
2780 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2781 if (status < 0)
2782 goto error;
2783 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2784 if (status < 0)
2785 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002786 status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002787 if (status < 0)
2788 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002789 status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002790 if (status < 0)
2791 goto error;
2792 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2793 if (status < 0)
2794 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002795
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002796 end = jiffies + msecs_to_jiffies(time_out);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002797 do {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002798 status = read16(state, SIO_BL_STATUS__A, &bl_status);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002799 if (status < 0)
2800 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002801 } while ((bl_status == 0x1) && time_is_after_jiffies(end));
2802 if (bl_status == 0x1) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002803 printk(KERN_ERR "drxk: SIO not ready\n");
2804 status = -EINVAL;
2805 goto error2;
2806 }
2807error:
2808 if (status < 0)
2809 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2810error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002811 mutex_unlock(&state->mutex);
2812 return status;
2813
2814}
2815
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002816static int adc_sync_measurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002817{
2818 u16 data = 0;
2819 int status;
2820
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002821 dprintk(1, "\n");
2822
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002823 /* start measurement */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002824 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2825 if (status < 0)
2826 goto error;
2827 status = write16(state, IQM_AF_START_LOCK__A, 1);
2828 if (status < 0)
2829 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002830
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002831 *count = 0;
2832 status = read16(state, IQM_AF_PHASE0__A, &data);
2833 if (status < 0)
2834 goto error;
2835 if (data == 127)
2836 *count = *count + 1;
2837 status = read16(state, IQM_AF_PHASE1__A, &data);
2838 if (status < 0)
2839 goto error;
2840 if (data == 127)
2841 *count = *count + 1;
2842 status = read16(state, IQM_AF_PHASE2__A, &data);
2843 if (status < 0)
2844 goto error;
2845 if (data == 127)
2846 *count = *count + 1;
2847
2848error:
2849 if (status < 0)
2850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002851 return status;
2852}
2853
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002854static int adc_synchronization(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855{
2856 u16 count = 0;
2857 int status;
2858
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002859 dprintk(1, "\n");
2860
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002861 status = adc_sync_measurement(state, &count);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002862 if (status < 0)
2863 goto error;
2864
2865 if (count == 1) {
2866 /* Try sampling on a diffrent edge */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002867 u16 clk_neg = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002868
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002869 status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002870 if (status < 0)
2871 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002872 if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002873 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002874 clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2875 clk_neg |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002876 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2877 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002878 clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2879 clk_neg |=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002880 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2881 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002882 status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002883 if (status < 0)
2884 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002885 status = adc_sync_measurement(state, &count);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002886 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002887 goto error;
2888 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002889
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002890 if (count < 2)
2891 status = -EINVAL;
2892error:
2893 if (status < 0)
2894 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002895 return status;
2896}
2897
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002898static int set_frequency_shifter(struct drxk_state *state,
2899 u16 intermediate_freqk_hz,
2900 s32 tuner_freq_offset, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002901{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002902 bool select_pos_image = false;
2903 u32 rf_freq_residual = tuner_freq_offset;
2904 u32 fm_frequency_shift = 0;
2905 bool tuner_mirror = !state->m_b_mirror_freq_spect;
2906 u32 adc_freq;
2907 bool adc_flip;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002908 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002909 u32 if_freq_actual;
2910 u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2911 u32 frequency_shift;
2912 bool image_to_select;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002913
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002914 dprintk(1, "\n");
2915
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002916 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03002917 Program frequency shifter
2918 No need to account for mirroring on RF
2919 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002920 if (is_dtv) {
2921 if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2922 (state->m_operation_mode == OM_QAM_ITU_C) ||
2923 (state->m_operation_mode == OM_DVBT))
2924 select_pos_image = true;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002925 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002926 select_pos_image = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002927 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002928 if (tuner_mirror)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002929 /* tuner doesn't mirror */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002930 if_freq_actual = intermediate_freqk_hz +
2931 rf_freq_residual + fm_frequency_shift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002932 else
2933 /* tuner mirrors */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002934 if_freq_actual = intermediate_freqk_hz -
2935 rf_freq_residual - fm_frequency_shift;
2936 if (if_freq_actual > sampling_frequency / 2) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002937 /* adc mirrors */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002938 adc_freq = sampling_frequency - if_freq_actual;
2939 adc_flip = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002940 } else {
2941 /* adc doesn't mirror */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002942 adc_freq = if_freq_actual;
2943 adc_flip = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002944 }
2945
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002946 frequency_shift = adc_freq;
2947 image_to_select = state->m_rfmirror ^ tuner_mirror ^
2948 adc_flip ^ select_pos_image;
2949 state->m_iqm_fs_rate_ofs =
2950 Frac28a((frequency_shift), sampling_frequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002951
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002952 if (image_to_select)
2953 state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002954
2955 /* Program frequency shifter with tuner offset compensation */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002956 /* frequency_shift += tuner_freq_offset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002957 status = write32(state, IQM_FS_RATE_OFS_LO__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002958 state->m_iqm_fs_rate_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002959 if (status < 0)
2960 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002961 return status;
2962}
2963
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002964static int init_agc(struct drxk_state *state, bool is_dtv)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002965{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002966 u16 ingain_tgt = 0;
2967 u16 ingain_tgt_min = 0;
2968 u16 ingain_tgt_max = 0;
2969 u16 clp_cyclen = 0;
2970 u16 clp_sum_min = 0;
2971 u16 clp_dir_to = 0;
2972 u16 sns_sum_min = 0;
2973 u16 sns_sum_max = 0;
2974 u16 clp_sum_max = 0;
2975 u16 sns_dir_to = 0;
2976 u16 ki_innergain_min = 0;
2977 u16 if_iaccu_hi_tgt = 0;
2978 u16 if_iaccu_hi_tgt_min = 0;
2979 u16 if_iaccu_hi_tgt_max = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002980 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002981 u16 fast_clp_ctrl_delay = 0;
2982 u16 clp_ctrl_mode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002983 int status = 0;
2984
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002985 dprintk(1, "\n");
2986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002987 /* Common settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002988 sns_sum_max = 1023;
2989 if_iaccu_hi_tgt_min = 2047;
2990 clp_cyclen = 500;
2991 clp_sum_max = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002992
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002993 /* AGCInit() not available for DVBT; init done in microcode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03002994 if (!is_qam(state)) {
2995 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_operation_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002996 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002997 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002998
2999 /* FIXME: Analog TV AGC require different settings */
3000
3001 /* Standard specific settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003002 clp_sum_min = 8;
3003 clp_dir_to = (u16) -9;
3004 clp_ctrl_mode = 0;
3005 sns_sum_min = 8;
3006 sns_dir_to = (u16) -9;
3007 ki_innergain_min = (u16) -1030;
3008 if_iaccu_hi_tgt_max = 0x2380;
3009 if_iaccu_hi_tgt = 0x2380;
3010 ingain_tgt_min = 0x0511;
3011 ingain_tgt = 0x0511;
3012 ingain_tgt_max = 5119;
3013 fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003014
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003015 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fast_clp_ctrl_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003016 if (status < 0)
3017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003018
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003019 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003020 if (status < 0)
3021 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003022 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003023 if (status < 0)
3024 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003025 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003026 if (status < 0)
3027 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003028 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003029 if (status < 0)
3030 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003031 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003032 if (status < 0)
3033 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003034 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, if_iaccu_hi_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003035 if (status < 0)
3036 goto error;
3037 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3038 if (status < 0)
3039 goto error;
3040 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3041 if (status < 0)
3042 goto error;
3043 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3044 if (status < 0)
3045 goto error;
3046 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3047 if (status < 0)
3048 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003049 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003050 if (status < 0)
3051 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003052 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003053 if (status < 0)
3054 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003055
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003056 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003057 if (status < 0)
3058 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003059 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, if_iaccu_hi_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003060 if (status < 0)
3061 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003062 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
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 Chehabbe44eb22011-07-10 01:49:53 -03003066 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3067 if (status < 0)
3068 goto error;
3069 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3070 if (status < 0)
3071 goto error;
3072 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3073 if (status < 0)
3074 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003076 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3077 if (status < 0)
3078 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003079 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003080 if (status < 0)
3081 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003082 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003083 if (status < 0)
3084 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003085 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003086 if (status < 0)
3087 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003088 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003089 if (status < 0)
3090 goto error;
3091 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3092 if (status < 0)
3093 goto error;
3094 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3095 if (status < 0)
3096 goto error;
3097 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3098 if (status < 0)
3099 goto error;
3100 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3101 if (status < 0)
3102 goto error;
3103 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3104 if (status < 0)
3105 goto error;
3106 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3107 if (status < 0)
3108 goto error;
3109 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3110 if (status < 0)
3111 goto error;
3112 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3113 if (status < 0)
3114 goto error;
3115 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3116 if (status < 0)
3117 goto error;
3118 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3119 if (status < 0)
3120 goto error;
3121 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3122 if (status < 0)
3123 goto error;
3124 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3125 if (status < 0)
3126 goto error;
3127 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3128 if (status < 0)
3129 goto error;
3130 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3131 if (status < 0)
3132 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003134 /* Initialize inner-loop KI gain factors */
3135 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3136 if (status < 0)
3137 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003138
3139 data = 0x0657;
3140 data &= ~SCU_RAM_AGC_KI_RF__M;
3141 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3142 data &= ~SCU_RAM_AGC_KI_IF__M;
3143 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3144
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003145 status = write16(state, SCU_RAM_AGC_KI__A, data);
3146error:
3147 if (status < 0)
3148 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003149 return status;
3150}
3151
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003152static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003153{
3154 int status;
3155
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003156 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003157 if (packet_err == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003158 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3159 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003160 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packet_err);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003161 if (status < 0)
3162 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003163 return status;
3164}
3165
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003166static int dvbt_sc_command(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003167 u16 cmd, u16 subcmd,
3168 u16 param0, u16 param1, u16 param2,
3169 u16 param3, u16 param4)
3170{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003171 u16 cur_cmd = 0;
3172 u16 err_code = 0;
3173 u16 retry_cnt = 0;
3174 u16 sc_exec = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003175 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003176
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003177 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003178 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3179 if (sc_exec != 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003180 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003181 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003182 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003183 if (status < 0)
3184 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003185
3186 /* Wait until sc is ready to receive command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003187 retry_cnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003188 do {
3189 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003190 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3191 retry_cnt++;
3192 } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3193 if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003194 goto error;
3195
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003196 /* Write sub-command */
3197 switch (cmd) {
3198 /* All commands using sub-cmd */
3199 case OFDM_SC_RA_RAM_CMD_PROC_START:
3200 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3201 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003202 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3203 if (status < 0)
3204 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003205 break;
3206 default:
3207 /* Do nothing */
3208 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003209 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003210
3211 /* Write needed parameters and the command */
3212 switch (cmd) {
3213 /* All commands using 5 parameters */
3214 /* All commands using 4 parameters */
3215 /* All commands using 3 parameters */
3216 /* All commands using 2 parameters */
3217 case OFDM_SC_RA_RAM_CMD_PROC_START:
3218 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3219 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003220 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003221 /* All commands using 1 parameters */
3222 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3223 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003224 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003225 /* All commands using 0 parameters */
3226 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3227 case OFDM_SC_RA_RAM_CMD_NULL:
3228 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003229 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003230 break;
3231 default:
3232 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003233 status = -EINVAL;
3234 }
3235 if (status < 0)
3236 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003237
3238 /* Wait until sc is ready processing command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003239 retry_cnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003240 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003241 msleep(1);
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;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003247
3248 /* Check for illegal cmd */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003249 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3250 if (err_code == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003251 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003252 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003253 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003254 if (status < 0)
3255 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003256
3257 /* Retreive results parameters from SC */
3258 switch (cmd) {
3259 /* All commands yielding 5 results */
3260 /* All commands yielding 4 results */
3261 /* All commands yielding 3 results */
3262 /* All commands yielding 2 results */
3263 /* All commands yielding 1 result */
3264 case OFDM_SC_RA_RAM_CMD_USER_IO:
3265 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003266 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003267 /* All commands yielding 0 results */
3268 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3269 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3270 case OFDM_SC_RA_RAM_CMD_PROC_START:
3271 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3272 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3273 case OFDM_SC_RA_RAM_CMD_NULL:
3274 break;
3275 default:
3276 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003277 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003278 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003279 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003280error:
3281 if (status < 0)
3282 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003283 return status;
3284}
3285
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003286static int power_up_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003287{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003288 enum drx_power_mode power_mode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003289 int status;
3290
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003291 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003292 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003293 if (status < 0)
3294 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003295 return status;
3296}
3297
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003298static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003299{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003301
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003302 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003303 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003304 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003305 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003306 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003307 if (status < 0)
3308 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003309 return status;
3310}
3311
3312#define DEFAULT_FR_THRES_8K 4000
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003313static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003314{
3315
3316 int status;
3317
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003318 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003319 if (*enabled == true) {
3320 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003321 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003322 DEFAULT_FR_THRES_8K);
3323 } else {
3324 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003325 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003326 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003327 if (status < 0)
3328 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003329
3330 return status;
3331}
3332
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003333static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3334 struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003335{
3336 u16 data = 0;
3337 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003338
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003339 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003340 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3341 if (status < 0)
3342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003344 switch (echo_thres->fft_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003345 case DRX_FFTMODE_2K:
3346 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003347 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003348 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3349 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003350 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003351 case DRX_FFTMODE_8K:
3352 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003353 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003354 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3355 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003356 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003357 default:
3358 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003359 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003360
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003361 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3362error:
3363 if (status < 0)
3364 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003365 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003366}
3367
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003368static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3369 enum drxk_cfg_dvbt_sqi_speed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003370{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003371 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003372
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003373 dprintk(1, "\n");
3374
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003375 switch (*speed) {
3376 case DRXK_DVBT_SQI_SPEED_FAST:
3377 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3378 case DRXK_DVBT_SQI_SPEED_SLOW:
3379 break;
3380 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003381 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003382 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003383 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003384 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003385error:
3386 if (status < 0)
3387 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003388 return status;
3389}
3390
3391/*============================================================================*/
3392
3393/**
3394* \brief Activate DVBT specific presets
3395* \param demod instance of demodulator.
3396* \return DRXStatus_t.
3397*
3398* Called in DVBTSetStandard
3399*
3400*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003401static int dvbt_activate_presets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003402{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003403 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003404 bool setincenable = false;
3405 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003406
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003407 struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3408 struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003409
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003410 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003411 status = dvbt_ctrl_set_inc_enable(state, &setincenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003412 if (status < 0)
3413 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003414 status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003415 if (status < 0)
3416 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003417 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003418 if (status < 0)
3419 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003420 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003421 if (status < 0)
3422 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003423 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbt_if_agc_cfg.ingain_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003424error:
3425 if (status < 0)
3426 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003427 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003428}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003429
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003430/*============================================================================*/
3431
3432/**
3433* \brief Initialize channelswitch-independent settings for DVBT.
3434* \param demod instance of demodulator.
3435* \return DRXStatus_t.
3436*
3437* For ROM code channel filter taps are loaded from the bootloader. For microcode
3438* the DVB-T taps from the drxk_filters.h are used.
3439*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003440static int set_dvbt_standard(struct drxk_state *state,
3441 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003442{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003443 u16 cmd_result = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003444 u16 data = 0;
3445 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003446
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003447 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003448
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003449 power_up_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003450 /* added antenna switch */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003451 switch_antenna_to_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003452 /* send OFDM reset command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003453 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmd_result);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003454 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003455 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003456
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003457 /* send OFDM setenv command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003458 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003459 if (status < 0)
3460 goto error;
3461
3462 /* reset datapath for OFDM, processors first */
3463 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3464 if (status < 0)
3465 goto error;
3466 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3467 if (status < 0)
3468 goto error;
3469 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3470 if (status < 0)
3471 goto error;
3472
3473 /* IQM setup */
3474 /* synchronize on ofdstate->m_festart */
3475 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3476 if (status < 0)
3477 goto error;
3478 /* window size for clipping ADC detection */
3479 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3480 if (status < 0)
3481 goto error;
3482 /* window size for for sense pre-SAW detection */
3483 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3484 if (status < 0)
3485 goto error;
3486 /* sense threshold for sense pre-SAW detection */
3487 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3488 if (status < 0)
3489 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003490 status = set_iqm_af(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003491 if (status < 0)
3492 goto error;
3493
3494 status = write16(state, IQM_AF_AGC_RF__A, 0);
3495 if (status < 0)
3496 goto error;
3497
3498 /* Impulse noise cruncher setup */
3499 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3500 if (status < 0)
3501 goto error;
3502 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3503 if (status < 0)
3504 goto error;
3505 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3506 if (status < 0)
3507 goto error;
3508
3509 status = write16(state, IQM_RC_STRETCH__A, 16);
3510 if (status < 0)
3511 goto error;
3512 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3513 if (status < 0)
3514 goto error;
3515 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3516 if (status < 0)
3517 goto error;
3518 status = write16(state, IQM_CF_SCALE__A, 1600);
3519 if (status < 0)
3520 goto error;
3521 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3522 if (status < 0)
3523 goto error;
3524
3525 /* virtual clipping threshold for clipping ADC detection */
3526 status = write16(state, IQM_AF_CLP_TH__A, 448);
3527 if (status < 0)
3528 goto error;
3529 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3530 if (status < 0)
3531 goto error;
3532
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003533 status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003534 if (status < 0)
3535 goto error;
3536
3537 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3538 if (status < 0)
3539 goto error;
3540 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3541 if (status < 0)
3542 goto error;
3543 /* enable power measurement interrupt */
3544 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3545 if (status < 0)
3546 goto error;
3547 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3548 if (status < 0)
3549 goto error;
3550
3551 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003552 status = adc_synchronization(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003553 if (status < 0)
3554 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003555 status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003556 if (status < 0)
3557 goto error;
3558
3559 /* Halt SCU to enable safe non-atomic accesses */
3560 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3561 if (status < 0)
3562 goto error;
3563
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003564 status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003565 if (status < 0)
3566 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003567 status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003568 if (status < 0)
3569 goto error;
3570
3571 /* Set Noise Estimation notch width and enable DC fix */
3572 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3573 if (status < 0)
3574 goto error;
3575 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3576 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3577 if (status < 0)
3578 goto error;
3579
3580 /* Activate SCU to enable SCU commands */
3581 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3582 if (status < 0)
3583 goto error;
3584
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003585 if (!state->m_drxk_a3_rom_code) {
3586 /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */
3587 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003588 if (status < 0)
3589 goto error;
3590 }
3591
3592 /* OFDM_SC setup */
3593#ifdef COMPILE_FOR_NONRT
3594 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3595 if (status < 0)
3596 goto error;
3597 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3598 if (status < 0)
3599 goto error;
3600#endif
3601
3602 /* FEC setup */
3603 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3604 if (status < 0)
3605 goto error;
3606
3607
3608#ifdef COMPILE_FOR_NONRT
3609 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3610 if (status < 0)
3611 goto error;
3612#else
3613 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3614 if (status < 0)
3615 goto error;
3616#endif
3617 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3618 if (status < 0)
3619 goto error;
3620
3621 /* Setup MPEG bus */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003622 status = mpegts_dto_setup(state, OM_DVBT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003623 if (status < 0)
3624 goto error;
3625 /* Set DVBT Presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003626 status = dvbt_activate_presets(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003627 if (status < 0)
3628 goto error;
3629
3630error:
3631 if (status < 0)
3632 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003633 return status;
3634}
3635
3636/*============================================================================*/
3637/**
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003638* \brief start dvbt demodulating for channel.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003639* \param demod instance of demodulator.
3640* \return DRXStatus_t.
3641*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003642static int dvbt_start(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003643{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003644 u16 param1;
3645 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003646 /* drxk_ofdm_sc_cmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003647
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003648 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003649 /* start correct processes to get in lock */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003650 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003651 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003652 status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003653 if (status < 0)
3654 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003655 /* start FEC OC */
3656 status = mpegts_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003657 if (status < 0)
3658 goto error;
3659 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3660 if (status < 0)
3661 goto error;
3662error:
3663 if (status < 0)
3664 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003665 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003666}
3667
3668
3669/*============================================================================*/
3670
3671/**
3672* \brief Set up dvbt demodulator for channel.
3673* \param demod instance of demodulator.
3674* \return DRXStatus_t.
3675* // original DVBTSetChannel()
3676*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003677static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3678 s32 tuner_freq_offset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003679{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003680 u16 cmd_result = 0;
3681 u16 transmission_params = 0;
3682 u16 operation_mode = 0;
3683 u32 iqm_rc_rate_ofs = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003684 u32 bandwidth = 0;
3685 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003686 int status;
3687
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003688 dprintk(1, "IF =%d, TFO = %d\n", intermediate_freqk_hz, tuner_freq_offset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003689
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003690 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003691 if (status < 0)
3692 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003693
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003694 /* Halt SCU to enable safe non-atomic accesses */
3695 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3696 if (status < 0)
3697 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003698
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003699 /* Stop processors */
3700 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3701 if (status < 0)
3702 goto error;
3703 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3704 if (status < 0)
3705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003707 /* Mandatory fix, always stop CP, required to set spl offset back to
3708 hardware default (is set to 0 by ucode during pilot detection */
3709 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3710 if (status < 0)
3711 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003713 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003715 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003716 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003717 case TRANSMISSION_MODE_AUTO:
3718 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003719 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003720 /* fall through , try first guess DRX_FFTMODE_8K */
3721 case TRANSMISSION_MODE_8K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003722 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003723 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003724 case TRANSMISSION_MODE_2K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003725 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003726 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003727 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003729 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003730 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003731 default:
3732 case GUARD_INTERVAL_AUTO:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003733 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003734 /* fall through , try first guess DRX_GUARD_1DIV4 */
3735 case GUARD_INTERVAL_1_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003736 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003737 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003738 case GUARD_INTERVAL_1_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003739 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003740 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003741 case GUARD_INTERVAL_1_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003742 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003743 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003744 case GUARD_INTERVAL_1_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003745 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003746 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003747 }
3748
3749 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003750 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003751 case HIERARCHY_AUTO:
3752 case HIERARCHY_NONE:
3753 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003754 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003755 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003756 /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003757 /* break; */
3758 case HIERARCHY_1:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003759 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003760 break;
3761 case HIERARCHY_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003762 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003763 break;
3764 case HIERARCHY_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003765 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003766 break;
3767 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003768
3769
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003770 /* modulation */
3771 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003772 case QAM_AUTO:
3773 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003774 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003775 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3776 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003777 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003778 break;
3779 case QPSK:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003780 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003781 break;
3782 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003783 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003784 break;
3785 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003786#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003787 /* No hierachical channels support in BDA */
3788 /* Priority (only for hierarchical channels) */
3789 switch (channel->priority) {
3790 case DRX_PRIORITY_LOW:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003791 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3792 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003793 OFDM_EC_SB_PRIOR_LO);
3794 break;
3795 case DRX_PRIORITY_HIGH:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003796 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3797 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003798 OFDM_EC_SB_PRIOR_HI));
3799 break;
3800 case DRX_PRIORITY_UNKNOWN: /* fall through */
3801 default:
3802 status = -EINVAL;
3803 goto error;
3804 }
3805#else
3806 /* Set Priorty high */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003807 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003808 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3809 if (status < 0)
3810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003811#endif
3812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003814 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003815 case FEC_AUTO:
3816 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003817 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003818 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3819 case FEC_2_3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003820 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003821 break;
3822 case FEC_1_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003823 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003824 break;
3825 case FEC_3_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003826 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003827 break;
3828 case FEC_5_6:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003829 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 break;
3831 case FEC_7_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003832 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 break;
3834 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003835
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003836 /* SAW filter selection: normaly not necesarry, but if wanted
3837 the application can select a SAW filter via the driver by using UIOs */
3838 /* First determine real bandwidth (Hz) */
3839 /* Also set delay for impulse noise cruncher */
3840 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3841 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3842 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003843 switch (state->props.bandwidth_hz) {
3844 case 0:
3845 state->props.bandwidth_hz = 8000000;
3846 /* fall though */
3847 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003848 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3849 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003850 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003851 goto error;
3852 /* cochannel protection for PAL 8 MHz */
3853 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3854 if (status < 0)
3855 goto error;
3856 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3857 if (status < 0)
3858 goto error;
3859 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3860 if (status < 0)
3861 goto error;
3862 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3863 if (status < 0)
3864 goto error;
3865 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003866 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003867 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3868 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3869 if (status < 0)
3870 goto error;
3871 /* cochannel protection for PAL 7 MHz */
3872 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3873 if (status < 0)
3874 goto error;
3875 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3876 if (status < 0)
3877 goto error;
3878 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3879 if (status < 0)
3880 goto error;
3881 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3882 if (status < 0)
3883 goto error;
3884 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003885 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003886 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3887 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3888 if (status < 0)
3889 goto error;
3890 /* cochannel protection for NTSC 6 MHz */
3891 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3892 if (status < 0)
3893 goto error;
3894 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3895 if (status < 0)
3896 goto error;
3897 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3898 if (status < 0)
3899 goto error;
3900 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3901 if (status < 0)
3902 goto error;
3903 break;
3904 default:
3905 status = -EINVAL;
3906 goto error;
3907 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003908
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003909 if (iqm_rc_rate_ofs == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003910 /* Now compute IQM_RC_RATE_OFS
3911 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3912 =>
3913 ((SysFreq / BandWidth) * (2^21)) - (2^23)
3914 */
3915 /* (SysFreq / BandWidth) * (2^28) */
3916 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3917 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3918 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003919 iqm_rc_rate_ofs = Frac28a((u32)
3920 ((state->m_sys_clock_freq *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003921 1000) / 3), bandwidth);
3922 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003923 if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
3924 iqm_rc_rate_ofs += 0x80L;
3925 iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003926 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003927 iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003928 }
3929
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003930 iqm_rc_rate_ofs &=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003931 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3932 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003933 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003934 if (status < 0)
3935 goto error;
3936
3937 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003938
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003939#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003940 status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003941 if (status < 0)
3942 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003943#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003944 status = set_frequency_shifter(state, intermediate_freqk_hz, tuner_freq_offset, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003945 if (status < 0)
3946 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003947
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003948 /*== start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003949
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003950 /* Activate SCU to enable SCU commands */
3951 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3952 if (status < 0)
3953 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003954
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003955 /* Enable SC after setting all other parameters */
3956 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
3957 if (status < 0)
3958 goto error;
3959 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
3960 if (status < 0)
3961 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003962
3963
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003964 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003965 if (status < 0)
3966 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003967
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003968 /* Write SC parameter registers, set all AUTO flags in operation mode */
3969 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3970 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3971 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3972 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3973 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003974 status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
3975 0, transmission_params, param1, 0, 0, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003976 if (status < 0)
3977 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003978
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003979 if (!state->m_drxk_a3_rom_code)
3980 status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003981error:
3982 if (status < 0)
3983 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003984
3985 return status;
3986}
3987
3988
3989/*============================================================================*/
3990
3991/**
3992* \brief Retreive lock status .
3993* \param demod Pointer to demodulator instance.
3994* \param lockStat Pointer to lock status structure.
3995* \return DRXStatus_t.
3996*
3997*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003998static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003999{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004000 int status;
4001 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4002 OFDM_SC_RA_RAM_LOCK_FEC__M);
4003 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4004 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004005
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004006 u16 sc_ra_ram_lock = 0;
4007 u16 sc_comm_exec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004008
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004009 dprintk(1, "\n");
4010
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004011 *p_lock_status = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004012 /* driver 0.9.0 */
4013 /* Check if SC is running */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004014 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004015 if (status < 0)
4016 goto end;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004017 if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004018 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004019
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004020 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004021 if (status < 0)
4022 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004023
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004024 if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4025 *p_lock_status = MPEG_LOCK;
4026 else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4027 *p_lock_status = FEC_LOCK;
4028 else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4029 *p_lock_status = DEMOD_LOCK;
4030 else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4031 *p_lock_status = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004032end:
4033 if (status < 0)
4034 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004035
Oliver Endrissebc7de22011-07-03 13:49:44 -03004036 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004037}
4038
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004039static int power_up_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004040{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004041 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004042 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004043
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004044 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004045 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004046 if (status < 0)
4047 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004048
Oliver Endrissebc7de22011-07-03 13:49:44 -03004049 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004050}
4051
4052
Oliver Endrissebc7de22011-07-03 13:49:44 -03004053/** Power Down QAM */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004054static int power_down_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004056 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004057 u16 cmd_result;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004058 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004059
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004060 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004061 status = read16(state, SCU_COMM_EXEC__A, &data);
4062 if (status < 0)
4063 goto error;
4064 if (data == SCU_COMM_EXEC_ACTIVE) {
4065 /*
4066 STOP demodulator
4067 QAM and HW blocks
4068 */
4069 /* stop all comstate->m_exec */
4070 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004071 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004072 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004073 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004074 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004075 goto error;
4076 }
4077 /* powerdown AFE */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004078 status = set_iqm_af(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004079
4080error:
4081 if (status < 0)
4082 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004083
Oliver Endrissebc7de22011-07-03 13:49:44 -03004084 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004085}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004086
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004087/*============================================================================*/
4088
4089/**
4090* \brief Setup of the QAM Measurement intervals for signal quality
4091* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004092* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004093* \return DRXStatus_t.
4094*
4095* NOTE:
4096* Take into account that for certain settings the errorcounters can overflow.
4097* The implementation does not check this.
4098*
4099*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004100static int set_qam_measurement(struct drxk_state *state,
4101 enum e_drxk_constellation modulation,
4102 u32 symbol_rate)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004103{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004104 u32 fec_bits_desired = 0; /* BER accounting period */
4105 u32 fec_rs_period_total = 0; /* Total period */
4106 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
4107 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004108 int status = 0;
4109
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004110 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004112 fec_rs_prescale = 1;
4113 /* fec_bits_desired = symbol_rate [kHz] *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004114 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004115 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004116 SyncLoss (== 1) *
4117 ViterbiLoss (==1)
4118 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004119 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004120 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004121 fec_bits_desired = 4 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004122 break;
4123 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004124 fec_bits_desired = 5 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004125 break;
4126 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004127 fec_bits_desired = 6 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004128 break;
4129 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004130 fec_bits_desired = 7 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004131 break;
4132 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004133 fec_bits_desired = 8 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004134 break;
4135 default:
4136 status = -EINVAL;
4137 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004138 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004139 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004140
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004141 fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */
4142 fec_bits_desired *= 500; /* meas. period [ms] */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004143
4144 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004145 /* fec_rs_period_total = fec_bits_desired / 1632 */
4146 fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004147
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004148 /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */
4149 fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4150 if (fec_rs_prescale == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004151 /* Divide by zero (though impossible) */
4152 status = -EINVAL;
4153 if (status < 0)
4154 goto error;
4155 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004156 fec_rs_period =
4157 ((u16) fec_rs_period_total +
4158 (fec_rs_prescale >> 1)) / fec_rs_prescale;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004159
4160 /* write corresponding registers */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004161 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004162 if (status < 0)
4163 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004164 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004165 if (status < 0)
4166 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004167 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004168error:
4169 if (status < 0)
4170 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004171 return status;
4172}
4173
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004174static int set_qam16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004175{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004176 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004177
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004178 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004179 /* QAM Equalizer Setup */
4180 /* Equalizer */
4181 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4182 if (status < 0)
4183 goto error;
4184 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4185 if (status < 0)
4186 goto error;
4187 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4188 if (status < 0)
4189 goto error;
4190 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4191 if (status < 0)
4192 goto error;
4193 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4194 if (status < 0)
4195 goto error;
4196 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4197 if (status < 0)
4198 goto error;
4199 /* Decision Feedback Equalizer */
4200 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4201 if (status < 0)
4202 goto error;
4203 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4204 if (status < 0)
4205 goto error;
4206 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4207 if (status < 0)
4208 goto error;
4209 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4210 if (status < 0)
4211 goto error;
4212 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4213 if (status < 0)
4214 goto error;
4215 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4216 if (status < 0)
4217 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004218
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004219 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4220 if (status < 0)
4221 goto error;
4222 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4223 if (status < 0)
4224 goto error;
4225 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4226 if (status < 0)
4227 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004229 /* QAM Slicer Settings */
4230 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4231 if (status < 0)
4232 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004233
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004234 /* QAM Loop Controller Coeficients */
4235 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4236 if (status < 0)
4237 goto error;
4238 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4239 if (status < 0)
4240 goto error;
4241 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4242 if (status < 0)
4243 goto error;
4244 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4245 if (status < 0)
4246 goto error;
4247 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4248 if (status < 0)
4249 goto error;
4250 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4251 if (status < 0)
4252 goto error;
4253 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4254 if (status < 0)
4255 goto error;
4256 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4257 if (status < 0)
4258 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004259
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004260 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4261 if (status < 0)
4262 goto error;
4263 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4264 if (status < 0)
4265 goto error;
4266 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4267 if (status < 0)
4268 goto error;
4269 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4270 if (status < 0)
4271 goto error;
4272 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4273 if (status < 0)
4274 goto error;
4275 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4276 if (status < 0)
4277 goto error;
4278 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4279 if (status < 0)
4280 goto error;
4281 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4282 if (status < 0)
4283 goto error;
4284 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4285 if (status < 0)
4286 goto error;
4287 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4294 if (status < 0)
4295 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004296
4297
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004298 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004299
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004300 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4301 if (status < 0)
4302 goto error;
4303 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4304 if (status < 0)
4305 goto error;
4306 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4316 if (status < 0)
4317 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004318
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004319 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4320 if (status < 0)
4321 goto error;
4322 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4323 if (status < 0)
4324 goto error;
4325 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4326 if (status < 0)
4327 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004328
4329
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004330 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004331
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004332 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4333 if (status < 0)
4334 goto error;
4335 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4336 if (status < 0)
4337 goto error;
4338 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4339 if (status < 0)
4340 goto error;
4341 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4351 if (status < 0)
4352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004354error:
4355 if (status < 0)
4356 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004357 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004358}
4359
4360/*============================================================================*/
4361
4362/**
4363* \brief QAM32 specific setup
4364* \param demod instance of demod.
4365* \return DRXStatus_t.
4366*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004367static int set_qam32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004368{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004369 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004370
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004371 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004372
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004373 /* QAM Equalizer Setup */
4374 /* Equalizer */
4375 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4391 if (status < 0)
4392 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004393
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004394 /* Decision Feedback Equalizer */
4395 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4396 if (status < 0)
4397 goto error;
4398 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4411 if (status < 0)
4412 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004413
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004414 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4415 if (status < 0)
4416 goto error;
4417 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4421 if (status < 0)
4422 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004423
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004424 /* QAM Slicer Settings */
4425
4426 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4427 if (status < 0)
4428 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004429
4430
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004431 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004432
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004433 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4449 if (status < 0)
4450 goto error;
4451 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4452 if (status < 0)
4453 goto error;
4454 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4455 if (status < 0)
4456 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004458 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4459 if (status < 0)
4460 goto error;
4461 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4462 if (status < 0)
4463 goto error;
4464 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4465 if (status < 0)
4466 goto error;
4467 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4468 if (status < 0)
4469 goto error;
4470 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4471 if (status < 0)
4472 goto error;
4473 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4489 if (status < 0)
4490 goto error;
4491 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4492 if (status < 0)
4493 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004494
4495
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004496 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004497
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004498 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4499 if (status < 0)
4500 goto error;
4501 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4514 if (status < 0)
4515 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004517 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4518 if (status < 0)
4519 goto error;
4520 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4521 if (status < 0)
4522 goto error;
4523 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4524 if (status < 0)
4525 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004526
4527
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004528 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004529
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004530 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4531 if (status < 0)
4532 goto error;
4533 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4534 if (status < 0)
4535 goto error;
4536 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4537 if (status < 0)
4538 goto error;
4539 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4549error:
4550 if (status < 0)
4551 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004552 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004553}
4554
4555/*============================================================================*/
4556
4557/**
4558* \brief QAM64 specific setup
4559* \param demod instance of demod.
4560* \return DRXStatus_t.
4561*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004562static int set_qam64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004563{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004564 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004565
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004566 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004567 /* QAM Equalizer Setup */
4568 /* Equalizer */
4569 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4570 if (status < 0)
4571 goto error;
4572 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4573 if (status < 0)
4574 goto error;
4575 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4576 if (status < 0)
4577 goto error;
4578 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4579 if (status < 0)
4580 goto error;
4581 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4582 if (status < 0)
4583 goto error;
4584 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4585 if (status < 0)
4586 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004587
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004588 /* Decision Feedback Equalizer */
4589 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4590 if (status < 0)
4591 goto error;
4592 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4593 if (status < 0)
4594 goto error;
4595 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4596 if (status < 0)
4597 goto error;
4598 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4599 if (status < 0)
4600 goto error;
4601 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4602 if (status < 0)
4603 goto error;
4604 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4605 if (status < 0)
4606 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004607
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004608 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4612 if (status < 0)
4613 goto error;
4614 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4615 if (status < 0)
4616 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004618 /* QAM Slicer Settings */
4619 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4620 if (status < 0)
4621 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004622
4623
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004624 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004625
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004626 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4627 if (status < 0)
4628 goto error;
4629 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4630 if (status < 0)
4631 goto error;
4632 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4633 if (status < 0)
4634 goto error;
4635 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4636 if (status < 0)
4637 goto error;
4638 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4639 if (status < 0)
4640 goto error;
4641 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4642 if (status < 0)
4643 goto error;
4644 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4645 if (status < 0)
4646 goto error;
4647 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4648 if (status < 0)
4649 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004651 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4652 if (status < 0)
4653 goto error;
4654 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4655 if (status < 0)
4656 goto error;
4657 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4658 if (status < 0)
4659 goto error;
4660 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4661 if (status < 0)
4662 goto error;
4663 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4664 if (status < 0)
4665 goto error;
4666 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4667 if (status < 0)
4668 goto error;
4669 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4670 if (status < 0)
4671 goto error;
4672 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4673 if (status < 0)
4674 goto error;
4675 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4685 if (status < 0)
4686 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004687
4688
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004689 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004690
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004691 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4692 if (status < 0)
4693 goto error;
4694 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4695 if (status < 0)
4696 goto error;
4697 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4698 if (status < 0)
4699 goto error;
4700 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4701 if (status < 0)
4702 goto error;
4703 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4704 if (status < 0)
4705 goto error;
4706 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4707 if (status < 0)
4708 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004709
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004710 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4711 if (status < 0)
4712 goto error;
4713 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4714 if (status < 0)
4715 goto error;
4716 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4717 if (status < 0)
4718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004719
4720
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004721 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004722
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004723 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4724 if (status < 0)
4725 goto error;
4726 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4727 if (status < 0)
4728 goto error;
4729 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4730 if (status < 0)
4731 goto error;
4732 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4742error:
4743 if (status < 0)
4744 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004745
Oliver Endrissebc7de22011-07-03 13:49:44 -03004746 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004747}
4748
4749/*============================================================================*/
4750
4751/**
4752* \brief QAM128 specific setup
4753* \param demod: instance of demod.
4754* \return DRXStatus_t.
4755*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004756static int set_qam128(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004757{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004758 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004759
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004760 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004761 /* QAM Equalizer Setup */
4762 /* Equalizer */
4763 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4779 if (status < 0)
4780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004782 /* Decision Feedback Equalizer */
4783 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4784 if (status < 0)
4785 goto error;
4786 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4787 if (status < 0)
4788 goto error;
4789 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4799 if (status < 0)
4800 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004801
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004802 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4803 if (status < 0)
4804 goto error;
4805 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4806 if (status < 0)
4807 goto error;
4808 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4809 if (status < 0)
4810 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004811
4812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004813 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004814
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004815 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4816 if (status < 0)
4817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004818
4819
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004820 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004821
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004822 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4823 if (status < 0)
4824 goto error;
4825 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4826 if (status < 0)
4827 goto error;
4828 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4829 if (status < 0)
4830 goto error;
4831 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4832 if (status < 0)
4833 goto error;
4834 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4835 if (status < 0)
4836 goto error;
4837 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4838 if (status < 0)
4839 goto error;
4840 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4841 if (status < 0)
4842 goto error;
4843 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4844 if (status < 0)
4845 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004846
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004847 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4848 if (status < 0)
4849 goto error;
4850 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4851 if (status < 0)
4852 goto error;
4853 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4854 if (status < 0)
4855 goto error;
4856 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4857 if (status < 0)
4858 goto error;
4859 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4860 if (status < 0)
4861 goto error;
4862 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4863 if (status < 0)
4864 goto error;
4865 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4866 if (status < 0)
4867 goto error;
4868 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4869 if (status < 0)
4870 goto error;
4871 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4872 if (status < 0)
4873 goto error;
4874 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4875 if (status < 0)
4876 goto error;
4877 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4878 if (status < 0)
4879 goto error;
4880 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4881 if (status < 0)
4882 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004883
4884
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004885 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004886
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004887 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4897 if (status < 0)
4898 goto error;
4899 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4900 if (status < 0)
4901 goto error;
4902 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4903 if (status < 0)
4904 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004905
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004906 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4907 if (status < 0)
4908 goto error;
4909 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4910 if (status < 0)
4911 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004912
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004913 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4914 if (status < 0)
4915 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004916
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004917 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4920 if (status < 0)
4921 goto error;
4922 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4923 if (status < 0)
4924 goto error;
4925 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4926 if (status < 0)
4927 goto error;
4928 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
4938error:
4939 if (status < 0)
4940 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004941
Oliver Endrissebc7de22011-07-03 13:49:44 -03004942 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004943}
4944
4945/*============================================================================*/
4946
4947/**
4948* \brief QAM256 specific setup
4949* \param demod: instance of demod.
4950* \return DRXStatus_t.
4951*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004952static int set_qam256(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004953{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004954 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004955
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004956 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004957 /* QAM Equalizer Setup */
4958 /* Equalizer */
4959 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
4975 if (status < 0)
4976 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004977
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004978 /* Decision Feedback Equalizer */
4979 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
4980 if (status < 0)
4981 goto error;
4982 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
4983 if (status < 0)
4984 goto error;
4985 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4995 if (status < 0)
4996 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004997
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004998 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4999 if (status < 0)
5000 goto error;
5001 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5002 if (status < 0)
5003 goto error;
5004 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5005 if (status < 0)
5006 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005007
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005008 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005009
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005010 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5011 if (status < 0)
5012 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005013
5014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005015 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005017 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5036 if (status < 0)
5037 goto error;
5038 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5039 if (status < 0)
5040 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005041
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005042 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5043 if (status < 0)
5044 goto error;
5045 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5046 if (status < 0)
5047 goto error;
5048 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5049 if (status < 0)
5050 goto error;
5051 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5052 if (status < 0)
5053 goto error;
5054 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5055 if (status < 0)
5056 goto error;
5057 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5073 if (status < 0)
5074 goto error;
5075 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5076 if (status < 0)
5077 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005078
5079
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005080 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005082 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5083 if (status < 0)
5084 goto error;
5085 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5098 if (status < 0)
5099 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005100
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005101 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5102 if (status < 0)
5103 goto error;
5104 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5105 if (status < 0)
5106 goto error;
5107 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5108 if (status < 0)
5109 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005110
5111
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005112 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005114 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5115 if (status < 0)
5116 goto error;
5117 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5118 if (status < 0)
5119 goto error;
5120 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5121 if (status < 0)
5122 goto error;
5123 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5133error:
5134 if (status < 0)
5135 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005136 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005137}
5138
5139
5140/*============================================================================*/
5141/**
5142* \brief Reset QAM block.
5143* \param demod: instance of demod.
5144* \param channel: pointer to channel data.
5145* \return DRXStatus_t.
5146*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005147static int qam_reset_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005148{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005149 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005150 u16 cmd_result;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005151
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005152 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005153 /* Stop QAM comstate->m_exec */
5154 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5155 if (status < 0)
5156 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005157
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005158 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005159error:
5160 if (status < 0)
5161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005162 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005163}
5164
5165/*============================================================================*/
5166
5167/**
5168* \brief Set QAM symbolrate.
5169* \param demod: instance of demod.
5170* \param channel: pointer to channel data.
5171* \return DRXStatus_t.
5172*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005173static int qam_set_symbolrate(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005174{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005175 u32 adc_frequency = 0;
5176 u32 symb_freq = 0;
5177 u32 iqm_rc_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005178 u16 ratesel = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005179 u32 lc_symb_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005180 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005181
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005182 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005183 /* Select & calculate correct IQM rate */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005184 adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005185 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005186 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5187 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005188 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005189 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005190 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005191 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005192 ratesel = 1;
5193 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5194 if (status < 0)
5195 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005196
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005197 /*
5198 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5199 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005200 symb_freq = state->props.symbol_rate * (1 << ratesel);
5201 if (symb_freq == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005202 /* Divide by zero */
5203 status = -EINVAL;
5204 goto error;
5205 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005206 iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5207 (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005208 (1 << 23);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005209 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005210 if (status < 0)
5211 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005212 state->m_iqm_rc_rate = iqm_rc_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005213 /*
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005214 LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005215 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005216 symb_freq = state->props.symbol_rate;
5217 if (adc_frequency == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005218 /* Divide by zero */
5219 status = -EINVAL;
5220 goto error;
5221 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005222 lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5223 (Frac28a((symb_freq % adc_frequency), adc_frequency) >>
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005224 16);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005225 if (lc_symb_rate > 511)
5226 lc_symb_rate = 511;
5227 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005228
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005229error:
5230 if (status < 0)
5231 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005232 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005233}
5234
5235/*============================================================================*/
5236
5237/**
5238* \brief Get QAM lock status.
5239* \param demod: instance of demod.
5240* \param channel: pointer to channel data.
5241* \return DRXStatus_t.
5242*/
5243
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005244static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005245{
5246 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005247 u16 result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005248
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005249 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005250 *p_lock_status = NOT_LOCKED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005251 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005252 SCU_RAM_COMMAND_STANDARD_QAM |
5253 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005254 result);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005255 if (status < 0)
Martin Blumenstingl257ee972012-07-04 17:38:23 -03005256 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005257
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005258 if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005259 /* 0x0000 NOT LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005260 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005261 /* 0x4000 DEMOD LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005262 *p_lock_status = DEMOD_LOCK;
5263 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005264 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005265 *p_lock_status = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005266 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005267 /* 0xC000 NEVER LOCKED */
5268 /* (system will never be able to lock to the signal) */
5269 /* TODO: check this, intermediate & standard specific lock states are not
5270 taken into account here */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005271 *p_lock_status = NEVER_LOCK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005272 }
5273 return status;
5274}
5275
5276#define QAM_MIRROR__M 0x03
5277#define QAM_MIRROR_NORMAL 0x00
5278#define QAM_MIRRORED 0x01
5279#define QAM_MIRROR_AUTO_ON 0x02
5280#define QAM_LOCKRANGE__M 0x10
5281#define QAM_LOCKRANGE_NORMAL 0x10
5282
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005283static int qam_demodulator_command(struct drxk_state *state,
5284 int number_of_parameters)
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005285{
5286 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005287 u16 cmd_result;
5288 u16 set_param_parameters[4] = { 0, 0, 0, 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005289
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005290 set_param_parameters[0] = state->m_constellation; /* modulation */
5291 set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005292
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005293 if (number_of_parameters == 2) {
5294 u16 set_env_parameters[1] = { 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005295
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005296 if (state->m_operation_mode == OM_QAM_ITU_C)
5297 set_env_parameters[0] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005298 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005299 set_env_parameters[0] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005300
5301 status = scu_command(state,
5302 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005303 1, set_env_parameters, 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005304 if (status < 0)
5305 goto error;
5306
5307 status = scu_command(state,
5308 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005309 number_of_parameters, set_param_parameters,
5310 1, &cmd_result);
5311 } else if (number_of_parameters == 4) {
5312 if (state->m_operation_mode == OM_QAM_ITU_C)
5313 set_param_parameters[2] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005314 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005315 set_param_parameters[2] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005316
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005317 set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005318 /* Env parameters */
5319 /* check for LOCKRANGE Extented */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005320 /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005321
5322 status = scu_command(state,
5323 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005324 number_of_parameters, set_param_parameters,
5325 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005326 } else {
5327 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005328 "count %d\n", number_of_parameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005329 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005330 }
5331
5332error:
5333 if (status < 0)
5334 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5335 status, __func__);
5336 return status;
5337}
5338
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005339static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5340 s32 tuner_freq_offset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005341{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005342 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005343 u16 cmd_result;
5344 int qam_demod_param_count = state->qam_demod_parameter_count;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005345
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005346 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005347 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005348 * STEP 1: reset demodulator
5349 * resets FEC DI and FEC RS
5350 * resets QAM block
5351 * resets SCU variables
5352 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005353 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005354 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005355 goto error;
5356 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5357 if (status < 0)
5358 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005359 status = qam_reset_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005360 if (status < 0)
5361 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005362
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005363 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005364 * STEP 2: configure demodulator
5365 * -set params; resets IQM,QAM,FEC HW; initializes some
5366 * SCU variables
5367 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005368 status = qam_set_symbolrate(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005369 if (status < 0)
5370 goto error;
5371
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005372 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005373 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005374 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005375 state->m_constellation = DRX_CONSTELLATION_QAM256;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005376 break;
5377 case QAM_AUTO:
5378 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005379 state->m_constellation = DRX_CONSTELLATION_QAM64;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005380 break;
5381 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005382 state->m_constellation = DRX_CONSTELLATION_QAM16;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005383 break;
5384 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005385 state->m_constellation = DRX_CONSTELLATION_QAM32;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005386 break;
5387 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005388 state->m_constellation = DRX_CONSTELLATION_QAM128;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005389 break;
5390 default:
5391 status = -EINVAL;
5392 break;
5393 }
5394 if (status < 0)
5395 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005396
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005397 /* Use the 4-parameter if it's requested or we're probing for
5398 * the correct command. */
5399 if (state->qam_demod_parameter_count == 4
5400 || !state->qam_demod_parameter_count) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005401 qam_demod_param_count = 4;
5402 status = qam_demodulator_command(state, qam_demod_param_count);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005403 }
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005404
5405 /* Use the 2-parameter command if it was requested or if we're
5406 * probing for the correct command and the 4-parameter command
5407 * failed. */
5408 if (state->qam_demod_parameter_count == 2
5409 || (!state->qam_demod_parameter_count && status < 0)) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005410 qam_demod_param_count = 2;
5411 status = qam_demodulator_command(state, qam_demod_param_count);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005412 }
5413
5414 if (status < 0) {
5415 dprintk(1, "Could not set demodulator parameters. Make "
5416 "sure qam_demod_parameter_count (%d) is correct for "
5417 "your firmware (%s).\n",
5418 state->qam_demod_parameter_count,
5419 state->microcode_name);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005420 goto error;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005421 } else if (!state->qam_demod_parameter_count) {
5422 dprintk(1, "Auto-probing the correct QAM demodulator command "
5423 "parameters was successful - using %d parameters.\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005424 qam_demod_param_count);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005425
Mauro Carvalho Chehab7eaf71882012-07-06 14:53:51 -03005426 /*
5427 * One of our commands was successful. We don't need to
5428 * auto-probe anymore, now that we got the correct command.
5429 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005430 state->qam_demod_parameter_count = qam_demod_param_count;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005431 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005432
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005433 /*
5434 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005435 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005436 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005437#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005438 status = set_frequency(channel, tuner_freq_offset));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005439 if (status < 0)
5440 goto error;
5441#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005442 status = set_frequency_shifter(state, intermediate_freqk_hz, tuner_freq_offset, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005443 if (status < 0)
5444 goto error;
5445
5446 /* Setup BER measurement */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005447 status = set_qam_measurement(state, state->m_constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005448 if (status < 0)
5449 goto error;
5450
5451 /* Reset default values */
5452 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5453 if (status < 0)
5454 goto error;
5455 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5456 if (status < 0)
5457 goto error;
5458
5459 /* Reset default LC values */
5460 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5461 if (status < 0)
5462 goto error;
5463 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5464 if (status < 0)
5465 goto error;
5466 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5467 if (status < 0)
5468 goto error;
5469 status = write16(state, QAM_LC_MODE__A, 7);
5470 if (status < 0)
5471 goto error;
5472
5473 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5474 if (status < 0)
5475 goto error;
5476 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5477 if (status < 0)
5478 goto error;
5479 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5480 if (status < 0)
5481 goto error;
5482 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5483 if (status < 0)
5484 goto error;
5485 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5486 if (status < 0)
5487 goto error;
5488 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5489 if (status < 0)
5490 goto error;
5491 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5492 if (status < 0)
5493 goto error;
5494 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5504 if (status < 0)
5505 goto error;
5506 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5507 if (status < 0)
5508 goto error;
5509 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5510 if (status < 0)
5511 goto error;
5512 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5513 if (status < 0)
5514 goto error;
5515 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5516 if (status < 0)
5517 goto error;
5518
5519 /* Mirroring, QAM-block starting point not inverted */
5520 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5521 if (status < 0)
5522 goto error;
5523
5524 /* Halt SCU to enable safe non-atomic accesses */
5525 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5526 if (status < 0)
5527 goto error;
5528
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005529 /* STEP 4: modulation specific setup */
5530 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005531 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005532 status = set_qam16(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005533 break;
5534 case QAM_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005535 status = set_qam32(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005536 break;
5537 case QAM_AUTO:
5538 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005539 status = set_qam64(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005540 break;
5541 case QAM_128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005542 status = set_qam128(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005543 break;
5544 case QAM_256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005545 status = set_qam256(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005546 break;
5547 default:
5548 status = -EINVAL;
5549 break;
5550 }
5551 if (status < 0)
5552 goto error;
5553
5554 /* Activate SCU to enable SCU commands */
5555 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5556 if (status < 0)
5557 goto error;
5558
5559 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005560 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005561 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005562 status = mpegts_dto_setup(state, state->m_operation_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005563 if (status < 0)
5564 goto error;
5565
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005566 /* start processes */
5567 status = mpegts_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005568 if (status < 0)
5569 goto error;
5570 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5571 if (status < 0)
5572 goto error;
5573 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5574 if (status < 0)
5575 goto error;
5576 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5577 if (status < 0)
5578 goto error;
5579
5580 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005581 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmd_result);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005582 if (status < 0)
5583 goto error;
5584
5585 /* update global DRXK data container */
5586/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5587
5588error:
5589 if (status < 0)
5590 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005591 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005592}
5593
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005594static int set_qam_standard(struct drxk_state *state,
5595 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005596{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005597 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005598#ifdef DRXK_QAM_TAPS
5599#define DRXK_QAMA_TAPS_SELECT
5600#include "drxk_filters.h"
5601#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005602#endif
5603
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005604 dprintk(1, "\n");
5605
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005606 /* added antenna switch */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005607 switch_antenna_to_qam(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005608
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005609 /* Ensure correct power-up mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005610 status = power_up_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005611 if (status < 0)
5612 goto error;
5613 /* Reset QAM block */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005614 status = qam_reset_qam(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005615 if (status < 0)
5616 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005618 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005619
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005620 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5621 if (status < 0)
5622 goto error;
5623 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5624 if (status < 0)
5625 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005627 /* Upload IQM Channel Filter settings by
5628 boot loader from ROM table */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005629 switch (o_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005630 case OM_QAM_ITU_A:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005631 status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005632 break;
5633 case OM_QAM_ITU_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005634 status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005635 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005636 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005637 status = bl_direct_cmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005638 break;
5639 default:
5640 status = -EINVAL;
5641 }
5642 if (status < 0)
5643 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005644
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005645 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5646 if (status < 0)
5647 goto error;
5648 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5649 if (status < 0)
5650 goto error;
5651 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5652 if (status < 0)
5653 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005654
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005655 status = write16(state, IQM_RC_STRETCH__A, 21);
5656 if (status < 0)
5657 goto error;
5658 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5659 if (status < 0)
5660 goto error;
5661 status = write16(state, IQM_AF_CLP_TH__A, 448);
5662 if (status < 0)
5663 goto error;
5664 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5665 if (status < 0)
5666 goto error;
5667 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5668 if (status < 0)
5669 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005670
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005671 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5672 if (status < 0)
5673 goto error;
5674 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5675 if (status < 0)
5676 goto error;
5677 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5678 if (status < 0)
5679 goto error;
5680 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5681 if (status < 0)
5682 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005683
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005684 /* IQM Impulse Noise Processing Unit */
5685 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5686 if (status < 0)
5687 goto error;
5688 status = write16(state, IQM_CF_DATATH__A, 1000);
5689 if (status < 0)
5690 goto error;
5691 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5692 if (status < 0)
5693 goto error;
5694 status = write16(state, IQM_CF_DET_LCT__A, 0);
5695 if (status < 0)
5696 goto error;
5697 status = write16(state, IQM_CF_WND_LEN__A, 1);
5698 if (status < 0)
5699 goto error;
5700 status = write16(state, IQM_CF_PKDTH__A, 1);
5701 if (status < 0)
5702 goto error;
5703 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5704 if (status < 0)
5705 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005706
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005707 /* turn on IQMAF. Must be done before setAgc**() */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005708 status = set_iqm_af(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5712 if (status < 0)
5713 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005714
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005715 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005716 status = adc_synchronization(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005717 if (status < 0)
5718 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005719
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005720 /* Set the FSM step period */
5721 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5722 if (status < 0)
5723 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005724
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005725 /* Halt SCU to enable safe non-atomic accesses */
5726 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5727 if (status < 0)
5728 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005730 /* No more resets of the IQM, current standard correctly set =>
5731 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005732
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005733 status = init_agc(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005734 if (status < 0)
5735 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005736 status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005737 if (status < 0)
5738 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005739
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005740 /* Configure AGC's */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005741 status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005742 if (status < 0)
5743 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005744 status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005745 if (status < 0)
5746 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005747
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005748 /* Activate SCU to enable SCU commands */
5749 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5750error:
5751 if (status < 0)
5752 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005753 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005754}
5755
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005756static int write_gpio(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005757{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005758 int status;
5759 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005760
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005761 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005762 /* stop lock indicator process */
5763 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5764 if (status < 0)
5765 goto error;
5766
5767 /* Write magic word to enable pdr reg write */
5768 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5769 if (status < 0)
5770 goto error;
5771
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005772 if (state->m_has_sawsw) {
5773 if (state->uio_mask & 0x0001) { /* UIO-1 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005774 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005775 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005776 if (status < 0)
5777 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005778
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005779 /* use corresponding bit in io data output registar */
5780 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5781 if (status < 0)
5782 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005783 if ((state->m_gpio & 0x0001) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005784 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5785 else
5786 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5787 /* write back to io data output register */
5788 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5789 if (status < 0)
5790 goto error;
5791 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005792 if (state->uio_mask & 0x0002) { /* UIO-2 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005793 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005794 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005795 if (status < 0)
5796 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005797
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005798 /* use corresponding bit in io data output registar */
5799 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5800 if (status < 0)
5801 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005802 if ((state->m_gpio & 0x0002) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005803 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5804 else
5805 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5806 /* write back to io data output register */
5807 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5808 if (status < 0)
5809 goto error;
5810 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005811 if (state->uio_mask & 0x0004) { /* UIO-3 */
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005812 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005813 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_gpio_cfg);
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005814 if (status < 0)
5815 goto error;
5816
5817 /* use corresponding bit in io data output registar */
5818 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5819 if (status < 0)
5820 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005821 if ((state->m_gpio & 0x0004) == 0)
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005822 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5823 else
5824 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5825 /* write back to io data output register */
5826 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5827 if (status < 0)
5828 goto error;
5829 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005830 }
5831 /* Write magic word to disable pdr reg write */
5832 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5833error:
5834 if (status < 0)
5835 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005836 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005837}
5838
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005839static int switch_antenna_to_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005840{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005841 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005842 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005843
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005844 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005845
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005846 if (!state->antenna_gpio)
5847 return 0;
5848
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005849 gpio_state = state->m_gpio & state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005850
5851 if (state->antenna_dvbt ^ gpio_state) {
5852 /* Antenna is on DVB-T mode. Switch */
5853 if (state->antenna_dvbt)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005854 state->m_gpio &= ~state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005855 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005856 state->m_gpio |= state->antenna_gpio;
5857 status = write_gpio(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005858 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005859 if (status < 0)
5860 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005861 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005862}
5863
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005864static int switch_antenna_to_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005865{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005866 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005867 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005868
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005869 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005870
5871 if (!state->antenna_gpio)
5872 return 0;
5873
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005874 gpio_state = state->m_gpio & state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005875
5876 if (!(state->antenna_dvbt ^ gpio_state)) {
5877 /* Antenna is on DVB-C mode. Switch */
5878 if (state->antenna_dvbt)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005879 state->m_gpio |= state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005880 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005881 state->m_gpio &= ~state->antenna_gpio;
5882 status = write_gpio(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005883 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005884 if (status < 0)
5885 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005886 return status;
5887}
5888
5889
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005890static int power_down_device(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005891{
5892 /* Power down to requested mode */
5893 /* Backup some register settings */
5894 /* Set pins with possible pull-ups connected to them in input mode */
5895 /* Analog power down */
5896 /* ADC power down */
5897 /* Power down device */
5898 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005899
5900 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005901 if (state->m_b_p_down_open_bridge) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005902 /* Open I2C bridge before power down of DRXK */
5903 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005904 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005905 goto error;
5906 }
5907 /* driver 0.9.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005908 status = dvbt_enable_ofdm_token_ring(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005909 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005910 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005911
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005912 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5913 if (status < 0)
5914 goto error;
5915 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5916 if (status < 0)
5917 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005918 state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5919 status = hi_cfg_command(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005920error:
5921 if (status < 0)
5922 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5923
5924 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005925}
5926
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005927static int init_drxk(struct drxk_state *state)
5928{
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03005929 int status = 0, n = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005930 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
5931 u16 driver_version;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005932
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005933 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005934 if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03005935 drxk_i2c_lock(state);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005936 status = power_up_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005937 if (status < 0)
5938 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005939 status = drxx_open(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005940 if (status < 0)
5941 goto error;
5942 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5943 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5944 if (status < 0)
5945 goto error;
5946 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5947 if (status < 0)
5948 goto error;
5949 /* TODO is this needed, if yes how much delay in worst case scenario */
5950 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005951 state->m_drxk_a3_patch_code = true;
5952 status = get_device_capabilities(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005953 if (status < 0)
5954 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005956 /* Bridge delay, uses oscilator clock */
5957 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
5958 /* SDA brdige delay */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005959 state->m_hi_cfg_bridge_delay =
5960 (u16) ((state->m_osc_clock_freq / 1000) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005961 HI_I2C_BRIDGE_DELAY) / 1000;
5962 /* Clipping */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005963 if (state->m_hi_cfg_bridge_delay >
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005964 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005965 state->m_hi_cfg_bridge_delay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005966 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
5967 }
5968 /* SCL bridge delay, same as SDA for now */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005969 state->m_hi_cfg_bridge_delay +=
5970 state->m_hi_cfg_bridge_delay <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005971 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005972
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005973 status = init_hi(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005974 if (status < 0)
5975 goto error;
5976 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005977#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005978 if (!(state->m_DRXK_A1_ROM_CODE)
5979 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005981 {
5982 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5983 if (status < 0)
5984 goto error;
5985 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005986
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005987 /* disable MPEG port */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005988 status = mpegts_disable(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005989 if (status < 0)
5990 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005991
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005992 /* Stop AUD and SCU */
5993 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
5994 if (status < 0)
5995 goto error;
5996 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
5997 if (status < 0)
5998 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005999
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006000 /* enable token-ring bus through OFDM block for possible ucode upload */
6001 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6002 if (status < 0)
6003 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006004
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006005 /* include boot loader section */
6006 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6007 if (status < 0)
6008 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006009 status = bl_chain_cmd(state, 0, 6, 100);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006010 if (status < 0)
6011 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006012
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006013 if (state->fw) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006014 status = download_microcode(state, state->fw->data,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006015 state->fw->size);
6016 if (status < 0)
6017 goto error;
6018 }
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006020 /* disable token-ring bus through OFDM block for possible ucode upload */
6021 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6022 if (status < 0)
6023 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006024
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006025 /* Run SCU for a little while to initialize microcode version numbers */
6026 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6027 if (status < 0)
6028 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006029 status = drxx_open(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006030 if (status < 0)
6031 goto error;
6032 /* added for test */
6033 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006034
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006035 power_mode = DRXK_POWER_DOWN_OFDM;
6036 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006037 if (status < 0)
6038 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006039
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006040 /* Stamp driver version number in SCU data RAM in BCD code
6041 Done to enable field application engineers to retreive drxdriver version
6042 via I2C from SCU RAM.
6043 Not using SCU command interface for SCU register access since no
6044 microcode may be present.
6045 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006046 driver_version =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006047 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6048 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6049 ((DRXK_VERSION_MAJOR % 10) << 4) +
6050 (DRXK_VERSION_MINOR % 10);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006051 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driver_version);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006052 if (status < 0)
6053 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006054 driver_version =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006055 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6056 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6057 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6058 (DRXK_VERSION_PATCH % 10);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006059 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driver_version);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006060 if (status < 0)
6061 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006062
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006063 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6064 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6065 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006067 /* Dirty fix of default values for ROM/PATCH microcode
6068 Dirty because this fix makes it impossible to setup suitable values
6069 before calling DRX_Open. This solution requires changes to RF AGC speed
6070 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006071
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006072 /* m_dvbt_rf_agc_cfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006073
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006074 /* Reset driver debug flags to 0 */
6075 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6076 if (status < 0)
6077 goto error;
6078 /* driver 0.9.0 */
6079 /* Setup FEC OC:
6080 NOTE: No more full FEC resets allowed afterwards!! */
6081 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6082 if (status < 0)
6083 goto error;
6084 /* MPEGTS functions are still the same */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006085 status = mpegts_dto_init(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006086 if (status < 0)
6087 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006088 status = mpegts_stop(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006089 if (status < 0)
6090 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006091 status = mpegts_configure_polarity(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006092 if (status < 0)
6093 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006094 status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006095 if (status < 0)
6096 goto error;
6097 /* added: configure GPIO */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006098 status = write_gpio(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006099 if (status < 0)
6100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006101
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006102 state->m_drxk_state = DRXK_STOPPED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006103
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006104 if (state->m_b_power_down) {
6105 status = power_down_device(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006106 if (status < 0)
6107 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006108 state->m_drxk_state = DRXK_POWERED_DOWN;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006109 } else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006110 state->m_drxk_state = DRXK_STOPPED;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006111
6112 /* Initialize the supported delivery systems */
6113 n = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006114 if (state->m_has_dvbc) {
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006115 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6116 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6117 strlcat(state->frontend.ops.info.name, " DVB-C",
6118 sizeof(state->frontend.ops.info.name));
6119 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006120 if (state->m_has_dvbt) {
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006121 state->frontend.ops.delsys[n++] = SYS_DVBT;
6122 strlcat(state->frontend.ops.info.name, " DVB-T",
6123 sizeof(state->frontend.ops.info.name));
6124 }
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006125 drxk_i2c_unlock(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006126 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006127error:
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006128 if (status < 0) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006129 state->m_drxk_state = DRXK_NO_DEV;
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006130 drxk_i2c_unlock(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006131 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -03006132 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006133
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006134 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006135}
6136
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006137static void load_firmware_cb(const struct firmware *fw,
6138 void *context)
6139{
6140 struct drxk_state *state = context;
6141
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006142 dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006143 if (!fw) {
6144 printk(KERN_ERR
6145 "drxk: Could not load firmware file %s.\n",
6146 state->microcode_name);
6147 printk(KERN_INFO
6148 "drxk: Copy %s to your hotplug directory!\n",
6149 state->microcode_name);
6150 state->microcode_name = NULL;
6151
6152 /*
6153 * As firmware is now load asynchronous, it is not possible
6154 * anymore to fail at frontend attach. We might silently
6155 * return here, and hope that the driver won't crash.
6156 * We might also change all DVB callbacks to return -ENODEV
6157 * if the device is not initialized.
6158 * As the DRX-K devices have their own internal firmware,
6159 * let's just hope that it will match a firmware revision
6160 * compatible with this driver and proceed.
6161 */
6162 }
6163 state->fw = fw;
6164
6165 init_drxk(state);
6166}
6167
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006168static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006169{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006170 struct drxk_state *state = fe->demodulator_priv;
6171
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006172 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006173 if (state->fw)
6174 release_firmware(state->fw);
6175
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006176 kfree(state);
6177}
6178
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006179static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006181 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006183 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006184
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006185 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006186 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006187 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006188 return 0;
6189
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006190 shut_down(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006191 return 0;
6192}
6193
Oliver Endrissebc7de22011-07-03 13:49:44 -03006194static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006195{
6196 struct drxk_state *state = fe->demodulator_priv;
6197
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006198 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006199
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006200 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006201 return -ENODEV;
6202
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006203 return ConfigureI2CBridge(state, enable ? true : false);
6204}
6205
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006206static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006207{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006208 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006209 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006210 struct drxk_state *state = fe->demodulator_priv;
6211 u32 IF;
6212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006213 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006214
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006215 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006216 return -ENODEV;
6217
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006218 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006219 return -EAGAIN;
6220
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006221 if (!fe->ops.tuner_ops.get_if_frequency) {
6222 printk(KERN_ERR
6223 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6224 return -EINVAL;
6225 }
6226
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006227 if (fe->ops.i2c_gate_ctrl)
6228 fe->ops.i2c_gate_ctrl(fe, 1);
6229 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006230 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006231 if (fe->ops.i2c_gate_ctrl)
6232 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006233
6234 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006235 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006236
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006237 if (old_delsys != delsys) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006238 shut_down(state);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006239 switch (delsys) {
6240 case SYS_DVBC_ANNEX_A:
6241 case SYS_DVBC_ANNEX_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006242 if (!state->m_has_dvbc)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006243 return -EINVAL;
6244 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6245 if (state->m_itut_annex_c)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006246 setoperation_mode(state, OM_QAM_ITU_C);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006247 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006248 setoperation_mode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006249 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006250 case SYS_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006251 if (!state->m_has_dvbt)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006252 return -EINVAL;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006253 setoperation_mode(state, OM_DVBT);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006254 break;
6255 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006256 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006257 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006258 }
6259
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006260 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006261 start(state, 0, IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006262
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006263 /* After set_frontend, stats aren't avaliable */
6264 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6265 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6266 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6267 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6268 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6269 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6270 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6271 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6272
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006273 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006274
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006275 return 0;
6276}
6277
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006278static int get_strength(struct drxk_state *state, u64 *strength)
6279{
6280 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006281 struct s_cfg_agc rf_agc, if_agc;
6282 u32 total_gain = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006283 u32 atten = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006284 u32 agc_range = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006285 u16 scu_lvl = 0;
6286 u16 scu_coc = 0;
6287 /* FIXME: those are part of the tuner presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006288 u16 tuner_rf_gain = 50; /* Default value on az6007 driver */
6289 u16 tuner_if_gain = 40; /* Default value on az6007 driver */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006290
6291 *strength = 0;
6292
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006293 if (is_dvbt(state)) {
6294 rf_agc = state->m_dvbt_rf_agc_cfg;
6295 if_agc = state->m_dvbt_if_agc_cfg;
6296 } else if (is_qam(state)) {
6297 rf_agc = state->m_qam_rf_agc_cfg;
6298 if_agc = state->m_qam_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006299 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006300 rf_agc = state->m_atv_rf_agc_cfg;
6301 if_agc = state->m_atv_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006302 }
6303
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006304 if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6305 /* SCU output_level */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006306 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6307 if (status < 0)
6308 return status;
6309
6310 /* SCU c.o.c. */
6311 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6312 if (status < 0)
6313 return status;
6314
6315 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006316 rf_agc.output_level = scu_lvl + scu_coc;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006317 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006318 rf_agc.output_level = 0xffff;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006319
6320 /* Take RF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006321 total_gain += tuner_rf_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006322
6323 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006324 if (rf_agc.output_level < rf_agc.min_output_level)
6325 rf_agc.output_level = rf_agc.min_output_level;
6326 if (rf_agc.output_level > rf_agc.max_output_level)
6327 rf_agc.output_level = rf_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006328
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006329 agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6330 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006331 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006332 ((u32)(tuner_rf_gain)) *
6333 ((u32)(rf_agc.output_level - rf_agc.min_output_level))
6334 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006335 }
6336 }
6337
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006338 if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006339 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006340 &if_agc.output_level);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006341 if (status < 0)
6342 return status;
6343
6344 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006345 &if_agc.top);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006346 if (status < 0)
6347 return status;
6348
6349 /* Take IF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006350 total_gain += (u32) tuner_if_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006351
6352 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006353 if (if_agc.output_level < if_agc.min_output_level)
6354 if_agc.output_level = if_agc.min_output_level;
6355 if (if_agc.output_level > if_agc.max_output_level)
6356 if_agc.output_level = if_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006357
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006358 agc_range = (u32) (if_agc.max_output_level - if_agc.min_output_level);
6359 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006360 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006361 ((u32)(tuner_if_gain)) *
6362 ((u32)(if_agc.output_level - if_agc.min_output_level))
6363 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006364 }
6365 }
6366
6367 /*
6368 * Convert to 0..65535 scale.
6369 * If it can't be measured (AGC is disabled), just show 100%.
6370 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006371 if (total_gain > 0)
6372 *strength = (65535UL * atten / total_gain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006373 else
6374 *strength = 65535;
6375
6376 return 0;
6377}
6378
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006379static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006380{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006381 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006382 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006383 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006384 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006385 u16 reg16;
6386 u32 post_bit_count;
6387 u32 post_bit_err_count;
6388 u32 post_bit_error_scale;
6389 u32 pre_bit_err_count;
6390 u32 pre_bit_count;
6391 u32 pkt_count;
6392 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006393 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006394
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006395 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006396 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006397 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006398 return -EAGAIN;
6399
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006400 /* get status */
6401 state->fe_status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006402 get_lock_status(state, &stat);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006403 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006404 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006405 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006406 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006407 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006408 state->fe_status |= 0x07;
6409
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006410 /*
6411 * Estimate signal strength from AGC
6412 */
6413 get_strength(state, &c->strength.stat[0].uvalue);
6414 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6415
6416
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006417 if (stat >= DEMOD_LOCK) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006418 get_signal_to_noise(state, &cnr);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006419 c->cnr.stat[0].svalue = cnr * 100;
6420 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6421 } else {
6422 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6423 }
6424
6425 if (stat < FEC_LOCK) {
6426 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6427 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6428 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6429 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6430 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6431 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6432 return 0;
6433 }
6434
6435 /* Get post BER */
6436
6437 /* BER measurement is valid if at least FEC lock is achieved */
6438
6439 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6440 to set nr of symbols or bits over which
6441 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6442
6443 /* Read registers for post/preViterbi BER calculation */
6444 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6445 if (status < 0)
6446 goto error;
6447 pre_bit_err_count = reg16;
6448
6449 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6450 if (status < 0)
6451 goto error;
6452 pre_bit_count = reg16;
6453
6454 /* Number of bit-errors */
6455 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6456 if (status < 0)
6457 goto error;
6458 post_bit_err_count = reg16;
6459
6460 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6461 if (status < 0)
6462 goto error;
6463 post_bit_error_scale = reg16;
6464
6465 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6466 if (status < 0)
6467 goto error;
6468 pkt_count = reg16;
6469
6470 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6471 if (status < 0)
6472 goto error;
6473 pkt_error_count = reg16;
6474 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6475
6476 post_bit_err_count *= post_bit_error_scale;
6477
6478 post_bit_count = pkt_count * 204 * 8;
6479
6480 /* Store the results */
6481 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6482 c->block_error.stat[0].uvalue += pkt_error_count;
6483 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6484 c->block_count.stat[0].uvalue += pkt_count;
6485
6486 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6487 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6488 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6489 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6490
6491 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6492 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6493 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6494 c->post_bit_count.stat[0].uvalue += post_bit_count;
6495
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006496error:
6497 return status;
6498}
6499
6500
6501static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6502{
6503 struct drxk_state *state = fe->demodulator_priv;
6504 int rc;
6505
6506 dprintk(1, "\n");
6507
6508 rc = drxk_get_stats(fe);
6509 if (rc < 0)
6510 return rc;
6511
6512 *status = state->fe_status;
6513
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006514 return 0;
6515}
6516
Oliver Endrissebc7de22011-07-03 13:49:44 -03006517static int drxk_read_signal_strength(struct dvb_frontend *fe,
6518 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006519{
6520 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006521 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006522
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006523 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006524
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006525 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006526 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006527 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006528 return -EAGAIN;
6529
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006530 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006531 return 0;
6532}
6533
6534static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6535{
6536 struct drxk_state *state = fe->demodulator_priv;
6537 s32 snr2;
6538
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006539 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006540
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006541 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006542 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006543 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006544 return -EAGAIN;
6545
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006546 get_signal_to_noise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006547
6548 /* No negative SNR, clip to zero */
6549 if (snr2 < 0)
6550 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006551 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006552 return 0;
6553}
6554
6555static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6556{
6557 struct drxk_state *state = fe->demodulator_priv;
6558 u16 err;
6559
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006560 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006561
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006562 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006563 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006564 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006565 return -EAGAIN;
6566
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006567 dvbtqam_get_acc_pkt_err(state, &err);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006568 *ucblocks = (u32) err;
6569 return 0;
6570}
6571
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006572static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006573 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006574{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006575 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006576 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006577
6578 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006579
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006580 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006581 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006582 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006583 return -EAGAIN;
6584
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006585 switch (p->delivery_system) {
6586 case SYS_DVBC_ANNEX_A:
6587 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006588 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006589 sets->min_delay_ms = 3000;
6590 sets->max_drift = 0;
6591 sets->step_size = 0;
6592 return 0;
6593 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006594 return -EINVAL;
6595 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006596}
6597
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006598static struct dvb_frontend_ops drxk_ops = {
6599 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006600 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006601 .name = "DRXK",
6602 .frequency_min = 47000000,
6603 .frequency_max = 865000000,
6604 /* For DVB-C */
6605 .symbol_rate_min = 870000,
6606 .symbol_rate_max = 11700000,
6607 /* For DVB-T */
6608 .frequency_stepsize = 166667,
6609
6610 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6611 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6612 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6613 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6614 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6615 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6616 },
6617
6618 .release = drxk_release,
6619 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006620 .i2c_gate_ctrl = drxk_gate_ctrl,
6621
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006622 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006623 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006624
6625 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006626 .read_signal_strength = drxk_read_signal_strength,
6627 .read_snr = drxk_read_snr,
6628 .read_ucblocks = drxk_read_ucblocks,
6629};
6630
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006631struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006632 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006633{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006634 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006635 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006636 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006637 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006638
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006639 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006640 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006641 if (!state)
6642 return NULL;
6643
Oliver Endrissebc7de22011-07-03 13:49:44 -03006644 state->i2c = i2c;
6645 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006646 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006647 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006648 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006649 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006650 state->antenna_gpio = config->antenna_gpio;
6651 state->antenna_dvbt = config->antenna_dvbt;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006652 state->m_chunk_size = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006653 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006654
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006655 if (config->dynamic_clk) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006656 state->m_dvbt_static_clk = 0;
6657 state->m_dvbc_static_clk = 0;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006658 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006659 state->m_dvbt_static_clk = 1;
6660 state->m_dvbc_static_clk = 1;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006661 }
6662
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006663
6664 if (config->mpeg_out_clk_strength)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006665 state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006666 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006667 state->m_ts_clockk_strength = 0x06;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006668
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006669 if (config->parallel_ts)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006670 state->m_enable_parallel = true;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006671 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006672 state->m_enable_parallel = false;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006673
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006674 /* NOTE: as more UIO bits will be used, add them to the mask */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006675 state->uio_mask = config->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006676
6677 /* Default gpio to DVB-C */
6678 if (!state->antenna_dvbt && state->antenna_gpio)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006679 state->m_gpio |= state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006680 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006681 state->m_gpio &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006682
6683 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006684
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006685 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6686 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006687
6688 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006689
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006690 /* Load firmware and initialize DRX-K */
6691 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006692 if (config->load_firmware_sync) {
6693 const struct firmware *fw = NULL;
6694
6695 status = request_firmware(&fw, state->microcode_name,
6696 state->i2c->dev.parent);
6697 if (status < 0)
6698 fw = NULL;
6699 load_firmware_cb(fw, state);
6700 } else {
6701 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006702 state->microcode_name,
6703 state->i2c->dev.parent,
6704 GFP_KERNEL,
6705 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006706 if (status < 0) {
6707 printk(KERN_ERR
6708 "drxk: failed to request a firmware\n");
6709 return NULL;
6710 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006711 }
6712 } else if (init_drxk(state) < 0)
6713 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006714
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006715
6716 /* Initialize stats */
6717 p = &state->frontend.dtv_property_cache;
6718 p->strength.len = 1;
6719 p->cnr.len = 1;
6720 p->block_error.len = 1;
6721 p->block_count.len = 1;
6722 p->pre_bit_error.len = 1;
6723 p->pre_bit_count.len = 1;
6724 p->post_bit_error.len = 1;
6725 p->post_bit_count.len = 1;
6726
6727 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6728 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6729 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6730 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6731 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6732 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6733 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6734 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6735
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006736 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006737 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006738
6739error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006740 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006741 kfree(state);
6742 return NULL;
6743}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006744EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006745
6746MODULE_DESCRIPTION("DRX-K driver");
6747MODULE_AUTHOR("Ralph Metzler");
6748MODULE_LICENSE("GPL");