blob: 552bce5d8f92727ded19da512c2902dff95630aa [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -030024#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
Ralph Metzler43dd07f2011-07-03 13:42:18 -030026#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/firmware.h>
32#include <linux/i2c.h>
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -030033#include <linux/hardirq.h>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030034#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "drxk.h"
38#include "drxk_hard.h"
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -030039#include "dvb_math.h"
Ralph Metzler43dd07f2011-07-03 13:42:18 -030040
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030041static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
42static int power_down_qam(struct drxk_state *state);
43static int set_dvbt_standard(struct drxk_state *state,
44 enum operation_mode o_mode);
45static int set_qam_standard(struct drxk_state *state,
46 enum operation_mode o_mode);
47static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
48 s32 tuner_freq_offset);
49static int set_dvbt_standard(struct drxk_state *state,
50 enum operation_mode o_mode);
51static int dvbt_start(struct drxk_state *state);
52static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
53 s32 tuner_freq_offset);
54static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
55static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
56static int switch_antenna_to_qam(struct drxk_state *state);
57static int switch_antenna_to_dvbt(struct drxk_state *state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030058
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030059static bool is_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030060{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030061 return state->m_operation_mode == OM_DVBT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030062}
63
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030064static bool is_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -030065{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -030066 return state->m_operation_mode == OM_QAM_ITU_A ||
67 state->m_operation_mode == OM_QAM_ITU_B ||
68 state->m_operation_mode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030069}
70
Ralph Metzler43dd07f2011-07-03 13:42:18 -030071#define NOA1ROM 0
72
Ralph Metzler43dd07f2011-07-03 13:42:18 -030073#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
74#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
75
76#define DEFAULT_MER_83 165
77#define DEFAULT_MER_93 250
78
79#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
80#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
81#endif
82
83#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
84#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
85#endif
86
Ralph Metzler43dd07f2011-07-03 13:42:18 -030087#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
88#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
89
90#ifndef DRXK_KI_RAGC_ATV
91#define DRXK_KI_RAGC_ATV 4
92#endif
93#ifndef DRXK_KI_IAGC_ATV
94#define DRXK_KI_IAGC_ATV 6
95#endif
96#ifndef DRXK_KI_DAGC_ATV
97#define DRXK_KI_DAGC_ATV 7
98#endif
99
100#ifndef DRXK_KI_RAGC_QAM
101#define DRXK_KI_RAGC_QAM 3
102#endif
103#ifndef DRXK_KI_IAGC_QAM
104#define DRXK_KI_IAGC_QAM 4
105#endif
106#ifndef DRXK_KI_DAGC_QAM
107#define DRXK_KI_DAGC_QAM 7
108#endif
109#ifndef DRXK_KI_RAGC_DVBT
110#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
111#endif
112#ifndef DRXK_KI_IAGC_DVBT
113#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
114#endif
115#ifndef DRXK_KI_DAGC_DVBT
116#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
117#endif
118
119#ifndef DRXK_AGC_DAC_OFFSET
120#define DRXK_AGC_DAC_OFFSET (0x800)
121#endif
122
123#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
124#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
125#endif
126
127#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
128#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
129#endif
130
131#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
132#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
133#endif
134
135#ifndef DRXK_QAM_SYMBOLRATE_MAX
136#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
137#endif
138
139#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
140#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
141#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
142#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
143#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
144#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
145#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
146#define DRXK_BL_ROM_OFFSET_UCODE 0
147
148#define DRXK_BLC_TIMEOUT 100
149
150#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
151#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
152
153#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
154
155#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
156#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
157#endif
158
159#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
160#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
161#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
162#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
163#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
164
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300165static unsigned int debug;
166module_param(debug, int, 0644);
167MODULE_PARM_DESC(debug, "enable debug messages");
168
169#define dprintk(level, fmt, arg...) do { \
170if (debug >= level) \
171 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
172} while (0)
173
174
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300175static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300176{
177 u64 tmp64;
178
Oliver Endrissebc7de22011-07-03 13:49:44 -0300179 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300180 do_div(tmp64, c);
181
182 return (u32) tmp64;
183}
184
Mauro Carvalho Chehabff38c212012-10-25 13:40:04 -0200185static inline u32 Frac28a(u32 a, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300186{
187 int i = 0;
188 u32 Q1 = 0;
189 u32 R0 = 0;
190
Oliver Endrissebc7de22011-07-03 13:49:44 -0300191 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
192 Q1 = a / c; /* integer part, only the 4 least significant bits
193 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300194
195 /* division using radix 16, 7 nibbles in the result */
196 for (i = 0; i < 7; i++) {
197 Q1 = (Q1 << 4) | (R0 / c);
198 R0 = (R0 % c) << 4;
199 }
200 /* rounding */
201 if ((R0 >> 3) >= c)
202 Q1++;
203
204 return Q1;
205}
206
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300207static inline u32 log10times100(u32 value)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300208{
Mauro Carvalho Chehabb5e9eb62013-04-28 11:47:43 -0300209 return (100L * intlog10(value)) >> 24;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300210}
211
212/****************************************************************************/
213/* I2C **********************************************************************/
214/****************************************************************************/
215
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300216static int drxk_i2c_lock(struct drxk_state *state)
217{
218 i2c_lock_adapter(state->i2c);
219 state->drxk_i2c_exclusive_lock = true;
220
221 return 0;
222}
223
224static void drxk_i2c_unlock(struct drxk_state *state)
225{
226 if (!state->drxk_i2c_exclusive_lock)
227 return;
228
229 i2c_unlock_adapter(state->i2c);
230 state->drxk_i2c_exclusive_lock = false;
231}
232
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300233static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
234 unsigned len)
235{
Mauro Carvalho Chehab20bfe7a2012-06-29 14:43:32 -0300236 if (state->drxk_i2c_exclusive_lock)
237 return __i2c_transfer(state->i2c, msgs, len);
238 else
239 return i2c_transfer(state->i2c, msgs, len);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300240}
241
242static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300243{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300244 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
245 .buf = val, .len = 1}
246 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300247
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300248 return drxk_i2c_transfer(state, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300249}
250
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300251static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300252{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300253 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300254 struct i2c_msg msg = {
255 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300256
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300257 dprintk(3, ":");
258 if (debug > 2) {
259 int i;
260 for (i = 0; i < len; i++)
261 printk(KERN_CONT " %02x", data[i]);
262 printk(KERN_CONT "\n");
263 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300264 status = drxk_i2c_transfer(state, &msg, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300265 if (status >= 0 && status != 1)
266 status = -EIO;
267
268 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300269 pr_err("i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300270
271 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300272}
273
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300274static int i2c_read(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300275 u8 adr, u8 *msg, int len, u8 *answ, int alen)
276{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300277 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300278 struct i2c_msg msgs[2] = {
279 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300280 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300281 {.addr = adr, .flags = I2C_M_RD,
282 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300283 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300284
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300285 status = drxk_i2c_transfer(state, msgs, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300286 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300287 if (debug > 2)
288 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300289 if (status >= 0)
290 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300291
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300292 pr_err("i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300293 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300294 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300295 if (debug > 2) {
296 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300297 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300298 for (i = 0; i < len; i++)
299 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300300 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300301 for (i = 0; i < alen; i++)
302 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300303 printk(KERN_CONT "\n");
304 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305 return 0;
306}
307
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300308static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300309{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300310 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300311 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300312
313 if (state->single_master)
314 flags |= 0xC0;
315
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300316 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
317 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
318 mm1[1] = ((reg >> 16) & 0xFF);
319 mm1[2] = ((reg >> 24) & 0xFF) | flags;
320 mm1[3] = ((reg >> 7) & 0xFF);
321 len = 4;
322 } else {
323 mm1[0] = ((reg << 1) & 0xFF);
324 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
325 len = 2;
326 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300327 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300328 status = i2c_read(state, adr, mm1, len, mm2, 2);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300329 if (status < 0)
330 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300331 if (data)
332 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300333
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300334 return 0;
335}
336
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300337static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300338{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300339 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300340}
341
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300342static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300343{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300344 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300345 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300346
347 if (state->single_master)
348 flags |= 0xC0;
349
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300350 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
351 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
352 mm1[1] = ((reg >> 16) & 0xFF);
353 mm1[2] = ((reg >> 24) & 0xFF) | flags;
354 mm1[3] = ((reg >> 7) & 0xFF);
355 len = 4;
356 } else {
357 mm1[0] = ((reg << 1) & 0xFF);
358 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
359 len = 2;
360 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300361 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300362 status = i2c_read(state, adr, mm1, len, mm2, 4);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300363 if (status < 0)
364 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300365 if (data)
366 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300367 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300368
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300369 return 0;
370}
371
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300372static int read32(struct drxk_state *state, u32 reg, u32 *data)
373{
374 return read32_flags(state, reg, data, 0);
375}
376
377static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300378{
379 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300380
381 if (state->single_master)
382 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300383 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
384 mm[0] = (((reg << 1) & 0xFF) | 0x01);
385 mm[1] = ((reg >> 16) & 0xFF);
386 mm[2] = ((reg >> 24) & 0xFF) | flags;
387 mm[3] = ((reg >> 7) & 0xFF);
388 len = 4;
389 } else {
390 mm[0] = ((reg << 1) & 0xFF);
391 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
392 len = 2;
393 }
394 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300395 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300396
397 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300398 return i2c_write(state, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300399}
400
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300401static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300402{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300403 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300404}
405
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300406static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300407{
408 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300409
410 if (state->single_master)
411 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
413 mm[0] = (((reg << 1) & 0xFF) | 0x01);
414 mm[1] = ((reg >> 16) & 0xFF);
415 mm[2] = ((reg >> 24) & 0xFF) | flags;
416 mm[3] = ((reg >> 7) & 0xFF);
417 len = 4;
418 } else {
419 mm[0] = ((reg << 1) & 0xFF);
420 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
421 len = 2;
422 }
423 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300424 mm[len + 1] = (data >> 8) & 0xff;
425 mm[len + 2] = (data >> 16) & 0xff;
426 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300427 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300428
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300429 return i2c_write(state, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300430}
431
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300432static int write32(struct drxk_state *state, u32 reg, u32 data)
433{
434 return write32_flags(state, reg, data, 0);
435}
436
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300437static int write_block(struct drxk_state *state, u32 address,
438 const int block_size, const u8 p_block[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300439{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300440 int status = 0, blk_size = block_size;
441 u8 flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300442
443 if (state->single_master)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300444 flags |= 0xC0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300445
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300446 while (blk_size > 0) {
447 int chunk = blk_size > state->m_chunk_size ?
448 state->m_chunk_size : blk_size;
449 u8 *adr_buf = &state->chunk[0];
450 u32 adr_length = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300451
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300452 if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
453 adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
454 adr_buf[1] = ((address >> 16) & 0xFF);
455 adr_buf[2] = ((address >> 24) & 0xFF);
456 adr_buf[3] = ((address >> 7) & 0xFF);
457 adr_buf[2] |= flags;
458 adr_length = 4;
459 if (chunk == state->m_chunk_size)
460 chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300461 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300462 adr_buf[0] = ((address << 1) & 0xFF);
463 adr_buf[1] = (((address >> 16) & 0x0F) |
464 ((address >> 18) & 0xF0));
465 adr_length = 2;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300466 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300467 memcpy(&state->chunk[adr_length], p_block, chunk);
468 dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300469 if (debug > 1) {
470 int i;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300471 if (p_block)
472 for (i = 0; i < chunk; i++)
473 printk(KERN_CONT " %02x", p_block[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300474 printk(KERN_CONT "\n");
475 }
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300476 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300477 &state->chunk[0], chunk + adr_length);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300478 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300479 pr_err("%s: i2c write error at addr 0x%02x\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300480 __func__, address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481 break;
482 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300483 p_block += chunk;
484 address += (chunk >> 1);
485 blk_size -= chunk;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300486 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300487 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300488}
489
490#ifndef DRXK_MAX_RETRIES_POWERUP
491#define DRXK_MAX_RETRIES_POWERUP 20
492#endif
493
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300494static int power_up_device(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300495{
496 int status;
497 u8 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300498 u16 retry_count = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300499
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300500 dprintk(1, "\n");
501
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300502 status = i2c_read1(state, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300503 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300504 do {
505 data = 0;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300506 status = i2c_write(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300507 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300508 msleep(10);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300509 retry_count++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300510 if (status < 0)
511 continue;
Mauro Carvalho Chehab2a5f6722012-06-29 14:24:18 -0300512 status = i2c_read1(state, state->demod_address,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300513 &data);
514 } while (status < 0 &&
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300515 (retry_count < DRXK_MAX_RETRIES_POWERUP));
516 if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300517 goto error;
518 }
519
520 /* Make sure all clk domains are active */
521 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
522 if (status < 0)
523 goto error;
524 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
525 if (status < 0)
526 goto error;
527 /* Enable pll lock tests */
528 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
529 if (status < 0)
530 goto error;
531
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300532 state->m_current_power_mode = DRX_POWER_UP;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300533
534error:
535 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300536 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300537
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300538 return status;
539}
540
541
542static int init_state(struct drxk_state *state)
543{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300544 /*
545 * FIXME: most (all?) of the values bellow should be moved into
546 * struct drxk_config, as they are probably board-specific
547 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300548 u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
549 u32 ul_vsb_if_agc_output_level = 0;
550 u32 ul_vsb_if_agc_min_level = 0;
551 u32 ul_vsb_if_agc_max_level = 0x7FFF;
552 u32 ul_vsb_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300553
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300554 u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
555 u32 ul_vsb_rf_agc_output_level = 0;
556 u32 ul_vsb_rf_agc_min_level = 0;
557 u32 ul_vsb_rf_agc_max_level = 0x7FFF;
558 u32 ul_vsb_rf_agc_speed = 3;
559 u32 ul_vsb_rf_agc_top = 9500;
560 u32 ul_vsb_rf_agc_cut_off_current = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300561
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300562 u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
563 u32 ul_atv_if_agc_output_level = 0;
564 u32 ul_atv_if_agc_min_level = 0;
565 u32 ul_atv_if_agc_max_level = 0;
566 u32 ul_atv_if_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300567
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300568 u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
569 u32 ul_atv_rf_agc_output_level = 0;
570 u32 ul_atv_rf_agc_min_level = 0;
571 u32 ul_atv_rf_agc_max_level = 0;
572 u32 ul_atv_rf_agc_top = 9500;
573 u32 ul_atv_rf_agc_cut_off_current = 4000;
574 u32 ul_atv_rf_agc_speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300575
576 u32 ulQual83 = DEFAULT_MER_83;
577 u32 ulQual93 = DEFAULT_MER_93;
578
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300579 u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
580 u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300581
582 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
583 /* io_pad_cfg_mode output mode is drive always */
584 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300585 u32 ul_gpio_cfg = 0x0113;
586 u32 ul_invert_ts_clock = 0;
587 u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
588 u32 ul_dvbt_bitrate = 50000000;
589 u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300590
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300591 u32 ul_insert_rs_byte = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300592
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300593 u32 ul_rf_mirror = 1;
594 u32 ul_power_down = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300595
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300596 dprintk(1, "\n");
597
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300598 state->m_has_lna = false;
599 state->m_has_dvbt = false;
600 state->m_has_dvbc = false;
601 state->m_has_atv = false;
602 state->m_has_oob = false;
603 state->m_has_audio = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300604
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300605 if (!state->m_chunk_size)
606 state->m_chunk_size = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300608 state->m_osc_clock_freq = 0;
609 state->m_smart_ant_inverted = false;
610 state->m_b_p_down_open_bridge = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300611
612 /* real system clock frequency in kHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300613 state->m_sys_clock_freq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300614 /* Timing div, 250ns/Psys */
615 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300616 state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300617 HI_I2C_DELAY) / 1000;
618 /* Clipping */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300619 if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
620 state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
621 state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300622 /* port/bridge/power down ctrl */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300623 state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300624
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300625 state->m_b_power_down = (ul_power_down != 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300626
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300627 state->m_drxk_a3_patch_code = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300628
629 /* Init AGC and PGA parameters */
630 /* VSB IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300631 state->m_vsb_if_agc_cfg.ctrl_mode = (ul_vsb_if_agc_mode);
632 state->m_vsb_if_agc_cfg.output_level = (ul_vsb_if_agc_output_level);
633 state->m_vsb_if_agc_cfg.min_output_level = (ul_vsb_if_agc_min_level);
634 state->m_vsb_if_agc_cfg.max_output_level = (ul_vsb_if_agc_max_level);
635 state->m_vsb_if_agc_cfg.speed = (ul_vsb_if_agc_speed);
636 state->m_vsb_pga_cfg = 140;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300637
638 /* VSB RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300639 state->m_vsb_rf_agc_cfg.ctrl_mode = (ul_vsb_rf_agc_mode);
640 state->m_vsb_rf_agc_cfg.output_level = (ul_vsb_rf_agc_output_level);
641 state->m_vsb_rf_agc_cfg.min_output_level = (ul_vsb_rf_agc_min_level);
642 state->m_vsb_rf_agc_cfg.max_output_level = (ul_vsb_rf_agc_max_level);
643 state->m_vsb_rf_agc_cfg.speed = (ul_vsb_rf_agc_speed);
644 state->m_vsb_rf_agc_cfg.top = (ul_vsb_rf_agc_top);
645 state->m_vsb_rf_agc_cfg.cut_off_current = (ul_vsb_rf_agc_cut_off_current);
646 state->m_vsb_pre_saw_cfg.reference = 0x07;
647 state->m_vsb_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648
649 state->m_Quality83percent = DEFAULT_MER_83;
650 state->m_Quality93percent = DEFAULT_MER_93;
651 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
652 state->m_Quality83percent = ulQual83;
653 state->m_Quality93percent = ulQual93;
654 }
655
656 /* ATV IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300657 state->m_atv_if_agc_cfg.ctrl_mode = (ul_atv_if_agc_mode);
658 state->m_atv_if_agc_cfg.output_level = (ul_atv_if_agc_output_level);
659 state->m_atv_if_agc_cfg.min_output_level = (ul_atv_if_agc_min_level);
660 state->m_atv_if_agc_cfg.max_output_level = (ul_atv_if_agc_max_level);
661 state->m_atv_if_agc_cfg.speed = (ul_atv_if_agc_speed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300662
663 /* ATV RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300664 state->m_atv_rf_agc_cfg.ctrl_mode = (ul_atv_rf_agc_mode);
665 state->m_atv_rf_agc_cfg.output_level = (ul_atv_rf_agc_output_level);
666 state->m_atv_rf_agc_cfg.min_output_level = (ul_atv_rf_agc_min_level);
667 state->m_atv_rf_agc_cfg.max_output_level = (ul_atv_rf_agc_max_level);
668 state->m_atv_rf_agc_cfg.speed = (ul_atv_rf_agc_speed);
669 state->m_atv_rf_agc_cfg.top = (ul_atv_rf_agc_top);
670 state->m_atv_rf_agc_cfg.cut_off_current = (ul_atv_rf_agc_cut_off_current);
671 state->m_atv_pre_saw_cfg.reference = 0x04;
672 state->m_atv_pre_saw_cfg.use_pre_saw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300673
674
675 /* DVBT RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300676 state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
677 state->m_dvbt_rf_agc_cfg.output_level = 0;
678 state->m_dvbt_rf_agc_cfg.min_output_level = 0;
679 state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
680 state->m_dvbt_rf_agc_cfg.top = 0x2100;
681 state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
682 state->m_dvbt_rf_agc_cfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300683
684
685 /* DVBT IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300686 state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
687 state->m_dvbt_if_agc_cfg.output_level = 0;
688 state->m_dvbt_if_agc_cfg.min_output_level = 0;
689 state->m_dvbt_if_agc_cfg.max_output_level = 9000;
690 state->m_dvbt_if_agc_cfg.top = 13424;
691 state->m_dvbt_if_agc_cfg.cut_off_current = 0;
692 state->m_dvbt_if_agc_cfg.speed = 3;
693 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
694 state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300695 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300696
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300697 state->m_dvbt_pre_saw_cfg.reference = 4;
698 state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300699
700 /* QAM RF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300701 state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
702 state->m_qam_rf_agc_cfg.output_level = 0;
703 state->m_qam_rf_agc_cfg.min_output_level = 6023;
704 state->m_qam_rf_agc_cfg.max_output_level = 27000;
705 state->m_qam_rf_agc_cfg.top = 0x2380;
706 state->m_qam_rf_agc_cfg.cut_off_current = 4000;
707 state->m_qam_rf_agc_cfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300708
709 /* QAM IF */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300710 state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
711 state->m_qam_if_agc_cfg.output_level = 0;
712 state->m_qam_if_agc_cfg.min_output_level = 0;
713 state->m_qam_if_agc_cfg.max_output_level = 9000;
714 state->m_qam_if_agc_cfg.top = 0x0511;
715 state->m_qam_if_agc_cfg.cut_off_current = 0;
716 state->m_qam_if_agc_cfg.speed = 3;
717 state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
718 state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300719
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300720 state->m_qam_pga_cfg = 140;
721 state->m_qam_pre_saw_cfg.reference = 4;
722 state->m_qam_pre_saw_cfg.use_pre_saw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300723
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300724 state->m_operation_mode = OM_NONE;
725 state->m_drxk_state = DRXK_UNINITIALIZED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300726
727 /* MPEG output configuration */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300728 state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */
729 state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */
730 state->m_invert_data = false; /* If TRUE; invert DATA signals */
731 state->m_invert_err = false; /* If TRUE; invert ERR signal */
732 state->m_invert_str = false; /* If TRUE; invert STR signals */
733 state->m_invert_val = false; /* If TRUE; invert VAL signals */
734 state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300735
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300736 /* If TRUE; static MPEG clockrate will be used;
737 otherwise clockrate will adapt to the bitrate of the TS */
738
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300739 state->m_dvbt_bitrate = ul_dvbt_bitrate;
740 state->m_dvbc_bitrate = ul_dvbc_bitrate;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300741
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300742 state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300743
744 /* Maximum bitrate in b/s in case static clockrate is selected */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300745 state->m_mpeg_ts_static_bitrate = 19392658;
746 state->m_disable_te_ihandling = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300747
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300748 if (ul_insert_rs_byte)
749 state->m_insert_rs_byte = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300750
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300751 state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
752 if (ul_mpeg_lock_time_out < 10000)
753 state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
754 state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
755 if (ul_demod_lock_time_out < 10000)
756 state->m_demod_lock_time_out = ul_demod_lock_time_out;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300757
Oliver Endrissebc7de22011-07-03 13:49:44 -0300758 /* QAM defaults */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300759 state->m_constellation = DRX_CONSTELLATION_AUTO;
760 state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
761 state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */
762 state->m_fec_rs_prescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300763
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300764 state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
765 state->m_agcfast_clip_ctrl_delay = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300766
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300767 state->m_gpio_cfg = (ul_gpio_cfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300768
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300769 state->m_b_power_down = false;
770 state->m_current_power_mode = DRX_POWER_DOWN;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300771
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300772 state->m_rfmirror = (ul_rf_mirror == 0);
773 state->m_if_agc_pol = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300774 return 0;
775}
776
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300777static int drxx_open(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300778{
779 int status = 0;
780 u32 jtag = 0;
781 u16 bid = 0;
782 u16 key = 0;
783
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300784 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300785 /* stop lock indicator process */
786 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
787 if (status < 0)
788 goto error;
789 /* Check device id */
790 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
791 if (status < 0)
792 goto error;
793 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
794 if (status < 0)
795 goto error;
796 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
797 if (status < 0)
798 goto error;
799 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
800 if (status < 0)
801 goto error;
802 status = write16(state, SIO_TOP_COMM_KEY__A, key);
803error:
804 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300805 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300806 return status;
807}
808
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300809static int get_device_capabilities(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300811 u16 sio_pdr_ohw_cfg = 0;
812 u32 sio_top_jtagid_lo = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300813 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300814 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300815
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300816 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300817
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300818 /* driver 0.9.0 */
819 /* stop lock indicator process */
820 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
821 if (status < 0)
822 goto error;
Martin Blumenstingl84183662012-10-04 14:22:55 -0300823 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300824 if (status < 0)
825 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300826 status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300827 if (status < 0)
828 goto error;
829 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
830 if (status < 0)
831 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300832
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300833 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300834 case 0:
835 /* ignore (bypass ?) */
836 break;
837 case 1:
838 /* 27 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300839 state->m_osc_clock_freq = 27000;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300840 break;
841 case 2:
842 /* 20.25 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300843 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300844 break;
845 case 3:
846 /* 4 MHz */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300847 state->m_osc_clock_freq = 20250;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300848 break;
849 default:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300850 pr_err("Clock Frequency is unknown\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300851 return -EINVAL;
852 }
853 /*
854 Determine device capabilities
855 Based on pinning v14
856 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300857 status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300858 if (status < 0)
859 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300860
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300861 pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300862
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300863 /* driver 0.9.0 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300864 switch ((sio_top_jtagid_lo >> 29) & 0xF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300865 case 0:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300866 state->m_device_spin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300867 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300868 break;
869 case 2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300870 state->m_device_spin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300871 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300872 break;
873 case 3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300874 state->m_device_spin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300875 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300876 break;
877 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300878 state->m_device_spin = DRXK_SPIN_UNKNOWN;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300879 status = -EINVAL;
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300880 pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300881 goto error2;
882 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300883 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300884 case 0x13:
885 /* typeId = DRX3913K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300886 state->m_has_lna = false;
887 state->m_has_oob = false;
888 state->m_has_atv = false;
889 state->m_has_audio = false;
890 state->m_has_dvbt = true;
891 state->m_has_dvbc = true;
892 state->m_has_sawsw = true;
893 state->m_has_gpio2 = false;
894 state->m_has_gpio1 = false;
895 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300896 break;
897 case 0x15:
898 /* typeId = DRX3915K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300899 state->m_has_lna = false;
900 state->m_has_oob = false;
901 state->m_has_atv = true;
902 state->m_has_audio = false;
903 state->m_has_dvbt = true;
904 state->m_has_dvbc = false;
905 state->m_has_sawsw = true;
906 state->m_has_gpio2 = true;
907 state->m_has_gpio1 = true;
908 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300909 break;
910 case 0x16:
911 /* typeId = DRX3916K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300912 state->m_has_lna = false;
913 state->m_has_oob = false;
914 state->m_has_atv = true;
915 state->m_has_audio = false;
916 state->m_has_dvbt = true;
917 state->m_has_dvbc = false;
918 state->m_has_sawsw = true;
919 state->m_has_gpio2 = true;
920 state->m_has_gpio1 = true;
921 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300922 break;
923 case 0x18:
924 /* typeId = DRX3918K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300925 state->m_has_lna = false;
926 state->m_has_oob = false;
927 state->m_has_atv = true;
928 state->m_has_audio = true;
929 state->m_has_dvbt = true;
930 state->m_has_dvbc = false;
931 state->m_has_sawsw = true;
932 state->m_has_gpio2 = true;
933 state->m_has_gpio1 = true;
934 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300935 break;
936 case 0x21:
937 /* typeId = DRX3921K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300938 state->m_has_lna = false;
939 state->m_has_oob = false;
940 state->m_has_atv = true;
941 state->m_has_audio = true;
942 state->m_has_dvbt = true;
943 state->m_has_dvbc = true;
944 state->m_has_sawsw = true;
945 state->m_has_gpio2 = true;
946 state->m_has_gpio1 = true;
947 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300948 break;
949 case 0x23:
950 /* typeId = DRX3923K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300951 state->m_has_lna = false;
952 state->m_has_oob = false;
953 state->m_has_atv = true;
954 state->m_has_audio = true;
955 state->m_has_dvbt = true;
956 state->m_has_dvbc = true;
957 state->m_has_sawsw = true;
958 state->m_has_gpio2 = true;
959 state->m_has_gpio1 = true;
960 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300961 break;
962 case 0x25:
963 /* typeId = DRX3925K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300964 state->m_has_lna = false;
965 state->m_has_oob = false;
966 state->m_has_atv = true;
967 state->m_has_audio = true;
968 state->m_has_dvbt = true;
969 state->m_has_dvbc = true;
970 state->m_has_sawsw = true;
971 state->m_has_gpio2 = true;
972 state->m_has_gpio1 = true;
973 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300974 break;
975 case 0x26:
976 /* typeId = DRX3926K_TYPE_ID */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300977 state->m_has_lna = false;
978 state->m_has_oob = false;
979 state->m_has_atv = true;
980 state->m_has_audio = false;
981 state->m_has_dvbt = true;
982 state->m_has_dvbc = true;
983 state->m_has_sawsw = true;
984 state->m_has_gpio2 = true;
985 state->m_has_gpio1 = true;
986 state->m_has_irqn = false;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300987 break;
988 default:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300989 pr_err("DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -0300990 ((sio_top_jtagid_lo >> 12) & 0xFF));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300991 status = -EINVAL;
992 goto error2;
993 }
994
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -0300995 pr_info("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001002 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001003
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001045 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001046
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001084 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001247 pr_err("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 Chehab3a4398f2013-04-28 11:47:45 -03001290 pr_err("SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001291 status = -EINVAL;
1292 goto error2;
1293 }
1294error:
1295 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001296 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001297error2:
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 Chehab3a4398f2013-04-28 11:47:45 -03001352 pr_err("Firmware is corrupted.\n");
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001353 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) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001358 pr_err("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 Chehab3a4398f2013-04-28 11:47:45 -03001398 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001430 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001431
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))) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001454 pr_err("Error %d on %s\n", status, __func__);
Alexey Khoroshilove4459e12012-04-05 18:53:20 -03001455 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 Chehab3a4398f2013-04-28 11:47:45 -03001480 pr_err("SCU not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001481 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 Chehab3a4398f2013-04-28 11:47:45 -03001518 pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001519 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 Chehab3a4398f2013-04-28 11:47:45 -03001526 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001562 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001667 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001668
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001719 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001799 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001800 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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001850 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001888 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001909 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03001955 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001956
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002092 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002272 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002400 pr_err("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) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002421 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002422 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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002548 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002743 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002761 pr_err("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 Chehab3a4398f2013-04-28 11:47:45 -03002803 pr_err("SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002804 status = -EINVAL;
2805 goto error2;
2806 }
2807error:
2808 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002809 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002810error2:
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002850 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002894 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002960 pr_err("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)) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03002995 pr_err("%s: mode %d is not DVB-C\n",
2996 __func__, state->m_operation_mode);
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002997 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002998 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03002999
3000 /* FIXME: Analog TV AGC require different settings */
3001
3002 /* Standard specific settings */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003003 clp_sum_min = 8;
3004 clp_dir_to = (u16) -9;
3005 clp_ctrl_mode = 0;
3006 sns_sum_min = 8;
3007 sns_dir_to = (u16) -9;
3008 ki_innergain_min = (u16) -1030;
3009 if_iaccu_hi_tgt_max = 0x2380;
3010 if_iaccu_hi_tgt = 0x2380;
3011 ingain_tgt_min = 0x0511;
3012 ingain_tgt = 0x0511;
3013 ingain_tgt_max = 5119;
3014 fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003015
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003016 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fast_clp_ctrl_delay);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003017 if (status < 0)
3018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003019
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003020 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003021 if (status < 0)
3022 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003023 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003024 if (status < 0)
3025 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003026 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003027 if (status < 0)
3028 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003029 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003030 if (status < 0)
3031 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003032 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 -03003033 if (status < 0)
3034 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003035 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 -03003036 if (status < 0)
3037 goto error;
3038 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3039 if (status < 0)
3040 goto error;
3041 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3042 if (status < 0)
3043 goto error;
3044 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3045 if (status < 0)
3046 goto error;
3047 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3048 if (status < 0)
3049 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003050 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003051 if (status < 0)
3052 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003053 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003054 if (status < 0)
3055 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003056
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003057 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003058 if (status < 0)
3059 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003060 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, if_iaccu_hi_tgt);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003061 if (status < 0)
3062 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003063 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003064 if (status < 0)
3065 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003066
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003067 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3068 if (status < 0)
3069 goto error;
3070 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3071 if (status < 0)
3072 goto error;
3073 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3074 if (status < 0)
3075 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003077 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3078 if (status < 0)
3079 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003080 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003081 if (status < 0)
3082 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003083 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003084 if (status < 0)
3085 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003086 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003087 if (status < 0)
3088 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003089 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003090 if (status < 0)
3091 goto error;
3092 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3093 if (status < 0)
3094 goto error;
3095 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3096 if (status < 0)
3097 goto error;
3098 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3099 if (status < 0)
3100 goto error;
3101 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3102 if (status < 0)
3103 goto error;
3104 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3105 if (status < 0)
3106 goto error;
3107 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3108 if (status < 0)
3109 goto error;
3110 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3111 if (status < 0)
3112 goto error;
3113 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3114 if (status < 0)
3115 goto error;
3116 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3117 if (status < 0)
3118 goto error;
3119 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3132 if (status < 0)
3133 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003134
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003135 /* Initialize inner-loop KI gain factors */
3136 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3137 if (status < 0)
3138 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003139
3140 data = 0x0657;
3141 data &= ~SCU_RAM_AGC_KI_RF__M;
3142 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3143 data &= ~SCU_RAM_AGC_KI_IF__M;
3144 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3145
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003146 status = write16(state, SCU_RAM_AGC_KI__A, data);
3147error:
3148 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003149 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003150 return status;
3151}
3152
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003153static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003154{
3155 int status;
3156
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003157 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003158 if (packet_err == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003159 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3160 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003161 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packet_err);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003162 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003163 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003164 return status;
3165}
3166
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003167static int dvbt_sc_command(struct drxk_state *state,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003168 u16 cmd, u16 subcmd,
3169 u16 param0, u16 param1, u16 param2,
3170 u16 param3, u16 param4)
3171{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003172 u16 cur_cmd = 0;
3173 u16 err_code = 0;
3174 u16 retry_cnt = 0;
3175 u16 sc_exec = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003176 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003177
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003178 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003179 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3180 if (sc_exec != 1) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003181 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003182 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003183 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003184 if (status < 0)
3185 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003186
3187 /* Wait until sc is ready to receive command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003188 retry_cnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003189 do {
3190 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003191 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3192 retry_cnt++;
3193 } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3194 if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003195 goto error;
3196
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003197 /* Write sub-command */
3198 switch (cmd) {
3199 /* All commands using sub-cmd */
3200 case OFDM_SC_RA_RAM_CMD_PROC_START:
3201 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3202 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003203 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3204 if (status < 0)
3205 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003206 break;
3207 default:
3208 /* Do nothing */
3209 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003210 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003211
3212 /* Write needed parameters and the command */
3213 switch (cmd) {
3214 /* All commands using 5 parameters */
3215 /* All commands using 4 parameters */
3216 /* All commands using 3 parameters */
3217 /* All commands using 2 parameters */
3218 case OFDM_SC_RA_RAM_CMD_PROC_START:
3219 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3220 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003221 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003222 /* All commands using 1 parameters */
3223 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3224 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003225 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003226 /* All commands using 0 parameters */
3227 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3228 case OFDM_SC_RA_RAM_CMD_NULL:
3229 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003230 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003231 break;
3232 default:
3233 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003234 status = -EINVAL;
3235 }
3236 if (status < 0)
3237 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003238
3239 /* Wait until sc is ready processing command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003240 retry_cnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003241 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003242 msleep(1);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003243 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3244 retry_cnt++;
3245 } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3246 if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003247 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003248
3249 /* Check for illegal cmd */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003250 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3251 if (err_code == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003252 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003253 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003254 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003255 if (status < 0)
3256 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003257
3258 /* Retreive results parameters from SC */
3259 switch (cmd) {
3260 /* All commands yielding 5 results */
3261 /* All commands yielding 4 results */
3262 /* All commands yielding 3 results */
3263 /* All commands yielding 2 results */
3264 /* All commands yielding 1 result */
3265 case OFDM_SC_RA_RAM_CMD_USER_IO:
3266 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003267 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003268 /* All commands yielding 0 results */
3269 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3270 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3271 case OFDM_SC_RA_RAM_CMD_PROC_START:
3272 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3273 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3274 case OFDM_SC_RA_RAM_CMD_NULL:
3275 break;
3276 default:
3277 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003278 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003280 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003281error:
3282 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003283 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003284 return status;
3285}
3286
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003287static int power_up_dvbt(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003289 enum drx_power_mode power_mode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003290 int status;
3291
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003292 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003293 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003294 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003295 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003296 return status;
3297}
3298
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003299static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003300{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003301 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003302
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003303 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003304 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003305 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003306 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003307 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003308 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003309 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003310 return status;
3311}
3312
3313#define DEFAULT_FR_THRES_8K 4000
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003314static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003315{
3316
3317 int status;
3318
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003319 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003320 if (*enabled == true) {
3321 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003322 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003323 DEFAULT_FR_THRES_8K);
3324 } else {
3325 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003326 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003327 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003328 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003329 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003330
3331 return status;
3332}
3333
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003334static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3335 struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
Oliver Endrissebc7de22011-07-03 13:49:44 -03003336{
3337 u16 data = 0;
3338 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003339
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003340 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003341 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3342 if (status < 0)
3343 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003344
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003345 switch (echo_thres->fft_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003346 case DRX_FFTMODE_2K:
3347 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003348 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003349 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3350 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003351 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003352 case DRX_FFTMODE_8K:
3353 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003354 data |= ((echo_thres->threshold <<
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003355 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3356 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003357 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003358 default:
3359 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003360 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003361
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003362 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3363error:
3364 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003365 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003366 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003367}
3368
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003369static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3370 enum drxk_cfg_dvbt_sqi_speed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003371{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003372 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003373
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003374 dprintk(1, "\n");
3375
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003376 switch (*speed) {
3377 case DRXK_DVBT_SQI_SPEED_FAST:
3378 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3379 case DRXK_DVBT_SQI_SPEED_SLOW:
3380 break;
3381 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003382 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003383 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003384 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003385 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003386error:
3387 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003388 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 return status;
3390}
3391
3392/*============================================================================*/
3393
3394/**
3395* \brief Activate DVBT specific presets
3396* \param demod instance of demodulator.
3397* \return DRXStatus_t.
3398*
3399* Called in DVBTSetStandard
3400*
3401*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003402static int dvbt_activate_presets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003403{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003405 bool setincenable = false;
3406 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003407
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003408 struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3409 struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003410
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003411 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003412 status = dvbt_ctrl_set_inc_enable(state, &setincenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003413 if (status < 0)
3414 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003415 status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003416 if (status < 0)
3417 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003418 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003419 if (status < 0)
3420 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003421 status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003422 if (status < 0)
3423 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003424 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 -03003425error:
3426 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003427 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003428 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003429}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003430
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003431/*============================================================================*/
3432
3433/**
3434* \brief Initialize channelswitch-independent settings for DVBT.
3435* \param demod instance of demodulator.
3436* \return DRXStatus_t.
3437*
3438* For ROM code channel filter taps are loaded from the bootloader. For microcode
3439* the DVB-T taps from the drxk_filters.h are used.
3440*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003441static int set_dvbt_standard(struct drxk_state *state,
3442 enum operation_mode o_mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003443{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003444 u16 cmd_result = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003445 u16 data = 0;
3446 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003447
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003448 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003449
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003450 power_up_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003451 /* added antenna switch */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003452 switch_antenna_to_dvbt(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003453 /* send OFDM reset command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003454 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 -03003455 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003456 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003458 /* send OFDM setenv command */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003459 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 -03003460 if (status < 0)
3461 goto error;
3462
3463 /* reset datapath for OFDM, processors first */
3464 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3465 if (status < 0)
3466 goto error;
3467 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3468 if (status < 0)
3469 goto error;
3470 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3471 if (status < 0)
3472 goto error;
3473
3474 /* IQM setup */
3475 /* synchronize on ofdstate->m_festart */
3476 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3477 if (status < 0)
3478 goto error;
3479 /* window size for clipping ADC detection */
3480 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3481 if (status < 0)
3482 goto error;
3483 /* window size for for sense pre-SAW detection */
3484 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3485 if (status < 0)
3486 goto error;
3487 /* sense threshold for sense pre-SAW detection */
3488 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3489 if (status < 0)
3490 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003491 status = set_iqm_af(state, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003492 if (status < 0)
3493 goto error;
3494
3495 status = write16(state, IQM_AF_AGC_RF__A, 0);
3496 if (status < 0)
3497 goto error;
3498
3499 /* Impulse noise cruncher setup */
3500 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3501 if (status < 0)
3502 goto error;
3503 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3504 if (status < 0)
3505 goto error;
3506 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3507 if (status < 0)
3508 goto error;
3509
3510 status = write16(state, IQM_RC_STRETCH__A, 16);
3511 if (status < 0)
3512 goto error;
3513 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3514 if (status < 0)
3515 goto error;
3516 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3517 if (status < 0)
3518 goto error;
3519 status = write16(state, IQM_CF_SCALE__A, 1600);
3520 if (status < 0)
3521 goto error;
3522 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3523 if (status < 0)
3524 goto error;
3525
3526 /* virtual clipping threshold for clipping ADC detection */
3527 status = write16(state, IQM_AF_CLP_TH__A, 448);
3528 if (status < 0)
3529 goto error;
3530 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3531 if (status < 0)
3532 goto error;
3533
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003534 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 -03003535 if (status < 0)
3536 goto error;
3537
3538 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3539 if (status < 0)
3540 goto error;
3541 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3542 if (status < 0)
3543 goto error;
3544 /* enable power measurement interrupt */
3545 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3546 if (status < 0)
3547 goto error;
3548 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3549 if (status < 0)
3550 goto error;
3551
3552 /* IQM will not be reset from here, sync ADC and update/init AGC */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003553 status = adc_synchronization(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003554 if (status < 0)
3555 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003556 status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003557 if (status < 0)
3558 goto error;
3559
3560 /* Halt SCU to enable safe non-atomic accesses */
3561 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3562 if (status < 0)
3563 goto error;
3564
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003565 status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003566 if (status < 0)
3567 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003568 status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003569 if (status < 0)
3570 goto error;
3571
3572 /* Set Noise Estimation notch width and enable DC fix */
3573 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3574 if (status < 0)
3575 goto error;
3576 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3577 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3578 if (status < 0)
3579 goto error;
3580
3581 /* Activate SCU to enable SCU commands */
3582 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3583 if (status < 0)
3584 goto error;
3585
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003586 if (!state->m_drxk_a3_rom_code) {
3587 /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */
3588 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 -03003589 if (status < 0)
3590 goto error;
3591 }
3592
3593 /* OFDM_SC setup */
3594#ifdef COMPILE_FOR_NONRT
3595 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3596 if (status < 0)
3597 goto error;
3598 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3599 if (status < 0)
3600 goto error;
3601#endif
3602
3603 /* FEC setup */
3604 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3605 if (status < 0)
3606 goto error;
3607
3608
3609#ifdef COMPILE_FOR_NONRT
3610 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3611 if (status < 0)
3612 goto error;
3613#else
3614 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3615 if (status < 0)
3616 goto error;
3617#endif
3618 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3619 if (status < 0)
3620 goto error;
3621
3622 /* Setup MPEG bus */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003623 status = mpegts_dto_setup(state, OM_DVBT);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003624 if (status < 0)
3625 goto error;
3626 /* Set DVBT Presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003627 status = dvbt_activate_presets(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003628 if (status < 0)
3629 goto error;
3630
3631error:
3632 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003633 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003634 return status;
3635}
3636
3637/*============================================================================*/
3638/**
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003639* \brief start dvbt demodulating for channel.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003640* \param demod instance of demodulator.
3641* \return DRXStatus_t.
3642*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003643static int dvbt_start(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003644{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003645 u16 param1;
3646 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003647 /* drxk_ofdm_sc_cmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003648
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003649 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003650 /* start correct processes to get in lock */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003651 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003652 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003653 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 -03003654 if (status < 0)
3655 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003656 /* start FEC OC */
3657 status = mpegts_start(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003658 if (status < 0)
3659 goto error;
3660 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3661 if (status < 0)
3662 goto error;
3663error:
3664 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003665 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003666 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003667}
3668
3669
3670/*============================================================================*/
3671
3672/**
3673* \brief Set up dvbt demodulator for channel.
3674* \param demod instance of demodulator.
3675* \return DRXStatus_t.
3676* // original DVBTSetChannel()
3677*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003678static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3679 s32 tuner_freq_offset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003680{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003681 u16 cmd_result = 0;
3682 u16 transmission_params = 0;
3683 u16 operation_mode = 0;
3684 u32 iqm_rc_rate_ofs = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003685 u32 bandwidth = 0;
3686 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003687 int status;
3688
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003689 dprintk(1, "IF =%d, TFO = %d\n", intermediate_freqk_hz, tuner_freq_offset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003690
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003691 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 -03003692 if (status < 0)
3693 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003694
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003695 /* Halt SCU to enable safe non-atomic accesses */
3696 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3697 if (status < 0)
3698 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003699
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003700 /* Stop processors */
3701 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3702 if (status < 0)
3703 goto error;
3704 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3705 if (status < 0)
3706 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003707
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003708 /* Mandatory fix, always stop CP, required to set spl offset back to
3709 hardware default (is set to 0 by ucode during pilot detection */
3710 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3711 if (status < 0)
3712 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003713
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003714 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003715
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003716 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003717 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003718 case TRANSMISSION_MODE_AUTO:
3719 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003720 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003721 /* fall through , try first guess DRX_FFTMODE_8K */
3722 case TRANSMISSION_MODE_8K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003723 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003724 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003725 case TRANSMISSION_MODE_2K:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003726 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003727 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003728 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003730 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003731 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003732 default:
3733 case GUARD_INTERVAL_AUTO:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003734 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003735 /* fall through , try first guess DRX_GUARD_1DIV4 */
3736 case GUARD_INTERVAL_1_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003737 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003738 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003739 case GUARD_INTERVAL_1_32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003740 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003741 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003742 case GUARD_INTERVAL_1_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003743 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003744 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003745 case GUARD_INTERVAL_1_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003746 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003747 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003748 }
3749
3750 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003751 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003752 case HIERARCHY_AUTO:
3753 case HIERARCHY_NONE:
3754 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003755 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003756 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003757 /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003758 /* break; */
3759 case HIERARCHY_1:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003760 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003761 break;
3762 case HIERARCHY_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003763 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003764 break;
3765 case HIERARCHY_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003766 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003767 break;
3768 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003769
3770
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003771 /* modulation */
3772 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003773 case QAM_AUTO:
3774 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003775 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003776 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3777 case QAM_64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003778 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003779 break;
3780 case QPSK:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003781 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003782 break;
3783 case QAM_16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003784 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003785 break;
3786 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003787#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003788 /* No hierachical channels support in BDA */
3789 /* Priority (only for hierarchical channels) */
3790 switch (channel->priority) {
3791 case DRX_PRIORITY_LOW:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003792 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3793 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 OFDM_EC_SB_PRIOR_LO);
3795 break;
3796 case DRX_PRIORITY_HIGH:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003797 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3798 WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003799 OFDM_EC_SB_PRIOR_HI));
3800 break;
3801 case DRX_PRIORITY_UNKNOWN: /* fall through */
3802 default:
3803 status = -EINVAL;
3804 goto error;
3805 }
3806#else
3807 /* Set Priorty high */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003808 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003809 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3810 if (status < 0)
3811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812#endif
3813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003814 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003815 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003816 case FEC_AUTO:
3817 default:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003818 operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3820 case FEC_2_3:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003821 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003822 break;
3823 case FEC_1_2:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003824 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003825 break;
3826 case FEC_3_4:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003827 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003828 break;
3829 case FEC_5_6:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003830 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003831 break;
3832 case FEC_7_8:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003833 transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003834 break;
3835 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003836
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003837 /* SAW filter selection: normaly not necesarry, but if wanted
3838 the application can select a SAW filter via the driver by using UIOs */
3839 /* First determine real bandwidth (Hz) */
3840 /* Also set delay for impulse noise cruncher */
3841 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3842 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3843 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003844 switch (state->props.bandwidth_hz) {
3845 case 0:
3846 state->props.bandwidth_hz = 8000000;
3847 /* fall though */
3848 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003849 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3850 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003851 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003852 goto error;
3853 /* cochannel protection for PAL 8 MHz */
3854 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3855 if (status < 0)
3856 goto error;
3857 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3858 if (status < 0)
3859 goto error;
3860 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3861 if (status < 0)
3862 goto error;
3863 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3864 if (status < 0)
3865 goto error;
3866 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003867 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003868 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3869 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3870 if (status < 0)
3871 goto error;
3872 /* cochannel protection for PAL 7 MHz */
3873 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3874 if (status < 0)
3875 goto error;
3876 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3877 if (status < 0)
3878 goto error;
3879 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3880 if (status < 0)
3881 goto error;
3882 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3883 if (status < 0)
3884 goto error;
3885 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003886 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003887 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3888 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3889 if (status < 0)
3890 goto error;
3891 /* cochannel protection for NTSC 6 MHz */
3892 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3893 if (status < 0)
3894 goto error;
3895 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3896 if (status < 0)
3897 goto error;
3898 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3899 if (status < 0)
3900 goto error;
3901 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3902 if (status < 0)
3903 goto error;
3904 break;
3905 default:
3906 status = -EINVAL;
3907 goto error;
3908 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003909
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003910 if (iqm_rc_rate_ofs == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003911 /* Now compute IQM_RC_RATE_OFS
3912 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
3913 =>
3914 ((SysFreq / BandWidth) * (2^21)) - (2^23)
3915 */
3916 /* (SysFreq / BandWidth) * (2^28) */
3917 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
3918 => assert(MAX(sysClk) < 16*MIN(bandwidth))
3919 => assert(109714272 > 48000000) = true so Frac 28 can be used */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003920 iqm_rc_rate_ofs = Frac28a((u32)
3921 ((state->m_sys_clock_freq *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003922 1000) / 3), bandwidth);
3923 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003924 if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
3925 iqm_rc_rate_ofs += 0x80L;
3926 iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003927 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003928 iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003929 }
3930
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003931 iqm_rc_rate_ofs &=
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003932 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
3933 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003934 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003935 if (status < 0)
3936 goto error;
3937
3938 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003939
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003940#if 0
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003941 status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003942 if (status < 0)
3943 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003944#endif
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003945 status = set_frequency_shifter(state, intermediate_freqk_hz, tuner_freq_offset, true);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003946 if (status < 0)
3947 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003948
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003949 /*== start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003950
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003951 /* Activate SCU to enable SCU commands */
3952 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3953 if (status < 0)
3954 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003955
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003956 /* Enable SC after setting all other parameters */
3957 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
3958 if (status < 0)
3959 goto error;
3960 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
3961 if (status < 0)
3962 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003963
3964
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003965 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 -03003966 if (status < 0)
3967 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003968
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003969 /* Write SC parameter registers, set all AUTO flags in operation mode */
3970 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
3971 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
3972 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
3973 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
3974 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003975 status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
3976 0, transmission_params, param1, 0, 0, 0);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003977 if (status < 0)
3978 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003979
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003980 if (!state->m_drxk_a3_rom_code)
3981 status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003982error:
3983 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03003984 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003985
3986 return status;
3987}
3988
3989
3990/*============================================================================*/
3991
3992/**
3993* \brief Retreive lock status .
3994* \param demod Pointer to demodulator instance.
3995* \param lockStat Pointer to lock status structure.
3996* \return DRXStatus_t.
3997*
3998*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03003999static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004000{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004001 int status;
4002 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4003 OFDM_SC_RA_RAM_LOCK_FEC__M);
4004 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4005 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004006
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004007 u16 sc_ra_ram_lock = 0;
4008 u16 sc_comm_exec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004009
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004010 dprintk(1, "\n");
4011
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004012 *p_lock_status = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004013 /* driver 0.9.0 */
4014 /* Check if SC is running */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004015 status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004016 if (status < 0)
4017 goto end;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004018 if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004019 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004020
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004021 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004022 if (status < 0)
4023 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004024
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004025 if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4026 *p_lock_status = MPEG_LOCK;
4027 else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4028 *p_lock_status = FEC_LOCK;
4029 else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4030 *p_lock_status = DEMOD_LOCK;
4031 else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4032 *p_lock_status = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004033end:
4034 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004035 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004036
Oliver Endrissebc7de22011-07-03 13:49:44 -03004037 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004038}
4039
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004040static int power_up_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004041{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004042 enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004043 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004045 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004046 status = ctrl_power_mode(state, &power_mode);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004047 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004048 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004049
Oliver Endrissebc7de22011-07-03 13:49:44 -03004050 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004051}
4052
4053
Oliver Endrissebc7de22011-07-03 13:49:44 -03004054/** Power Down QAM */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004055static int power_down_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004056{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004057 u16 data = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004058 u16 cmd_result;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004059 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004061 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004062 status = read16(state, SCU_COMM_EXEC__A, &data);
4063 if (status < 0)
4064 goto error;
4065 if (data == SCU_COMM_EXEC_ACTIVE) {
4066 /*
4067 STOP demodulator
4068 QAM and HW blocks
4069 */
4070 /* stop all comstate->m_exec */
4071 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004072 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004073 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004074 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 -03004075 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004076 goto error;
4077 }
4078 /* powerdown AFE */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004079 status = set_iqm_af(state, false);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004080
4081error:
4082 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004083 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004084
Oliver Endrissebc7de22011-07-03 13:49:44 -03004085 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004086}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004087
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004088/*============================================================================*/
4089
4090/**
4091* \brief Setup of the QAM Measurement intervals for signal quality
4092* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004093* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004094* \return DRXStatus_t.
4095*
4096* NOTE:
4097* Take into account that for certain settings the errorcounters can overflow.
4098* The implementation does not check this.
4099*
4100*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004101static int set_qam_measurement(struct drxk_state *state,
4102 enum e_drxk_constellation modulation,
4103 u32 symbol_rate)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004104{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004105 u32 fec_bits_desired = 0; /* BER accounting period */
4106 u32 fec_rs_period_total = 0; /* Total period */
4107 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
4108 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004109 int status = 0;
4110
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004111 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004112
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004113 fec_rs_prescale = 1;
4114 /* fec_bits_desired = symbol_rate [kHz] *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004115 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004116 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004117 SyncLoss (== 1) *
4118 ViterbiLoss (==1)
4119 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004120 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004121 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004122 fec_bits_desired = 4 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004123 break;
4124 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004125 fec_bits_desired = 5 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004126 break;
4127 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004128 fec_bits_desired = 6 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004129 break;
4130 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004131 fec_bits_desired = 7 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004132 break;
4133 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004134 fec_bits_desired = 8 * symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004135 break;
4136 default:
4137 status = -EINVAL;
4138 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004139 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004140 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004141
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004142 fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */
4143 fec_bits_desired *= 500; /* meas. period [ms] */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004144
4145 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004146 /* fec_rs_period_total = fec_bits_desired / 1632 */
4147 fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004148
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004149 /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */
4150 fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4151 if (fec_rs_prescale == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004152 /* Divide by zero (though impossible) */
4153 status = -EINVAL;
4154 if (status < 0)
4155 goto error;
4156 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004157 fec_rs_period =
4158 ((u16) fec_rs_period_total +
4159 (fec_rs_prescale >> 1)) / fec_rs_prescale;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004160
4161 /* write corresponding registers */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004162 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004163 if (status < 0)
4164 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004165 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004166 if (status < 0)
4167 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004168 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004169error:
4170 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004171 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004172 return status;
4173}
4174
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004175static int set_qam16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004176{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004177 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004178
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004179 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004180 /* QAM Equalizer Setup */
4181 /* Equalizer */
4182 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4183 if (status < 0)
4184 goto error;
4185 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4186 if (status < 0)
4187 goto error;
4188 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4189 if (status < 0)
4190 goto error;
4191 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4192 if (status < 0)
4193 goto error;
4194 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4195 if (status < 0)
4196 goto error;
4197 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4198 if (status < 0)
4199 goto error;
4200 /* Decision Feedback Equalizer */
4201 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4202 if (status < 0)
4203 goto error;
4204 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4205 if (status < 0)
4206 goto error;
4207 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4208 if (status < 0)
4209 goto error;
4210 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4211 if (status < 0)
4212 goto error;
4213 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4214 if (status < 0)
4215 goto error;
4216 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4217 if (status < 0)
4218 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004219
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004220 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4221 if (status < 0)
4222 goto error;
4223 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4224 if (status < 0)
4225 goto error;
4226 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4227 if (status < 0)
4228 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004230 /* QAM Slicer Settings */
4231 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4232 if (status < 0)
4233 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004234
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004235 /* QAM Loop Controller Coeficients */
4236 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4237 if (status < 0)
4238 goto error;
4239 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4240 if (status < 0)
4241 goto error;
4242 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4243 if (status < 0)
4244 goto error;
4245 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4246 if (status < 0)
4247 goto error;
4248 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4249 if (status < 0)
4250 goto error;
4251 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4252 if (status < 0)
4253 goto error;
4254 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4255 if (status < 0)
4256 goto error;
4257 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4258 if (status < 0)
4259 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004260
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004261 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4262 if (status < 0)
4263 goto error;
4264 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4265 if (status < 0)
4266 goto error;
4267 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4268 if (status < 0)
4269 goto error;
4270 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4271 if (status < 0)
4272 goto error;
4273 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4274 if (status < 0)
4275 goto error;
4276 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4277 if (status < 0)
4278 goto error;
4279 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4295 if (status < 0)
4296 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004297
4298
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004299 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004300
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004301 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4314 if (status < 0)
4315 goto error;
4316 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4317 if (status < 0)
4318 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004319
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004320 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4324 if (status < 0)
4325 goto error;
4326 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4327 if (status < 0)
4328 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004329
4330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004331 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004332
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004333 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4334 if (status < 0)
4335 goto error;
4336 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4352 if (status < 0)
4353 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004354
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004355error:
4356 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004357 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004358 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004359}
4360
4361/*============================================================================*/
4362
4363/**
4364* \brief QAM32 specific setup
4365* \param demod instance of demod.
4366* \return DRXStatus_t.
4367*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004368static int set_qam32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004369{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004370 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004371
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004372 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004373
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004374 /* QAM Equalizer Setup */
4375 /* Equalizer */
4376 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4392 if (status < 0)
4393 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004394
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004395 /* Decision Feedback Equalizer */
4396 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4397 if (status < 0)
4398 goto error;
4399 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4400 if (status < 0)
4401 goto error;
4402 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4403 if (status < 0)
4404 goto error;
4405 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4406 if (status < 0)
4407 goto error;
4408 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4409 if (status < 0)
4410 goto error;
4411 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4412 if (status < 0)
4413 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004414
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004415 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4419 if (status < 0)
4420 goto error;
4421 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4422 if (status < 0)
4423 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004424
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004425 /* QAM Slicer Settings */
4426
4427 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4428 if (status < 0)
4429 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004430
4431
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004432 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004433
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004434 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4435 if (status < 0)
4436 goto error;
4437 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4438 if (status < 0)
4439 goto error;
4440 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4441 if (status < 0)
4442 goto error;
4443 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4444 if (status < 0)
4445 goto error;
4446 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4447 if (status < 0)
4448 goto error;
4449 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4450 if (status < 0)
4451 goto error;
4452 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4453 if (status < 0)
4454 goto error;
4455 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4456 if (status < 0)
4457 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004458
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004459 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4460 if (status < 0)
4461 goto error;
4462 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4463 if (status < 0)
4464 goto error;
4465 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4466 if (status < 0)
4467 goto error;
4468 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4469 if (status < 0)
4470 goto error;
4471 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4472 if (status < 0)
4473 goto error;
4474 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4475 if (status < 0)
4476 goto error;
4477 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4478 if (status < 0)
4479 goto error;
4480 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4481 if (status < 0)
4482 goto error;
4483 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4484 if (status < 0)
4485 goto error;
4486 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4487 if (status < 0)
4488 goto error;
4489 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4490 if (status < 0)
4491 goto error;
4492 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4493 if (status < 0)
4494 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004495
4496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004497 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004498
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004499 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4509 if (status < 0)
4510 goto error;
4511 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4512 if (status < 0)
4513 goto error;
4514 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4515 if (status < 0)
4516 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004517
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004518 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4519 if (status < 0)
4520 goto error;
4521 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4522 if (status < 0)
4523 goto error;
4524 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4525 if (status < 0)
4526 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004527
4528
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004529 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004530
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004531 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4532 if (status < 0)
4533 goto error;
4534 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4550error:
4551 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004552 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004553 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004554}
4555
4556/*============================================================================*/
4557
4558/**
4559* \brief QAM64 specific setup
4560* \param demod instance of demod.
4561* \return DRXStatus_t.
4562*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004563static int set_qam64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004564{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004565 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004566
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004567 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004568 /* QAM Equalizer Setup */
4569 /* Equalizer */
4570 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4586 if (status < 0)
4587 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004588
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004589 /* Decision Feedback Equalizer */
4590 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4591 if (status < 0)
4592 goto error;
4593 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4594 if (status < 0)
4595 goto error;
4596 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4606 if (status < 0)
4607 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004608
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004609 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4610 if (status < 0)
4611 goto error;
4612 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4613 if (status < 0)
4614 goto error;
4615 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4616 if (status < 0)
4617 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004618
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004619 /* QAM Slicer Settings */
4620 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4621 if (status < 0)
4622 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004623
4624
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004625 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004626
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004627 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4628 if (status < 0)
4629 goto error;
4630 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4631 if (status < 0)
4632 goto error;
4633 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4634 if (status < 0)
4635 goto error;
4636 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4649 if (status < 0)
4650 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004651
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004652 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4653 if (status < 0)
4654 goto error;
4655 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4656 if (status < 0)
4657 goto error;
4658 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4659 if (status < 0)
4660 goto error;
4661 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4662 if (status < 0)
4663 goto error;
4664 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4665 if (status < 0)
4666 goto error;
4667 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4668 if (status < 0)
4669 goto error;
4670 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4680 if (status < 0)
4681 goto error;
4682 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4683 if (status < 0)
4684 goto error;
4685 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4686 if (status < 0)
4687 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004688
4689
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004690 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004691
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004692 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4693 if (status < 0)
4694 goto error;
4695 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4708 if (status < 0)
4709 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004710
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004711 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4712 if (status < 0)
4713 goto error;
4714 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4715 if (status < 0)
4716 goto error;
4717 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4718 if (status < 0)
4719 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004720
4721
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004722 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004724 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4743error:
4744 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004745 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004746
Oliver Endrissebc7de22011-07-03 13:49:44 -03004747 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004748}
4749
4750/*============================================================================*/
4751
4752/**
4753* \brief QAM128 specific setup
4754* \param demod: instance of demod.
4755* \return DRXStatus_t.
4756*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004757static int set_qam128(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004758{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004759 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004760
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004761 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004762 /* QAM Equalizer Setup */
4763 /* Equalizer */
4764 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4780 if (status < 0)
4781 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004782
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004783 /* Decision Feedback Equalizer */
4784 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4785 if (status < 0)
4786 goto error;
4787 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4788 if (status < 0)
4789 goto error;
4790 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4791 if (status < 0)
4792 goto error;
4793 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4794 if (status < 0)
4795 goto error;
4796 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4797 if (status < 0)
4798 goto error;
4799 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4800 if (status < 0)
4801 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004802
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004803 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4804 if (status < 0)
4805 goto error;
4806 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4807 if (status < 0)
4808 goto error;
4809 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4810 if (status < 0)
4811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004812
4813
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004814 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004816 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4817 if (status < 0)
4818 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004819
4820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004821 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004822
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004823 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4824 if (status < 0)
4825 goto error;
4826 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4827 if (status < 0)
4828 goto error;
4829 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4842 if (status < 0)
4843 goto error;
4844 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4845 if (status < 0)
4846 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004847
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004848 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4849 if (status < 0)
4850 goto error;
4851 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4852 if (status < 0)
4853 goto error;
4854 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4855 if (status < 0)
4856 goto error;
4857 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4858 if (status < 0)
4859 goto error;
4860 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4861 if (status < 0)
4862 goto error;
4863 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4864 if (status < 0)
4865 goto error;
4866 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4867 if (status < 0)
4868 goto error;
4869 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4870 if (status < 0)
4871 goto error;
4872 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4876 if (status < 0)
4877 goto error;
4878 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4882 if (status < 0)
4883 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004884
4885
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004886 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004887
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004888 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4889 if (status < 0)
4890 goto error;
4891 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4892 if (status < 0)
4893 goto error;
4894 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4895 if (status < 0)
4896 goto error;
4897 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4898 if (status < 0)
4899 goto error;
4900 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4904 if (status < 0)
4905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004907 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4908 if (status < 0)
4909 goto error;
4910 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
4911 if (status < 0)
4912 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004913
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004914 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
4915 if (status < 0)
4916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004917
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004918 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004919
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004920 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
4939error:
4940 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03004941 pr_err("Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004942
Oliver Endrissebc7de22011-07-03 13:49:44 -03004943 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004944}
4945
4946/*============================================================================*/
4947
4948/**
4949* \brief QAM256 specific setup
4950* \param demod: instance of demod.
4951* \return DRXStatus_t.
4952*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03004953static int set_qam256(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004954{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004955 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004956
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004957 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004958 /* QAM Equalizer Setup */
4959 /* Equalizer */
4960 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
4976 if (status < 0)
4977 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004978
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004979 /* Decision Feedback Equalizer */
4980 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
4981 if (status < 0)
4982 goto error;
4983 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
4984 if (status < 0)
4985 goto error;
4986 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
4987 if (status < 0)
4988 goto error;
4989 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
4990 if (status < 0)
4991 goto error;
4992 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
4993 if (status < 0)
4994 goto error;
4995 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4996 if (status < 0)
4997 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004998
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004999 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5000 if (status < 0)
5001 goto error;
5002 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5003 if (status < 0)
5004 goto error;
5005 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5006 if (status < 0)
5007 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005008
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005009 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005010
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005011 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5012 if (status < 0)
5013 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005014
5015
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005016 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005017
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005018 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5019 if (status < 0)
5020 goto error;
5021 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5022 if (status < 0)
5023 goto error;
5024 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5025 if (status < 0)
5026 goto error;
5027 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5028 if (status < 0)
5029 goto error;
5030 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5031 if (status < 0)
5032 goto error;
5033 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5034 if (status < 0)
5035 goto error;
5036 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5037 if (status < 0)
5038 goto error;
5039 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5040 if (status < 0)
5041 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005042
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005043 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5044 if (status < 0)
5045 goto error;
5046 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5047 if (status < 0)
5048 goto error;
5049 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5050 if (status < 0)
5051 goto error;
5052 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5053 if (status < 0)
5054 goto error;
5055 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5056 if (status < 0)
5057 goto error;
5058 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5059 if (status < 0)
5060 goto error;
5061 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5062 if (status < 0)
5063 goto error;
5064 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5065 if (status < 0)
5066 goto error;
5067 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5068 if (status < 0)
5069 goto error;
5070 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5071 if (status < 0)
5072 goto error;
5073 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5074 if (status < 0)
5075 goto error;
5076 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5077 if (status < 0)
5078 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005079
5080
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005081 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005082
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005083 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5093 if (status < 0)
5094 goto error;
5095 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5096 if (status < 0)
5097 goto error;
5098 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5099 if (status < 0)
5100 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005101
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005102 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5103 if (status < 0)
5104 goto error;
5105 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5106 if (status < 0)
5107 goto error;
5108 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5109 if (status < 0)
5110 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005111
5112
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005113 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005114
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005115 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5116 if (status < 0)
5117 goto error;
5118 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5134error:
5135 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005136 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005137 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005138}
5139
5140
5141/*============================================================================*/
5142/**
5143* \brief Reset QAM block.
5144* \param demod: instance of demod.
5145* \param channel: pointer to channel data.
5146* \return DRXStatus_t.
5147*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005148static int qam_reset_qam(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005149{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005150 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005151 u16 cmd_result;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005152
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005153 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005154 /* Stop QAM comstate->m_exec */
5155 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5156 if (status < 0)
5157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005158
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005159 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 -03005160error:
5161 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005162 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005163 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005164}
5165
5166/*============================================================================*/
5167
5168/**
5169* \brief Set QAM symbolrate.
5170* \param demod: instance of demod.
5171* \param channel: pointer to channel data.
5172* \return DRXStatus_t.
5173*/
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005174static int qam_set_symbolrate(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005175{
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005176 u32 adc_frequency = 0;
5177 u32 symb_freq = 0;
5178 u32 iqm_rc_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005179 u16 ratesel = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005180 u32 lc_symb_rate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005181 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005182
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005183 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005184 /* Select & calculate correct IQM rate */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005185 adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005186 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005187 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5188 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005189 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005190 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005191 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005192 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005193 ratesel = 1;
5194 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5195 if (status < 0)
5196 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005197
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005198 /*
5199 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5200 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005201 symb_freq = state->props.symbol_rate * (1 << ratesel);
5202 if (symb_freq == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005203 /* Divide by zero */
5204 status = -EINVAL;
5205 goto error;
5206 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005207 iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5208 (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005209 (1 << 23);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005210 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005211 if (status < 0)
5212 goto error;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005213 state->m_iqm_rc_rate = iqm_rc_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005214 /*
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005215 LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005216 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005217 symb_freq = state->props.symbol_rate;
5218 if (adc_frequency == 0) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005219 /* Divide by zero */
5220 status = -EINVAL;
5221 goto error;
5222 }
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005223 lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5224 (Frac28a((symb_freq % adc_frequency), adc_frequency) >>
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005225 16);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005226 if (lc_symb_rate > 511)
5227 lc_symb_rate = 511;
5228 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005229
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005230error:
5231 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005232 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005233 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005234}
5235
5236/*============================================================================*/
5237
5238/**
5239* \brief Get QAM lock status.
5240* \param demod: instance of demod.
5241* \param channel: pointer to channel data.
5242* \return DRXStatus_t.
5243*/
5244
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005245static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005246{
5247 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005248 u16 result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005249
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005250 dprintk(1, "\n");
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005251 *p_lock_status = NOT_LOCKED;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005252 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005253 SCU_RAM_COMMAND_STANDARD_QAM |
5254 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005255 result);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005256 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005257 pr_err("Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005258
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005259 if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005260 /* 0x0000 NOT LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005261 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005262 /* 0x4000 DEMOD LOCKED */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005263 *p_lock_status = DEMOD_LOCK;
5264 } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005265 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005266 *p_lock_status = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005267 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005268 /* 0xC000 NEVER LOCKED */
5269 /* (system will never be able to lock to the signal) */
5270 /* TODO: check this, intermediate & standard specific lock states are not
5271 taken into account here */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005272 *p_lock_status = NEVER_LOCK;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005273 }
5274 return status;
5275}
5276
5277#define QAM_MIRROR__M 0x03
5278#define QAM_MIRROR_NORMAL 0x00
5279#define QAM_MIRRORED 0x01
5280#define QAM_MIRROR_AUTO_ON 0x02
5281#define QAM_LOCKRANGE__M 0x10
5282#define QAM_LOCKRANGE_NORMAL 0x10
5283
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005284static int qam_demodulator_command(struct drxk_state *state,
5285 int number_of_parameters)
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005286{
5287 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005288 u16 cmd_result;
5289 u16 set_param_parameters[4] = { 0, 0, 0, 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005290
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005291 set_param_parameters[0] = state->m_constellation; /* modulation */
5292 set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005293
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005294 if (number_of_parameters == 2) {
5295 u16 set_env_parameters[1] = { 0 };
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005296
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005297 if (state->m_operation_mode == OM_QAM_ITU_C)
5298 set_env_parameters[0] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005299 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005300 set_env_parameters[0] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005301
5302 status = scu_command(state,
5303 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005304 1, set_env_parameters, 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005305 if (status < 0)
5306 goto error;
5307
5308 status = scu_command(state,
5309 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005310 number_of_parameters, set_param_parameters,
5311 1, &cmd_result);
5312 } else if (number_of_parameters == 4) {
5313 if (state->m_operation_mode == OM_QAM_ITU_C)
5314 set_param_parameters[2] = QAM_TOP_ANNEX_C;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005315 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005316 set_param_parameters[2] = QAM_TOP_ANNEX_A;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005317
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005318 set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005319 /* Env parameters */
5320 /* check for LOCKRANGE Extented */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005321 /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005322
5323 status = scu_command(state,
5324 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03005325 number_of_parameters, set_param_parameters,
5326 1, &cmd_result);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005327 } else {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005328 pr_warn("Unknown QAM demodulator parameter count %d\n",
5329 number_of_parameters);
Mauro Carvalho Chehab94af1b62012-10-29 07:58:59 -02005330 status = -EINVAL;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005331 }
5332
5333error:
5334 if (status < 0)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005335 pr_warn("Warning %d on %s\n", status, __func__);
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03005336 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 Chehab7eaf7182012-07-06 14:53:51 -03005426 /*
5427 * One of our commands was successful. We don't need to
5428 * auto-probe anymore, now that we got the correct command.
5429 */
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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005590 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005752 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005835 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005860 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005885 pr_err("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)
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03005922 pr_err("Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005923
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 Chehab3a4398f2013-04-28 11:47:45 -03006063 pr_info("DRXK driver version %d.%d.%d\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006064 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 Chehab3a4398f2013-04-28 11:47:45 -03006131 pr_err("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) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006144 pr_err("Could not load firmware file %s.\n",
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006145 state->microcode_name);
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006146 pr_info("Copy %s to your hotplug directory!\n",
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006147 state->microcode_name);
6148 state->microcode_name = NULL;
6149
6150 /*
6151 * As firmware is now load asynchronous, it is not possible
6152 * anymore to fail at frontend attach. We might silently
6153 * return here, and hope that the driver won't crash.
6154 * We might also change all DVB callbacks to return -ENODEV
6155 * if the device is not initialized.
6156 * As the DRX-K devices have their own internal firmware,
6157 * let's just hope that it will match a firmware revision
6158 * compatible with this driver and proceed.
6159 */
6160 }
6161 state->fw = fw;
6162
6163 init_drxk(state);
6164}
6165
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006166static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006167{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006168 struct drxk_state *state = fe->demodulator_priv;
6169
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006170 dprintk(1, "\n");
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006171 if (state->fw)
6172 release_firmware(state->fw);
6173
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174 kfree(state);
6175}
6176
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006177static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006178{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006179 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006180
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006181 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006182
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006183 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006184 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006185 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006186 return 0;
6187
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006188 shut_down(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189 return 0;
6190}
6191
Oliver Endrissebc7de22011-07-03 13:49:44 -03006192static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006193{
6194 struct drxk_state *state = fe->demodulator_priv;
6195
Martin Blumenstingl257ee972012-07-04 17:38:23 -03006196 dprintk(1, ": %s\n", enable ? "enable" : "disable");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006197
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006198 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006199 return -ENODEV;
6200
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006201 return ConfigureI2CBridge(state, enable ? true : false);
6202}
6203
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006204static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006205{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006206 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006207 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006208 struct drxk_state *state = fe->demodulator_priv;
6209 u32 IF;
6210
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006211 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006212
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006213 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006214 return -ENODEV;
6215
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006216 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006217 return -EAGAIN;
6218
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006219 if (!fe->ops.tuner_ops.get_if_frequency) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006220 pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006221 return -EINVAL;
6222 }
6223
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006224 if (fe->ops.i2c_gate_ctrl)
6225 fe->ops.i2c_gate_ctrl(fe, 1);
6226 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006227 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006228 if (fe->ops.i2c_gate_ctrl)
6229 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006230
6231 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006232 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006233
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006234 if (old_delsys != delsys) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006235 shut_down(state);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006236 switch (delsys) {
6237 case SYS_DVBC_ANNEX_A:
6238 case SYS_DVBC_ANNEX_C:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006239 if (!state->m_has_dvbc)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006240 return -EINVAL;
6241 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6242 if (state->m_itut_annex_c)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006243 setoperation_mode(state, OM_QAM_ITU_C);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006244 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006245 setoperation_mode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006246 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006247 case SYS_DVBT:
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006248 if (!state->m_has_dvbt)
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006249 return -EINVAL;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006250 setoperation_mode(state, OM_DVBT);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006251 break;
6252 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006253 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006254 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006255 }
6256
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006257 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006258 start(state, 0, IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006259
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006260 /* After set_frontend, stats aren't avaliable */
6261 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6262 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6263 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6264 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6265 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6266 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6267 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6268 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6269
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006270 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006271
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006272 return 0;
6273}
6274
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006275static int get_strength(struct drxk_state *state, u64 *strength)
6276{
6277 int status;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006278 struct s_cfg_agc rf_agc, if_agc;
6279 u32 total_gain = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006280 u32 atten = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006281 u32 agc_range = 0;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006282 u16 scu_lvl = 0;
6283 u16 scu_coc = 0;
6284 /* FIXME: those are part of the tuner presets */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006285 u16 tuner_rf_gain = 50; /* Default value on az6007 driver */
6286 u16 tuner_if_gain = 40; /* Default value on az6007 driver */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006287
6288 *strength = 0;
6289
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006290 if (is_dvbt(state)) {
6291 rf_agc = state->m_dvbt_rf_agc_cfg;
6292 if_agc = state->m_dvbt_if_agc_cfg;
6293 } else if (is_qam(state)) {
6294 rf_agc = state->m_qam_rf_agc_cfg;
6295 if_agc = state->m_qam_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006296 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006297 rf_agc = state->m_atv_rf_agc_cfg;
6298 if_agc = state->m_atv_if_agc_cfg;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006299 }
6300
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006301 if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6302 /* SCU output_level */
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006303 status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
6304 if (status < 0)
6305 return status;
6306
6307 /* SCU c.o.c. */
6308 read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
6309 if (status < 0)
6310 return status;
6311
6312 if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006313 rf_agc.output_level = scu_lvl + scu_coc;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006314 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006315 rf_agc.output_level = 0xffff;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006316
6317 /* Take RF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006318 total_gain += tuner_rf_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006319
6320 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006321 if (rf_agc.output_level < rf_agc.min_output_level)
6322 rf_agc.output_level = rf_agc.min_output_level;
6323 if (rf_agc.output_level > rf_agc.max_output_level)
6324 rf_agc.output_level = rf_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006325
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006326 agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6327 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006328 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006329 ((u32)(tuner_rf_gain)) *
6330 ((u32)(rf_agc.output_level - rf_agc.min_output_level))
6331 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006332 }
6333 }
6334
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006335 if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006336 status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006337 &if_agc.output_level);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006338 if (status < 0)
6339 return status;
6340
6341 status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006342 &if_agc.top);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006343 if (status < 0)
6344 return status;
6345
6346 /* Take IF gain into account */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006347 total_gain += (u32) tuner_if_gain;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006348
6349 /* clip output value */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006350 if (if_agc.output_level < if_agc.min_output_level)
6351 if_agc.output_level = if_agc.min_output_level;
6352 if (if_agc.output_level > if_agc.max_output_level)
6353 if_agc.output_level = if_agc.max_output_level;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006354
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006355 agc_range = (u32) (if_agc.max_output_level - if_agc.min_output_level);
6356 if (agc_range > 0) {
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006357 atten += 100UL *
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006358 ((u32)(tuner_if_gain)) *
6359 ((u32)(if_agc.output_level - if_agc.min_output_level))
6360 / agc_range;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006361 }
6362 }
6363
6364 /*
6365 * Convert to 0..65535 scale.
6366 * If it can't be measured (AGC is disabled), just show 100%.
6367 */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006368 if (total_gain > 0)
6369 *strength = (65535UL * atten / total_gain / 100);
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006370 else
6371 *strength = 65535;
6372
6373 return 0;
6374}
6375
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006376static int drxk_get_stats(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006377{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006378 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006379 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006380 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006381 u32 stat;
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006382 u16 reg16;
6383 u32 post_bit_count;
6384 u32 post_bit_err_count;
6385 u32 post_bit_error_scale;
6386 u32 pre_bit_err_count;
6387 u32 pre_bit_count;
6388 u32 pkt_count;
6389 u32 pkt_error_count;
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006390 s32 cnr;
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006391
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006392 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006393 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006394 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006395 return -EAGAIN;
6396
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006397 /* get status */
6398 state->fe_status = 0;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006399 get_lock_status(state, &stat);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006400 if (stat == MPEG_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006401 state->fe_status |= 0x1f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006402 if (stat == FEC_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006403 state->fe_status |= 0x0f;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006404 if (stat == DEMOD_LOCK)
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006405 state->fe_status |= 0x07;
6406
Mauro Carvalho Chehab59a7a232013-03-20 08:21:52 -03006407 /*
6408 * Estimate signal strength from AGC
6409 */
6410 get_strength(state, &c->strength.stat[0].uvalue);
6411 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
6412
6413
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006414 if (stat >= DEMOD_LOCK) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006415 get_signal_to_noise(state, &cnr);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006416 c->cnr.stat[0].svalue = cnr * 100;
6417 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6418 } else {
6419 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6420 }
6421
6422 if (stat < FEC_LOCK) {
6423 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6424 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6425 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6426 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6427 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6428 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6429 return 0;
6430 }
6431
6432 /* Get post BER */
6433
6434 /* BER measurement is valid if at least FEC lock is achieved */
6435
6436 /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
6437 to set nr of symbols or bits over which
6438 to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
6439
6440 /* Read registers for post/preViterbi BER calculation */
6441 status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
6442 if (status < 0)
6443 goto error;
6444 pre_bit_err_count = reg16;
6445
6446 status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
6447 if (status < 0)
6448 goto error;
6449 pre_bit_count = reg16;
6450
6451 /* Number of bit-errors */
6452 status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
6453 if (status < 0)
6454 goto error;
6455 post_bit_err_count = reg16;
6456
6457 status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
6458 if (status < 0)
6459 goto error;
6460 post_bit_error_scale = reg16;
6461
6462 status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
6463 if (status < 0)
6464 goto error;
6465 pkt_count = reg16;
6466
6467 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
6468 if (status < 0)
6469 goto error;
6470 pkt_error_count = reg16;
6471 write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6472
6473 post_bit_err_count *= post_bit_error_scale;
6474
6475 post_bit_count = pkt_count * 204 * 8;
6476
6477 /* Store the results */
6478 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
6479 c->block_error.stat[0].uvalue += pkt_error_count;
6480 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
6481 c->block_count.stat[0].uvalue += pkt_count;
6482
6483 c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6484 c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
6485 c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6486 c->pre_bit_count.stat[0].uvalue += pre_bit_count;
6487
6488 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
6489 c->post_bit_error.stat[0].uvalue += post_bit_err_count;
6490 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
6491 c->post_bit_count.stat[0].uvalue += post_bit_count;
6492
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006493error:
6494 return status;
6495}
6496
6497
6498static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6499{
6500 struct drxk_state *state = fe->demodulator_priv;
6501 int rc;
6502
6503 dprintk(1, "\n");
6504
6505 rc = drxk_get_stats(fe);
6506 if (rc < 0)
6507 return rc;
6508
6509 *status = state->fe_status;
6510
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006511 return 0;
6512}
6513
Oliver Endrissebc7de22011-07-03 13:49:44 -03006514static int drxk_read_signal_strength(struct dvb_frontend *fe,
6515 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006516{
6517 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006518 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006519
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006520 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006521
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006522 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006523 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006524 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006525 return -EAGAIN;
6526
Mauro Carvalho Chehab340e7692013-03-20 08:57:42 -03006527 *strength = c->strength.stat[0].uvalue;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006528 return 0;
6529}
6530
6531static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6532{
6533 struct drxk_state *state = fe->demodulator_priv;
6534 s32 snr2;
6535
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006536 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006537
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006538 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006539 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006540 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006541 return -EAGAIN;
6542
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006543 get_signal_to_noise(state, &snr2);
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006544
6545 /* No negative SNR, clip to zero */
6546 if (snr2 < 0)
6547 snr2 = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03006548 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006549 return 0;
6550}
6551
6552static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6553{
6554 struct drxk_state *state = fe->demodulator_priv;
6555 u16 err;
6556
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006557 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006558
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006559 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006560 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006561 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006562 return -EAGAIN;
6563
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006564 dvbtqam_get_acc_pkt_err(state, &err);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006565 *ucblocks = (u32) err;
6566 return 0;
6567}
6568
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006569static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006570 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006571{
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006572 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006573 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006574
6575 dprintk(1, "\n");
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006576
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006577 if (state->m_drxk_state == DRXK_NO_DEV)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006578 return -ENODEV;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006579 if (state->m_drxk_state == DRXK_UNINITIALIZED)
Mauro Carvalho Chehab704a28e2012-06-29 15:45:04 -03006580 return -EAGAIN;
6581
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006582 switch (p->delivery_system) {
6583 case SYS_DVBC_ANNEX_A:
6584 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006585 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006586 sets->min_delay_ms = 3000;
6587 sets->max_drift = 0;
6588 sets->step_size = 0;
6589 return 0;
6590 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006591 return -EINVAL;
6592 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006593}
6594
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006595static struct dvb_frontend_ops drxk_ops = {
6596 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006597 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006598 .name = "DRXK",
6599 .frequency_min = 47000000,
6600 .frequency_max = 865000000,
6601 /* For DVB-C */
6602 .symbol_rate_min = 870000,
6603 .symbol_rate_max = 11700000,
6604 /* For DVB-T */
6605 .frequency_stepsize = 166667,
6606
6607 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6608 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6609 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6610 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6611 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6612 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6613 },
6614
6615 .release = drxk_release,
6616 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006617 .i2c_gate_ctrl = drxk_gate_ctrl,
6618
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006619 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006620 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006621
6622 .read_status = drxk_read_status,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006623 .read_signal_strength = drxk_read_signal_strength,
6624 .read_snr = drxk_read_snr,
6625 .read_ucblocks = drxk_read_ucblocks,
6626};
6627
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006628struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006629 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006630{
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006631 struct dtv_frontend_properties *p;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006632 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006633 u8 adr = config->adr;
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006634 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006635
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006636 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006637 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006638 if (!state)
6639 return NULL;
6640
Oliver Endrissebc7de22011-07-03 13:49:44 -03006641 state->i2c = i2c;
6642 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006643 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006644 state->microcode_name = config->microcode_name;
Martin Blumenstingl9e23f50a2012-07-04 17:36:55 -03006645 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006646 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006647 state->antenna_gpio = config->antenna_gpio;
6648 state->antenna_dvbt = config->antenna_dvbt;
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006649 state->m_chunk_size = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006650 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006651
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006652 if (config->dynamic_clk) {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006653 state->m_dvbt_static_clk = 0;
6654 state->m_dvbc_static_clk = 0;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006655 } else {
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006656 state->m_dvbt_static_clk = 1;
6657 state->m_dvbc_static_clk = 1;
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006658 }
6659
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006660
6661 if (config->mpeg_out_clk_strength)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006662 state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006663 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006664 state->m_ts_clockk_strength = 0x06;
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006665
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006666 if (config->parallel_ts)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006667 state->m_enable_parallel = true;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006668 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006669 state->m_enable_parallel = false;
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006670
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006671 /* NOTE: as more UIO bits will be used, add them to the mask */
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006672 state->uio_mask = config->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006673
6674 /* Default gpio to DVB-C */
6675 if (!state->antenna_dvbt && state->antenna_gpio)
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006676 state->m_gpio |= state->antenna_gpio;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006677 else
Mauro Carvalho Chehabcd7a67a2013-04-28 11:47:44 -03006678 state->m_gpio &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006679
6680 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006681
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006682 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6683 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006684
6685 init_state(state);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006686
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006687 /* Load firmware and initialize DRX-K */
6688 if (state->microcode_name) {
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006689 if (config->load_firmware_sync) {
6690 const struct firmware *fw = NULL;
6691
6692 status = request_firmware(&fw, state->microcode_name,
6693 state->i2c->dev.parent);
6694 if (status < 0)
6695 fw = NULL;
6696 load_firmware_cb(fw, state);
6697 } else {
6698 status = request_firmware_nowait(THIS_MODULE, 1,
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006699 state->microcode_name,
6700 state->i2c->dev.parent,
6701 GFP_KERNEL,
6702 state, load_firmware_cb);
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006703 if (status < 0) {
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006704 pr_err("failed to request a firmware\n");
Mauro Carvalho Chehab8e307832012-10-02 16:01:15 -03006705 return NULL;
6706 }
Mauro Carvalho Chehab177bc7d2012-06-21 09:36:38 -03006707 }
6708 } else if (init_drxk(state) < 0)
6709 goto error;
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006710
Mauro Carvalho Chehab8f3741e2013-03-20 06:15:45 -03006711
6712 /* Initialize stats */
6713 p = &state->frontend.dtv_property_cache;
6714 p->strength.len = 1;
6715 p->cnr.len = 1;
6716 p->block_error.len = 1;
6717 p->block_count.len = 1;
6718 p->pre_bit_error.len = 1;
6719 p->pre_bit_count.len = 1;
6720 p->post_bit_error.len = 1;
6721 p->post_bit_count.len = 1;
6722
6723 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
6724 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6725 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6726 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6727 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6728 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6729 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6730 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6731
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006732 pr_info("frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006733 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006734
6735error:
Mauro Carvalho Chehab3a4398f2013-04-28 11:47:45 -03006736 pr_err("not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006737 kfree(state);
6738 return NULL;
6739}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006740EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006741
6742MODULE_DESCRIPTION("DRX-K driver");
6743MODULE_AUTHOR("Ralph Metzler");
6744MODULE_LICENSE("GPL");