blob: 88bd1c888ca8e5a109dde658b01992d0cef2c5fd [file] [log] [blame]
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
Ralph Metzler43dd07f2011-07-03 13:42:18 -030031#include <asm/div64.h>
32
33#include "dvb_frontend.h"
34#include "drxk.h"
35#include "drxk_hard.h"
36
37static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
38static int PowerDownQAM(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030039static int SetDVBTStandard(struct drxk_state *state,
40 enum OperationMode oMode);
41static int SetQAMStandard(struct drxk_state *state,
42 enum OperationMode oMode);
43static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
Ralph Metzler43dd07f2011-07-03 13:42:18 -030044 s32 tunerFreqOffset);
Oliver Endrissebc7de22011-07-03 13:49:44 -030045static int SetDVBTStandard(struct drxk_state *state,
46 enum OperationMode oMode);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030047static int DVBTStart(struct drxk_state *state);
Oliver Endrissebc7de22011-07-03 13:49:44 -030048static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
49 s32 tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -030050static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
51static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int SwitchAntennaToQAM(struct drxk_state *state);
53static int SwitchAntennaToDVBT(struct drxk_state *state);
54
55static bool IsDVBT(struct drxk_state *state)
56{
57 return state->m_OperationMode == OM_DVBT;
58}
59
60static bool IsQAM(struct drxk_state *state)
61{
62 return state->m_OperationMode == OM_QAM_ITU_A ||
Oliver Endrissebc7de22011-07-03 13:49:44 -030063 state->m_OperationMode == OM_QAM_ITU_B ||
64 state->m_OperationMode == OM_QAM_ITU_C;
Ralph Metzler43dd07f2011-07-03 13:42:18 -030065}
66
67bool IsA1WithPatchCode(struct drxk_state *state)
68{
69 return state->m_DRXK_A1_PATCH_CODE;
70}
71
72bool IsA1WithRomCode(struct drxk_state *state)
73{
74 return state->m_DRXK_A1_ROM_CODE;
75}
76
77#define NOA1ROM 0
78
Ralph Metzler43dd07f2011-07-03 13:42:18 -030079#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
80#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
81
82#define DEFAULT_MER_83 165
83#define DEFAULT_MER_93 250
84
85#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
86#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
87#endif
88
89#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
90#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
91#endif
92
Ralph Metzler43dd07f2011-07-03 13:42:18 -030093#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
94#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
95
96#ifndef DRXK_KI_RAGC_ATV
97#define DRXK_KI_RAGC_ATV 4
98#endif
99#ifndef DRXK_KI_IAGC_ATV
100#define DRXK_KI_IAGC_ATV 6
101#endif
102#ifndef DRXK_KI_DAGC_ATV
103#define DRXK_KI_DAGC_ATV 7
104#endif
105
106#ifndef DRXK_KI_RAGC_QAM
107#define DRXK_KI_RAGC_QAM 3
108#endif
109#ifndef DRXK_KI_IAGC_QAM
110#define DRXK_KI_IAGC_QAM 4
111#endif
112#ifndef DRXK_KI_DAGC_QAM
113#define DRXK_KI_DAGC_QAM 7
114#endif
115#ifndef DRXK_KI_RAGC_DVBT
116#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
117#endif
118#ifndef DRXK_KI_IAGC_DVBT
119#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
120#endif
121#ifndef DRXK_KI_DAGC_DVBT
122#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
123#endif
124
125#ifndef DRXK_AGC_DAC_OFFSET
126#define DRXK_AGC_DAC_OFFSET (0x800)
127#endif
128
129#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
130#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
131#endif
132
133#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
134#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
135#endif
136
137#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
138#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
139#endif
140
141#ifndef DRXK_QAM_SYMBOLRATE_MAX
142#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
143#endif
144
145#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
146#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
147#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
148#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
149#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
150#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
151#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
152#define DRXK_BL_ROM_OFFSET_UCODE 0
153
154#define DRXK_BLC_TIMEOUT 100
155
156#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
157#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
158
159#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
160
161#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
162#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
163#endif
164
165#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
166#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
167#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
168#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
169#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
170
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300171static unsigned int debug;
172module_param(debug, int, 0644);
173MODULE_PARM_DESC(debug, "enable debug messages");
174
175#define dprintk(level, fmt, arg...) do { \
176if (debug >= level) \
177 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
178} while (0)
179
180
Mauro Carvalho Chehabb01fbc12011-07-03 17:18:57 -0300181static inline u32 MulDiv32(u32 a, u32 b, u32 c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300182{
183 u64 tmp64;
184
Oliver Endrissebc7de22011-07-03 13:49:44 -0300185 tmp64 = (u64) a * (u64) b;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300186 do_div(tmp64, c);
187
188 return (u32) tmp64;
189}
190
191inline u32 Frac28a(u32 a, u32 c)
192{
193 int i = 0;
194 u32 Q1 = 0;
195 u32 R0 = 0;
196
Oliver Endrissebc7de22011-07-03 13:49:44 -0300197 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
198 Q1 = a / c; /* integer part, only the 4 least significant bits
199 will be visible in the result */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300200
201 /* division using radix 16, 7 nibbles in the result */
202 for (i = 0; i < 7; i++) {
203 Q1 = (Q1 << 4) | (R0 / c);
204 R0 = (R0 % c) << 4;
205 }
206 /* rounding */
207 if ((R0 >> 3) >= c)
208 Q1++;
209
210 return Q1;
211}
212
213static u32 Log10Times100(u32 x)
214{
215 static const u8 scale = 15;
216 static const u8 indexWidth = 5;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300217 u8 i = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300218 u32 y = 0;
219 u32 d = 0;
220 u32 k = 0;
221 u32 r = 0;
222 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300223 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
224 0 <= n < ((1<<INDEXWIDTH)+1)
225 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300226
227 static const u32 log2lut[] = {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300228 0, /* 0.000000 */
229 290941, /* 290941.300628 */
230 573196, /* 573196.476418 */
231 847269, /* 847269.179851 */
232 1113620, /* 1113620.489452 */
233 1372674, /* 1372673.576986 */
234 1624818, /* 1624817.752104 */
235 1870412, /* 1870411.981536 */
236 2109788, /* 2109787.962654 */
237 2343253, /* 2343252.817465 */
238 2571091, /* 2571091.461923 */
239 2793569, /* 2793568.696416 */
240 3010931, /* 3010931.055901 */
241 3223408, /* 3223408.452106 */
242 3431216, /* 3431215.635215 */
243 3634553, /* 3634553.498355 */
244 3833610, /* 3833610.244726 */
245 4028562, /* 4028562.434393 */
246 4219576, /* 4219575.925308 */
247 4406807, /* 4406806.721144 */
248 4590402, /* 4590401.736809 */
249 4770499, /* 4770499.491025 */
250 4947231, /* 4947230.734179 */
251 5120719, /* 5120719.018555 */
252 5291081, /* 5291081.217197 */
253 5458428, /* 5458427.996830 */
254 5622864, /* 5622864.249668 */
255 5784489, /* 5784489.488298 */
256 5943398, /* 5943398.207380 */
257 6099680, /* 6099680.215452 */
258 6253421, /* 6253420.939751 */
259 6404702, /* 6404701.706649 */
260 6553600, /* 6553600.000000 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300261 };
262
263
264 if (x == 0)
Oliver Endrissebc7de22011-07-03 13:49:44 -0300265 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300266
267 /* Scale x (normalize) */
268 /* computing y in log(x/y) = log(x) - log(y) */
269 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
270 for (k = scale; k > 0; k--) {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300271 if (x & (((u32) 1) << scale))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300272 break;
273 x <<= 1;
274 }
275 } else {
Oliver Endrissebc7de22011-07-03 13:49:44 -0300276 for (k = scale; k < 31; k++) {
277 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300278 break;
279 x >>= 1;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300280 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300281 }
282 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -0300283 Now x has binary point between bit[scale] and bit[scale-1]
284 and 1.0 <= x < 2.0 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300285
286 /* correction for divison: log(x) = log(x/y)+log(y) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300287 y = k * ((((u32) 1) << scale) * 200);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300288
289 /* remove integer part */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300290 x &= ((((u32) 1) << scale) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300291 /* get index */
292 i = (u8) (x >> (scale - indexWidth));
293 /* compute delta (x - a) */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300294 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300295 /* compute log, multiplication (d* (..)) must be within range ! */
296 y += log2lut[i] +
Oliver Endrissebc7de22011-07-03 13:49:44 -0300297 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300298 /* Conver to log10() */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300299 y /= 108853; /* (log2(10) << scale) */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300300 r = (y >> 1);
301 /* rounding */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300302 if (y & ((u32) 1))
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300303 r++;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300304 return r;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300305}
306
307/****************************************************************************/
308/* I2C **********************************************************************/
309/****************************************************************************/
310
311static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
312{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300313 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
314 .buf = val, .len = 1}
315 };
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300316
317 return i2c_transfer(adapter, msgs, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300318}
319
320static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
321{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300322 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300323 struct i2c_msg msg = {
324 .addr = adr, .flags = 0, .buf = data, .len = len };
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300325
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300326 dprintk(3, ":");
327 if (debug > 2) {
328 int i;
329 for (i = 0; i < len; i++)
330 printk(KERN_CONT " %02x", data[i]);
331 printk(KERN_CONT "\n");
332 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300333 status = i2c_transfer(adap, &msg, 1);
334 if (status >= 0 && status != 1)
335 status = -EIO;
336
337 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300338 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300339
340 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300341}
342
343static int i2c_read(struct i2c_adapter *adap,
344 u8 adr, u8 *msg, int len, u8 *answ, int alen)
345{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300346 int status;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300347 struct i2c_msg msgs[2] = {
348 {.addr = adr, .flags = 0,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300349 .buf = msg, .len = len},
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -0300350 {.addr = adr, .flags = I2C_M_RD,
351 .buf = answ, .len = alen}
Oliver Endrissebc7de22011-07-03 13:49:44 -0300352 };
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300353
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300354 status = i2c_transfer(adap, msgs, 2);
355 if (status != 2) {
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300356 if (debug > 2)
357 printk(KERN_CONT ": ERROR!\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300358 if (status >= 0)
359 status = -EIO;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300360
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300361 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300362 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300363 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300364 if (debug > 2) {
365 int i;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300366 dprintk(2, ": read from");
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300367 for (i = 0; i < len; i++)
368 printk(KERN_CONT " %02x", msg[i]);
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300369 printk(KERN_CONT ", value = ");
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -0300370 for (i = 0; i < alen; i++)
371 printk(KERN_CONT " %02x", answ[i]);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300372 printk(KERN_CONT "\n");
373 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300374 return 0;
375}
376
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300377static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300378{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300379 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300380 u8 adr = state->demod_address, mm1[4], mm2[2], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300381
382 if (state->single_master)
383 flags |= 0xC0;
384
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300385 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
386 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
387 mm1[1] = ((reg >> 16) & 0xFF);
388 mm1[2] = ((reg >> 24) & 0xFF) | flags;
389 mm1[3] = ((reg >> 7) & 0xFF);
390 len = 4;
391 } else {
392 mm1[0] = ((reg << 1) & 0xFF);
393 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
394 len = 2;
395 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300396 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300397 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
398 if (status < 0)
399 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300400 if (data)
401 *data = mm2[0] | (mm2[1] << 8);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300402
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300403 return 0;
404}
405
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300406static int read16(struct drxk_state *state, u32 reg, u16 *data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300407{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300408 return read16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300409}
410
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300411static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300412{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300413 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300414 u8 adr = state->demod_address, mm1[4], mm2[4], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300415
416 if (state->single_master)
417 flags |= 0xC0;
418
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300419 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
420 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
421 mm1[1] = ((reg >> 16) & 0xFF);
422 mm1[2] = ((reg >> 24) & 0xFF) | flags;
423 mm1[3] = ((reg >> 7) & 0xFF);
424 len = 4;
425 } else {
426 mm1[0] = ((reg << 1) & 0xFF);
427 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
428 len = 2;
429 }
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300430 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300431 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
432 if (status < 0)
433 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300434 if (data)
435 *data = mm2[0] | (mm2[1] << 8) |
Oliver Endrissebc7de22011-07-03 13:49:44 -0300436 (mm2[2] << 16) | (mm2[3] << 24);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300437
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300438 return 0;
439}
440
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300441static int read32(struct drxk_state *state, u32 reg, u32 *data)
442{
443 return read32_flags(state, reg, data, 0);
444}
445
446static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300447{
448 u8 adr = state->demod_address, mm[6], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300449
450 if (state->single_master)
451 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300452 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
453 mm[0] = (((reg << 1) & 0xFF) | 0x01);
454 mm[1] = ((reg >> 16) & 0xFF);
455 mm[2] = ((reg >> 24) & 0xFF) | flags;
456 mm[3] = ((reg >> 7) & 0xFF);
457 len = 4;
458 } else {
459 mm[0] = ((reg << 1) & 0xFF);
460 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
461 len = 2;
462 }
463 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300464 mm[len + 1] = (data >> 8) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300465
466 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300467 return i2c_write(state->i2c, adr, mm, len + 2);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300468}
469
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300470static int write16(struct drxk_state *state, u32 reg, u16 data)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300471{
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300472 return write16_flags(state, reg, data, 0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300473}
474
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300475static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300476{
477 u8 adr = state->demod_address, mm[8], len;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300478
479 if (state->single_master)
480 flags |= 0xC0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300481 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
482 mm[0] = (((reg << 1) & 0xFF) | 0x01);
483 mm[1] = ((reg >> 16) & 0xFF);
484 mm[2] = ((reg >> 24) & 0xFF) | flags;
485 mm[3] = ((reg >> 7) & 0xFF);
486 len = 4;
487 } else {
488 mm[0] = ((reg << 1) & 0xFF);
489 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
490 len = 2;
491 }
492 mm[len] = data & 0xff;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300493 mm[len + 1] = (data >> 8) & 0xff;
494 mm[len + 2] = (data >> 16) & 0xff;
495 mm[len + 3] = (data >> 24) & 0xff;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300496 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300497
498 return i2c_write(state->i2c, adr, mm, len + 4);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300499}
500
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300501static int write32(struct drxk_state *state, u32 reg, u32 data)
502{
503 return write32_flags(state, reg, data, 0);
504}
505
506static int write_block(struct drxk_state *state, u32 Address,
507 const int BlockSize, const u8 pBlock[])
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300508{
509 int status = 0, BlkSize = BlockSize;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -0300510 u8 Flags = 0;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -0300511
512 if (state->single_master)
513 Flags |= 0xC0;
514
Oliver Endrissebc7de22011-07-03 13:49:44 -0300515 while (BlkSize > 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300516 int Chunk = BlkSize > state->m_ChunkSize ?
Oliver Endrissebc7de22011-07-03 13:49:44 -0300517 state->m_ChunkSize : BlkSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300518 u8 *AdrBuf = &state->Chunk[0];
519 u32 AdrLength = 0;
520
Oliver Endrissebc7de22011-07-03 13:49:44 -0300521 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
522 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
523 AdrBuf[1] = ((Address >> 16) & 0xFF);
524 AdrBuf[2] = ((Address >> 24) & 0xFF);
525 AdrBuf[3] = ((Address >> 7) & 0xFF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300526 AdrBuf[2] |= Flags;
527 AdrLength = 4;
528 if (Chunk == state->m_ChunkSize)
529 Chunk -= 2;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300530 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300531 AdrBuf[0] = ((Address << 1) & 0xFF);
532 AdrBuf[1] = (((Address >> 16) & 0x0F) |
533 ((Address >> 18) & 0xF0));
534 AdrLength = 2;
535 }
536 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300537 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
538 if (debug > 1) {
539 int i;
540 if (pBlock)
541 for (i = 0; i < Chunk; i++)
542 printk(KERN_CONT " %02x", pBlock[i]);
543 printk(KERN_CONT "\n");
544 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300545 status = i2c_write(state->i2c, state->demod_address,
Oliver Endrissebc7de22011-07-03 13:49:44 -0300546 &state->Chunk[0], Chunk + AdrLength);
547 if (status < 0) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -0300548 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
549 __func__, Address);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300550 break;
551 }
552 pBlock += Chunk;
553 Address += (Chunk >> 1);
554 BlkSize -= Chunk;
555 }
Oliver Endrissebc7de22011-07-03 13:49:44 -0300556 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300557}
558
559#ifndef DRXK_MAX_RETRIES_POWERUP
560#define DRXK_MAX_RETRIES_POWERUP 20
561#endif
562
563int PowerUpDevice(struct drxk_state *state)
564{
565 int status;
566 u8 data = 0;
567 u16 retryCount = 0;
568
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300569 dprintk(1, "\n");
570
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300571 status = i2c_read1(state->i2c, state->demod_address, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300572 if (status < 0) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300573 do {
574 data = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300575 status = i2c_write(state->i2c, state->demod_address,
576 &data, 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300577 msleep(10);
Oliver Endrissebc7de22011-07-03 13:49:44 -0300578 retryCount++;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300579 if (status < 0)
580 continue;
581 status = i2c_read1(state->i2c, state->demod_address,
582 &data);
583 } while (status < 0 &&
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300584 (retryCount < DRXK_MAX_RETRIES_POWERUP));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300585 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
586 goto error;
587 }
588
589 /* Make sure all clk domains are active */
590 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
591 if (status < 0)
592 goto error;
593 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
594 if (status < 0)
595 goto error;
596 /* Enable pll lock tests */
597 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
598 if (status < 0)
599 goto error;
600
601 state->m_currentPowerMode = DRX_POWER_UP;
602
603error:
604 if (status < 0)
605 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
606
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300607 return status;
608}
609
610
611static int init_state(struct drxk_state *state)
612{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -0300613 /*
614 * FIXME: most (all?) of the values bellow should be moved into
615 * struct drxk_config, as they are probably board-specific
616 */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300617 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
618 u32 ulVSBIfAgcOutputLevel = 0;
619 u32 ulVSBIfAgcMinLevel = 0;
620 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
621 u32 ulVSBIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300622
Oliver Endrissebc7de22011-07-03 13:49:44 -0300623 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
624 u32 ulVSBRfAgcOutputLevel = 0;
625 u32 ulVSBRfAgcMinLevel = 0;
626 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
627 u32 ulVSBRfAgcSpeed = 3;
628 u32 ulVSBRfAgcTop = 9500;
629 u32 ulVSBRfAgcCutOffCurrent = 4000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300630
Oliver Endrissebc7de22011-07-03 13:49:44 -0300631 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
632 u32 ulATVIfAgcOutputLevel = 0;
633 u32 ulATVIfAgcMinLevel = 0;
634 u32 ulATVIfAgcMaxLevel = 0;
635 u32 ulATVIfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300636
Oliver Endrissebc7de22011-07-03 13:49:44 -0300637 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
638 u32 ulATVRfAgcOutputLevel = 0;
639 u32 ulATVRfAgcMinLevel = 0;
640 u32 ulATVRfAgcMaxLevel = 0;
641 u32 ulATVRfAgcTop = 9500;
642 u32 ulATVRfAgcCutOffCurrent = 4000;
643 u32 ulATVRfAgcSpeed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300644
645 u32 ulQual83 = DEFAULT_MER_83;
646 u32 ulQual93 = DEFAULT_MER_93;
647
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300648 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
649 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
650
651 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
652 /* io_pad_cfg_mode output mode is drive always */
653 /* io_pad_cfg_drive is set to power 2 (23 mA) */
654 u32 ulGPIOCfg = 0x0113;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300655 u32 ulInvertTSClock = 0;
656 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300657 u32 ulDVBTBitrate = 50000000;
658 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
659
660 u32 ulInsertRSByte = 0;
661
662 u32 ulRfMirror = 1;
663 u32 ulPowerDown = 0;
664
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300665 dprintk(1, "\n");
666
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300667 state->m_hasLNA = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300668 state->m_hasDVBT = false;
669 state->m_hasDVBC = false;
670 state->m_hasATV = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300671 state->m_hasOOB = false;
672 state->m_hasAudio = false;
673
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -0300674 if (!state->m_ChunkSize)
Mauro Carvalho Chehabde724052011-11-20 11:23:24 -0200675 state->m_ChunkSize = 124;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300676
677 state->m_oscClockFreq = 0;
678 state->m_smartAntInverted = false;
679 state->m_bPDownOpenBridge = false;
680
681 /* real system clock frequency in kHz */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300682 state->m_sysClockFreq = 151875;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300683 /* Timing div, 250ns/Psys */
684 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
685 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
686 HI_I2C_DELAY) / 1000;
687 /* Clipping */
688 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
689 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
690 state->m_HICfgWakeUpKey = (state->demod_address << 1);
691 /* port/bridge/power down ctrl */
692 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
693
694 state->m_bPowerDown = (ulPowerDown != 0);
695
696 state->m_DRXK_A1_PATCH_CODE = false;
697 state->m_DRXK_A1_ROM_CODE = false;
698 state->m_DRXK_A2_ROM_CODE = false;
699 state->m_DRXK_A3_ROM_CODE = false;
700 state->m_DRXK_A2_PATCH_CODE = false;
701 state->m_DRXK_A3_PATCH_CODE = false;
702
703 /* Init AGC and PGA parameters */
704 /* VSB IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300705 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
706 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
707 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
708 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
709 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300710 state->m_vsbPgaCfg = 140;
711
712 /* VSB RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300713 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
714 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
715 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
716 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
717 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
718 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
719 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
720 state->m_vsbPreSawCfg.reference = 0x07;
721 state->m_vsbPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300722
723 state->m_Quality83percent = DEFAULT_MER_83;
724 state->m_Quality93percent = DEFAULT_MER_93;
725 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
726 state->m_Quality83percent = ulQual83;
727 state->m_Quality93percent = ulQual93;
728 }
729
730 /* ATV IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300731 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
732 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
733 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
734 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
735 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300736
737 /* ATV RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300738 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
739 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
740 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
741 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
742 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
743 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
744 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
745 state->m_atvPreSawCfg.reference = 0x04;
746 state->m_atvPreSawCfg.usePreSaw = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300747
748
749 /* DVBT RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300750 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
751 state->m_dvbtRfAgcCfg.outputLevel = 0;
752 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
753 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
754 state->m_dvbtRfAgcCfg.top = 0x2100;
755 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
756 state->m_dvbtRfAgcCfg.speed = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300757
758
759 /* DVBT IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300760 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
761 state->m_dvbtIfAgcCfg.outputLevel = 0;
762 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
763 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
764 state->m_dvbtIfAgcCfg.top = 13424;
765 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
766 state->m_dvbtIfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300767 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300768 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
769 /* state->m_dvbtPgaCfg = 140; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300770
Oliver Endrissebc7de22011-07-03 13:49:44 -0300771 state->m_dvbtPreSawCfg.reference = 4;
772 state->m_dvbtPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300773
774 /* QAM RF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300775 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
776 state->m_qamRfAgcCfg.outputLevel = 0;
777 state->m_qamRfAgcCfg.minOutputLevel = 6023;
778 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
779 state->m_qamRfAgcCfg.top = 0x2380;
780 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
781 state->m_qamRfAgcCfg.speed = 3;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300782
783 /* QAM IF */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300784 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
785 state->m_qamIfAgcCfg.outputLevel = 0;
786 state->m_qamIfAgcCfg.minOutputLevel = 0;
787 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
788 state->m_qamIfAgcCfg.top = 0x0511;
789 state->m_qamIfAgcCfg.cutOffCurrent = 0;
790 state->m_qamIfAgcCfg.speed = 3;
791 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300792 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
793
Oliver Endrissebc7de22011-07-03 13:49:44 -0300794 state->m_qamPgaCfg = 140;
795 state->m_qamPreSawCfg.reference = 4;
796 state->m_qamPreSawCfg.usePreSaw = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300797
798 state->m_OperationMode = OM_NONE;
799 state->m_DrxkState = DRXK_UNINITIALIZED;
800
801 /* MPEG output configuration */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300802 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
803 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
Oliver Endrissebc7de22011-07-03 13:49:44 -0300804 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
805 state->m_invertERR = false; /* If TRUE; invert ERR signal */
806 state->m_invertSTR = false; /* If TRUE; invert STR signals */
807 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
808 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -0300809
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300810 /* If TRUE; static MPEG clockrate will be used;
811 otherwise clockrate will adapt to the bitrate of the TS */
812
813 state->m_DVBTBitrate = ulDVBTBitrate;
814 state->m_DVBCBitrate = ulDVBCBitrate;
815
816 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300817
818 /* Maximum bitrate in b/s in case static clockrate is selected */
819 state->m_mpegTsStaticBitrate = 19392658;
820 state->m_disableTEIhandling = false;
821
822 if (ulInsertRSByte)
823 state->m_insertRSByte = true;
824
825 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
826 if (ulMpegLockTimeOut < 10000)
827 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
828 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
829 if (ulDemodLockTimeOut < 10000)
830 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
831
Oliver Endrissebc7de22011-07-03 13:49:44 -0300832 /* QAM defaults */
833 state->m_Constellation = DRX_CONSTELLATION_AUTO;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300834 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
Oliver Endrissebc7de22011-07-03 13:49:44 -0300835 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
836 state->m_fecRsPrescale = 1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300837
838 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
839 state->m_agcFastClipCtrlDelay = 0;
840
841 state->m_GPIOCfg = (ulGPIOCfg);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300842
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300843 state->m_bPowerDown = false;
844 state->m_currentPowerMode = DRX_POWER_DOWN;
845
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300846 state->m_rfmirror = (ulRfMirror == 0);
847 state->m_IfAgcPol = false;
848 return 0;
849}
850
851static int DRXX_Open(struct drxk_state *state)
852{
853 int status = 0;
854 u32 jtag = 0;
855 u16 bid = 0;
856 u16 key = 0;
857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300858 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300859 /* stop lock indicator process */
860 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
861 if (status < 0)
862 goto error;
863 /* Check device id */
864 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
865 if (status < 0)
866 goto error;
867 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
868 if (status < 0)
869 goto error;
870 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
871 if (status < 0)
872 goto error;
873 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
874 if (status < 0)
875 goto error;
876 status = write16(state, SIO_TOP_COMM_KEY__A, key);
877error:
878 if (status < 0)
879 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300880 return status;
881}
882
883static int GetDeviceCapabilities(struct drxk_state *state)
884{
Oliver Endrissebc7de22011-07-03 13:49:44 -0300885 u16 sioPdrOhwCfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300886 u32 sioTopJtagidLo = 0;
887 int status;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300888 const char *spin = "";
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300889
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -0300890 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300891
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300892 /* driver 0.9.0 */
893 /* stop lock indicator process */
894 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
895 if (status < 0)
896 goto error;
897 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
898 if (status < 0)
899 goto error;
900 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
901 if (status < 0)
902 goto error;
903 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
904 if (status < 0)
905 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -0300906
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300907 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
908 case 0:
909 /* ignore (bypass ?) */
910 break;
911 case 1:
912 /* 27 MHz */
913 state->m_oscClockFreq = 27000;
914 break;
915 case 2:
916 /* 20.25 MHz */
917 state->m_oscClockFreq = 20250;
918 break;
919 case 3:
920 /* 4 MHz */
921 state->m_oscClockFreq = 20250;
922 break;
923 default:
924 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
925 return -EINVAL;
926 }
927 /*
928 Determine device capabilities
929 Based on pinning v14
930 */
931 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
932 if (status < 0)
933 goto error;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300934
935printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300937 /* driver 0.9.0 */
938 switch ((sioTopJtagidLo >> 29) & 0xF) {
939 case 0:
940 state->m_deviceSpin = DRXK_SPIN_A1;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300941 spin = "A1";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300942 break;
943 case 2:
944 state->m_deviceSpin = DRXK_SPIN_A2;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300945 spin = "A2";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300946 break;
947 case 3:
948 state->m_deviceSpin = DRXK_SPIN_A3;
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -0300949 spin = "A3";
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300950 break;
951 default:
952 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
953 status = -EINVAL;
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -0300954 printk(KERN_ERR "drxk: Spin %d unknown\n",
955 (sioTopJtagidLo >> 29) & 0xF);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -0300956 goto error2;
957 }
958 switch ((sioTopJtagidLo >> 12) & 0xFF) {
959 case 0x13:
960 /* typeId = DRX3913K_TYPE_ID */
961 state->m_hasLNA = false;
962 state->m_hasOOB = false;
963 state->m_hasATV = false;
964 state->m_hasAudio = false;
965 state->m_hasDVBT = true;
966 state->m_hasDVBC = true;
967 state->m_hasSAWSW = true;
968 state->m_hasGPIO2 = false;
969 state->m_hasGPIO1 = false;
970 state->m_hasIRQN = false;
971 break;
972 case 0x15:
973 /* typeId = DRX3915K_TYPE_ID */
974 state->m_hasLNA = false;
975 state->m_hasOOB = false;
976 state->m_hasATV = true;
977 state->m_hasAudio = false;
978 state->m_hasDVBT = true;
979 state->m_hasDVBC = false;
980 state->m_hasSAWSW = true;
981 state->m_hasGPIO2 = true;
982 state->m_hasGPIO1 = true;
983 state->m_hasIRQN = false;
984 break;
985 case 0x16:
986 /* typeId = DRX3916K_TYPE_ID */
987 state->m_hasLNA = false;
988 state->m_hasOOB = false;
989 state->m_hasATV = true;
990 state->m_hasAudio = false;
991 state->m_hasDVBT = true;
992 state->m_hasDVBC = false;
993 state->m_hasSAWSW = true;
994 state->m_hasGPIO2 = true;
995 state->m_hasGPIO1 = true;
996 state->m_hasIRQN = false;
997 break;
998 case 0x18:
999 /* typeId = DRX3918K_TYPE_ID */
1000 state->m_hasLNA = false;
1001 state->m_hasOOB = false;
1002 state->m_hasATV = true;
1003 state->m_hasAudio = true;
1004 state->m_hasDVBT = true;
1005 state->m_hasDVBC = false;
1006 state->m_hasSAWSW = true;
1007 state->m_hasGPIO2 = true;
1008 state->m_hasGPIO1 = true;
1009 state->m_hasIRQN = false;
1010 break;
1011 case 0x21:
1012 /* typeId = DRX3921K_TYPE_ID */
1013 state->m_hasLNA = false;
1014 state->m_hasOOB = false;
1015 state->m_hasATV = true;
1016 state->m_hasAudio = true;
1017 state->m_hasDVBT = true;
1018 state->m_hasDVBC = true;
1019 state->m_hasSAWSW = true;
1020 state->m_hasGPIO2 = true;
1021 state->m_hasGPIO1 = true;
1022 state->m_hasIRQN = false;
1023 break;
1024 case 0x23:
1025 /* typeId = DRX3923K_TYPE_ID */
1026 state->m_hasLNA = false;
1027 state->m_hasOOB = false;
1028 state->m_hasATV = true;
1029 state->m_hasAudio = true;
1030 state->m_hasDVBT = true;
1031 state->m_hasDVBC = true;
1032 state->m_hasSAWSW = true;
1033 state->m_hasGPIO2 = true;
1034 state->m_hasGPIO1 = true;
1035 state->m_hasIRQN = false;
1036 break;
1037 case 0x25:
1038 /* typeId = DRX3925K_TYPE_ID */
1039 state->m_hasLNA = false;
1040 state->m_hasOOB = false;
1041 state->m_hasATV = true;
1042 state->m_hasAudio = true;
1043 state->m_hasDVBT = true;
1044 state->m_hasDVBC = true;
1045 state->m_hasSAWSW = true;
1046 state->m_hasGPIO2 = true;
1047 state->m_hasGPIO1 = true;
1048 state->m_hasIRQN = false;
1049 break;
1050 case 0x26:
1051 /* typeId = DRX3926K_TYPE_ID */
1052 state->m_hasLNA = false;
1053 state->m_hasOOB = false;
1054 state->m_hasATV = true;
1055 state->m_hasAudio = false;
1056 state->m_hasDVBT = true;
1057 state->m_hasDVBC = true;
1058 state->m_hasSAWSW = true;
1059 state->m_hasGPIO2 = true;
1060 state->m_hasGPIO1 = true;
1061 state->m_hasIRQN = false;
1062 break;
1063 default:
Mauro Carvalho Chehabf07a0bc2011-07-21 22:30:27 -03001064 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001065 ((sioTopJtagidLo >> 12) & 0xFF));
1066 status = -EINVAL;
1067 goto error2;
1068 }
1069
Mauro Carvalho Chehab9c6e1822011-07-10 08:38:18 -03001070 printk(KERN_INFO
1071 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1072 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1073 state->m_oscClockFreq / 1000,
1074 state->m_oscClockFreq % 1000);
1075
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001076error:
1077 if (status < 0)
1078 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1079
1080error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001081 return status;
1082}
1083
1084static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1085{
1086 int status;
1087 bool powerdown_cmd;
1088
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001089 dprintk(1, "\n");
1090
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001091 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001092 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001093 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001094 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001095 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1096 msleep(1);
1097
1098 powerdown_cmd =
Oliver Endrissebc7de22011-07-03 13:49:44 -03001099 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1100 ((state->m_HICfgCtrl) &
1101 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1102 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001103 if (powerdown_cmd == false) {
1104 /* Wait until command rdy */
1105 u32 retryCount = 0;
1106 u16 waitCmd;
1107
1108 do {
1109 msleep(1);
1110 retryCount += 1;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001111 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1112 &waitCmd);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001113 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1114 && (waitCmd != 0));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001115 if (status < 0)
1116 goto error;
1117 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001118 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001119error:
1120 if (status < 0)
1121 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1122
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001123 return status;
1124}
1125
1126static int HI_CfgCommand(struct drxk_state *state)
1127{
1128 int status;
1129
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001130 dprintk(1, "\n");
1131
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001132 mutex_lock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001133
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001134 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1135 if (status < 0)
1136 goto error;
1137 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1138 if (status < 0)
1139 goto error;
1140 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1141 if (status < 0)
1142 goto error;
1143 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1144 if (status < 0)
1145 goto error;
1146 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1147 if (status < 0)
1148 goto error;
1149 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1150 if (status < 0)
1151 goto error;
1152 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1153 if (status < 0)
1154 goto error;
1155
1156 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1157error:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001158 mutex_unlock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001159 if (status < 0)
1160 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001161 return status;
1162}
1163
1164static int InitHI(struct drxk_state *state)
1165{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001166 dprintk(1, "\n");
1167
Oliver Endrissebc7de22011-07-03 13:49:44 -03001168 state->m_HICfgWakeUpKey = (state->demod_address << 1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001169 state->m_HICfgTimeout = 0x96FF;
1170 /* port/bridge/power down ctrl */
1171 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001172
Oliver Endrissebc7de22011-07-03 13:49:44 -03001173 return HI_CfgCommand(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001174}
1175
1176static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1177{
1178 int status = -1;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001179 u16 sioPdrMclkCfg = 0;
1180 u16 sioPdrMdxCfg = 0;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001181 u16 err_cfg = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001182
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03001183 dprintk(1, ": mpeg %s, %s mode\n",
1184 mpegEnable ? "enable" : "disable",
1185 state->m_enableParallel ? "parallel" : "serial");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001186
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001187 /* stop lock indicator process */
1188 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1189 if (status < 0)
1190 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001191
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001192 /* MPEG TS pad configuration */
1193 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1194 if (status < 0)
1195 goto error;
1196
1197 if (mpegEnable == false) {
1198 /* Set MPEG TS pads to inputmode */
1199 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1200 if (status < 0)
1201 goto error;
1202 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1203 if (status < 0)
1204 goto error;
1205 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1206 if (status < 0)
1207 goto error;
1208 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1209 if (status < 0)
1210 goto error;
1211 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1212 if (status < 0)
1213 goto error;
1214 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1215 if (status < 0)
1216 goto error;
1217 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1218 if (status < 0)
1219 goto error;
1220 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1221 if (status < 0)
1222 goto error;
1223 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1224 if (status < 0)
1225 goto error;
1226 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1227 if (status < 0)
1228 goto error;
1229 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1230 if (status < 0)
1231 goto error;
1232 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1233 if (status < 0)
1234 goto error;
1235 } else {
1236 /* Enable MPEG output */
1237 sioPdrMdxCfg =
1238 ((state->m_TSDataStrength <<
1239 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1240 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1241 SIO_PDR_MCLK_CFG_DRIVE__B) |
1242 0x0003);
1243
1244 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1245 if (status < 0)
1246 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001247
1248 if (state->enable_merr_cfg)
1249 err_cfg = sioPdrMdxCfg;
1250
1251 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001252 if (status < 0)
1253 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001254 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001255 if (status < 0)
1256 goto error;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03001257
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001258 if (state->m_enableParallel == true) {
1259 /* paralel -> enable MD1 to MD7 */
1260 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001261 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001262 goto error;
1263 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001264 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001265 goto error;
1266 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001267 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001268 goto error;
1269 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001270 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001271 goto error;
1272 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001273 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001274 goto error;
1275 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1276 if (status < 0)
1277 goto error;
1278 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1279 if (status < 0)
1280 goto error;
1281 } else {
1282 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1283 SIO_PDR_MD0_CFG_DRIVE__B)
1284 | 0x0003);
1285 /* serial -> disable MD1 to MD7 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001286 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001287 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001288 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001289 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001290 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001291 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001292 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001293 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001294 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001295 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001296 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001297 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001298 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001299 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001300 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001301 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001302 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001303 goto error;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001304 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001305 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001306 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001307 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001308 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001309 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001310 goto error;
1311 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001312 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001313 goto error;
1314 }
1315 /* Enable MB output over MPEG pads and ctl input */
1316 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1317 if (status < 0)
1318 goto error;
1319 /* Write nomagic word to enable pdr reg write */
1320 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1321error:
1322 if (status < 0)
1323 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001324 return status;
1325}
1326
1327static int MPEGTSDisable(struct drxk_state *state)
1328{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001329 dprintk(1, "\n");
1330
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001331 return MPEGTSConfigurePins(state, false);
1332}
1333
1334static int BLChainCmd(struct drxk_state *state,
1335 u16 romOffset, u16 nrOfElements, u32 timeOut)
1336{
1337 u16 blStatus = 0;
1338 int status;
1339 unsigned long end;
1340
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001341 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001342 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001343 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1344 if (status < 0)
1345 goto error;
1346 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1347 if (status < 0)
1348 goto error;
1349 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1350 if (status < 0)
1351 goto error;
1352 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1353 if (status < 0)
1354 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001355
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001356 end = jiffies + msecs_to_jiffies(timeOut);
1357 do {
1358 msleep(1);
1359 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1360 if (status < 0)
1361 goto error;
1362 } while ((blStatus == 0x1) &&
1363 ((time_is_after_jiffies(end))));
1364
1365 if (blStatus == 0x1) {
1366 printk(KERN_ERR "drxk: SIO not ready\n");
1367 status = -EINVAL;
1368 goto error2;
1369 }
1370error:
1371 if (status < 0)
1372 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1373error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001374 mutex_unlock(&state->mutex);
1375 return status;
1376}
1377
1378
1379static int DownloadMicrocode(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001380 const u8 pMCImage[], u32 Length)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001381{
1382 const u8 *pSrc = pMCImage;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001383 u32 Address;
1384 u16 nBlocks;
1385 u16 BlockSize;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001386 u32 offset = 0;
1387 u32 i;
Mauro Carvalho Chehab1bd09dd2011-07-03 18:21:59 -03001388 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001389
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001390 dprintk(1, "\n");
1391
Hans Verkuil5becbc52012-05-14 10:22:58 -03001392 /* down the drain (we don't care about MAGIC_WORD) */
1393#if 0
1394 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001395 Drain = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001396#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001397 pSrc += sizeof(u16);
1398 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001399 nBlocks = (pSrc[0] << 8) | pSrc[1];
Oliver Endrissebc7de22011-07-03 13:49:44 -03001400 pSrc += sizeof(u16);
1401 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001402
1403 for (i = 0; i < nBlocks; i += 1) {
1404 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
Oliver Endrissebc7de22011-07-03 13:49:44 -03001405 (pSrc[2] << 8) | pSrc[3];
1406 pSrc += sizeof(u32);
1407 offset += sizeof(u32);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001408
1409 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
Oliver Endrissebc7de22011-07-03 13:49:44 -03001410 pSrc += sizeof(u16);
1411 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001412
Hans Verkuil5becbc52012-05-14 10:22:58 -03001413#if 0
1414 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001415 Flags = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001416#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001419
Hans Verkuil5becbc52012-05-14 10:22:58 -03001420#if 0
1421 /* For future reference */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001422 BlockCRC = (pSrc[0] << 8) | pSrc[1];
Hans Verkuil5becbc52012-05-14 10:22:58 -03001423#endif
Oliver Endrissebc7de22011-07-03 13:49:44 -03001424 pSrc += sizeof(u16);
1425 offset += sizeof(u16);
Mauro Carvalho Chehabbcd2ebb2011-07-09 18:57:54 -03001426
1427 if (offset + BlockSize > Length) {
1428 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1429 return -EINVAL;
1430 }
1431
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001432 status = write_block(state, Address, BlockSize, pSrc);
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001433 if (status < 0) {
1434 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001435 break;
Mauro Carvalho Chehab39624f72011-07-09 19:23:44 -03001436 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001437 pSrc += BlockSize;
1438 offset += BlockSize;
1439 }
1440 return status;
1441}
1442
1443static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1444{
1445 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001446 u16 data = 0;
1447 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001448 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1449 unsigned long end;
1450
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001451 dprintk(1, "\n");
1452
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001453 if (enable == false) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03001454 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001455 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1456 }
1457
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001458 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1459 if (status >= 0 && data == desiredStatus) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001460 /* tokenring already has correct status */
1461 return status;
1462 }
1463 /* Disable/enable dvbt tokenring bridge */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001464 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001465
Oliver Endrissebc7de22011-07-03 13:49:44 -03001466 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001467 do {
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03001468 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001469 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001470 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001471 msleep(1);
1472 } while (1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001473 if (data != desiredStatus) {
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03001474 printk(KERN_ERR "drxk: SIO not ready\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001475 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001476 }
1477 return status;
1478}
1479
1480static int MPEGTSStop(struct drxk_state *state)
1481{
1482 int status = 0;
1483 u16 fecOcSncMode = 0;
1484 u16 fecOcIprMode = 0;
1485
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001486 dprintk(1, "\n");
1487
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001488 /* Gracefull shutdown (byte boundaries) */
1489 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1490 if (status < 0)
1491 goto error;
1492 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1493 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1494 if (status < 0)
1495 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001496
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001497 /* Suppress MCLK during absence of data */
1498 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1499 if (status < 0)
1500 goto error;
1501 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1502 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1503
1504error:
1505 if (status < 0)
1506 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1507
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001508 return status;
1509}
1510
1511static int scu_command(struct drxk_state *state,
1512 u16 cmd, u8 parameterLen,
Oliver Endrissebc7de22011-07-03 13:49:44 -03001513 u16 *parameter, u8 resultLen, u16 *result)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001514{
1515#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1516#error DRXK register mapping no longer compatible with this routine!
1517#endif
1518 u16 curCmd = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001519 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001520 unsigned long end;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001521 u8 buffer[34];
1522 int cnt = 0, ii;
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001523 const char *p;
1524 char errname[30];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001525
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001526 dprintk(1, "\n");
1527
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001528 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1529 ((resultLen > 0) && (result == NULL)))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001530 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001531
1532 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001533
1534 /* assume that the command register is ready
1535 since it is checked afterwards */
1536 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1537 buffer[cnt++] = (parameter[ii] & 0xFF);
1538 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1539 }
1540 buffer[cnt++] = (cmd & 0xFF);
1541 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1542
1543 write_block(state, SCU_RAM_PARAM_0__A -
1544 (parameterLen - 1), cnt, buffer);
1545 /* Wait until SCU has processed command */
1546 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001547 do {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001548 msleep(1);
1549 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1550 if (status < 0)
1551 goto error;
1552 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1553 if (curCmd != DRX_SCU_READY) {
1554 printk(KERN_ERR "drxk: SCU not ready\n");
1555 status = -EIO;
1556 goto error2;
1557 }
1558 /* read results */
1559 if ((resultLen > 0) && (result != NULL)) {
1560 s16 err;
1561 int ii;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001563 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1564 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001565 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001566 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001567 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001568
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001569 /* Check if an error was reported by SCU */
1570 err = (s16)result[0];
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001571 if (err >= 0)
1572 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001573
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001574 /* check for the known error codes */
1575 switch (err) {
1576 case SCU_RESULT_UNKCMD:
1577 p = "SCU_RESULT_UNKCMD";
1578 break;
1579 case SCU_RESULT_UNKSTD:
1580 p = "SCU_RESULT_UNKSTD";
1581 break;
1582 case SCU_RESULT_SIZE:
1583 p = "SCU_RESULT_SIZE";
1584 break;
1585 case SCU_RESULT_INVPAR:
1586 p = "SCU_RESULT_INVPAR";
1587 break;
1588 default: /* Other negative values are errors */
1589 sprintf(errname, "ERROR: %d\n", err);
1590 p = errname;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001591 }
Mauro Carvalho Chehab75589772011-07-10 13:25:48 -03001592 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1593 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1594 status = -EINVAL;
1595 goto error2;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001596 }
1597
1598error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03001599 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001600 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001601error2:
1602 mutex_unlock(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001603 return status;
1604}
1605
1606static int SetIqmAf(struct drxk_state *state, bool active)
1607{
1608 u16 data = 0;
1609 int status;
1610
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001611 dprintk(1, "\n");
1612
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001613 /* Configure IQM */
1614 status = read16(state, IQM_AF_STDBY__A, &data);
1615 if (status < 0)
1616 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001617
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001618 if (!active) {
1619 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1620 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1621 | IQM_AF_STDBY_STDBY_PD_STANDBY
1622 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1623 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1624 } else {
1625 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1627 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1628 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1629 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1630 );
1631 }
1632 status = write16(state, IQM_AF_STDBY__A, data);
1633
1634error:
1635 if (status < 0)
1636 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001637 return status;
1638}
1639
Oliver Endrissebc7de22011-07-03 13:49:44 -03001640static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001641{
1642 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03001643 u16 sioCcPwdMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001644
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001645 dprintk(1, "\n");
1646
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001647 /* Check arguments */
1648 if (mode == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001649 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001650
1651 switch (*mode) {
1652 case DRX_POWER_UP:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1654 break;
1655 case DRXK_POWER_DOWN_OFDM:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1657 break;
1658 case DRXK_POWER_DOWN_CORE:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1660 break;
1661 case DRXK_POWER_DOWN_PLL:
1662 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1663 break;
1664 case DRX_POWER_DOWN:
1665 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1666 break;
1667 default:
1668 /* Unknow sleep mode */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001669 return -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001670 }
1671
1672 /* If already in requested power mode, do nothing */
1673 if (state->m_currentPowerMode == *mode)
1674 return 0;
1675
1676 /* For next steps make sure to start from DRX_POWER_UP mode */
Oliver Endrissebc7de22011-07-03 13:49:44 -03001677 if (state->m_currentPowerMode != DRX_POWER_UP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001678 status = PowerUpDevice(state);
1679 if (status < 0)
1680 goto error;
1681 status = DVBTEnableOFDMTokenRing(state, true);
1682 if (status < 0)
1683 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001684 }
1685
1686 if (*mode == DRX_POWER_UP) {
1687 /* Restore analog & pin configuartion */
1688 } else {
1689 /* Power down to requested mode */
1690 /* Backup some register settings */
1691 /* Set pins with possible pull-ups connected
1692 to them in input mode */
1693 /* Analog power down */
1694 /* ADC power down */
1695 /* Power down device */
1696 /* stop all comm_exec */
1697 /* Stop and power down previous standard */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001698 switch (state->m_OperationMode) {
1699 case OM_DVBT:
1700 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001701 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001702 goto error;
1703 status = PowerDownDVBT(state, false);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001704 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001705 goto error;
1706 break;
1707 case OM_QAM_ITU_A:
1708 case OM_QAM_ITU_C:
1709 status = MPEGTSStop(state);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001710 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001711 goto error;
1712 status = PowerDownQAM(state);
1713 if (status < 0)
1714 goto error;
1715 break;
1716 default:
1717 break;
1718 }
1719 status = DVBTEnableOFDMTokenRing(state, false);
1720 if (status < 0)
1721 goto error;
1722 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1723 if (status < 0)
1724 goto error;
1725 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1726 if (status < 0)
1727 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001728
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001729 if (*mode != DRXK_POWER_DOWN_OFDM) {
1730 state->m_HICfgCtrl |=
1731 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1732 status = HI_CfgCommand(state);
1733 if (status < 0)
1734 goto error;
1735 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001736 }
1737 state->m_currentPowerMode = *mode;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001738
1739error:
1740 if (status < 0)
1741 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1742
Oliver Endrissebc7de22011-07-03 13:49:44 -03001743 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001744}
1745
1746static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1747{
Oliver Endrissebc7de22011-07-03 13:49:44 -03001748 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001749 u16 cmdResult = 0;
1750 u16 data = 0;
1751 int status;
1752
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001753 dprintk(1, "\n");
1754
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001755 status = read16(state, SCU_COMM_EXEC__A, &data);
1756 if (status < 0)
1757 goto error;
1758 if (data == SCU_COMM_EXEC_ACTIVE) {
1759 /* Send OFDM stop command */
1760 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03001761 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001762 goto error;
1763 /* Send OFDM reset command */
1764 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1765 if (status < 0)
1766 goto error;
1767 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001768
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001769 /* Reset datapath for OFDM, processors first */
1770 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1771 if (status < 0)
1772 goto error;
1773 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1774 if (status < 0)
1775 goto error;
1776 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1777 if (status < 0)
1778 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001779
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001780 /* powerdown AFE */
1781 status = SetIqmAf(state, false);
1782 if (status < 0)
1783 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001784
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001785 /* powerdown to OFDM mode */
1786 if (setPowerMode) {
1787 status = CtrlPowerMode(state, &powerMode);
1788 if (status < 0)
1789 goto error;
1790 }
1791error:
1792 if (status < 0)
1793 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001794 return status;
1795}
1796
Oliver Endrissebc7de22011-07-03 13:49:44 -03001797static int SetOperationMode(struct drxk_state *state,
1798 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001799{
1800 int status = 0;
1801
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001802 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001803 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03001804 Stop and power down previous standard
1805 TODO investigate total power down instead of partial
1806 power down depending on "previous" standard.
1807 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001808
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001809 /* disable HW lock indicator */
1810 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1811 if (status < 0)
1812 goto error;
1813
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001814 /* Device is already at the required mode */
1815 if (state->m_OperationMode == oMode)
1816 return 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001817
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001818 switch (state->m_OperationMode) {
1819 /* OM_NONE was added for start up */
1820 case OM_NONE:
1821 break;
1822 case OM_DVBT:
1823 status = MPEGTSStop(state);
1824 if (status < 0)
1825 goto error;
1826 status = PowerDownDVBT(state, true);
1827 if (status < 0)
1828 goto error;
1829 state->m_OperationMode = OM_NONE;
1830 break;
1831 case OM_QAM_ITU_A: /* fallthrough */
1832 case OM_QAM_ITU_C:
1833 status = MPEGTSStop(state);
1834 if (status < 0)
1835 goto error;
1836 status = PowerDownQAM(state);
1837 if (status < 0)
1838 goto error;
1839 state->m_OperationMode = OM_NONE;
1840 break;
1841 case OM_QAM_ITU_B:
1842 default:
1843 status = -EINVAL;
1844 goto error;
1845 }
1846
1847 /*
1848 Power up new standard
1849 */
1850 switch (oMode) {
1851 case OM_DVBT:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001852 dprintk(1, ": DVB-T\n");
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001853 state->m_OperationMode = oMode;
1854 status = SetDVBTStandard(state, oMode);
1855 if (status < 0)
1856 goto error;
1857 break;
1858 case OM_QAM_ITU_A: /* fallthrough */
1859 case OM_QAM_ITU_C:
Mauro Carvalho Chehab48763e22011-12-09 08:53:36 -02001860 dprintk(1, ": DVB-C Annex %c\n",
1861 (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03001862 state->m_OperationMode = oMode;
1863 status = SetQAMStandard(state, oMode);
1864 if (status < 0)
1865 goto error;
1866 break;
1867 case OM_QAM_ITU_B:
1868 default:
1869 status = -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001870 }
1871error:
1872 if (status < 0)
1873 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1874 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001875}
1876
1877static int Start(struct drxk_state *state, s32 offsetFreq,
1878 s32 IntermediateFrequency)
1879{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001880 int status = -EINVAL;
1881
1882 u16 IFreqkHz;
1883 s32 OffsetkHz = offsetFreq / 1000;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001884
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001885 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001886 if (state->m_DrxkState != DRXK_STOPPED &&
1887 state->m_DrxkState != DRXK_DTV_STARTED)
1888 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001889
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03001890 state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001891
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001892 if (IntermediateFrequency < 0) {
1893 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1894 IntermediateFrequency = -IntermediateFrequency;
1895 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001896
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001897 switch (state->m_OperationMode) {
1898 case OM_QAM_ITU_A:
1899 case OM_QAM_ITU_C:
1900 IFreqkHz = (IntermediateFrequency / 1000);
1901 status = SetQAM(state, IFreqkHz, OffsetkHz);
1902 if (status < 0)
1903 goto error;
1904 state->m_DrxkState = DRXK_DTV_STARTED;
1905 break;
1906 case OM_DVBT:
1907 IFreqkHz = (IntermediateFrequency / 1000);
1908 status = MPEGTSStop(state);
1909 if (status < 0)
1910 goto error;
1911 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1912 if (status < 0)
1913 goto error;
1914 status = DVBTStart(state);
1915 if (status < 0)
1916 goto error;
1917 state->m_DrxkState = DRXK_DTV_STARTED;
1918 break;
1919 default:
1920 break;
1921 }
1922error:
1923 if (status < 0)
1924 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001925 return status;
1926}
1927
1928static int ShutDown(struct drxk_state *state)
1929{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001930 dprintk(1, "\n");
1931
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001932 MPEGTSStop(state);
1933 return 0;
1934}
1935
Oliver Endrissebc7de22011-07-03 13:49:44 -03001936static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1937 u32 Time)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001938{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001939 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001940
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001941 dprintk(1, "\n");
1942
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001943 if (pLockStatus == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001944 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001945
1946 *pLockStatus = NOT_LOCKED;
1947
1948 /* define the SCU command code */
1949 switch (state->m_OperationMode) {
1950 case OM_QAM_ITU_A:
1951 case OM_QAM_ITU_B:
1952 case OM_QAM_ITU_C:
1953 status = GetQAMLockStatus(state, pLockStatus);
1954 break;
1955 case OM_DVBT:
1956 status = GetDVBTLockStatus(state, pLockStatus);
1957 break;
1958 default:
1959 break;
1960 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001961error:
1962 if (status < 0)
1963 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001964 return status;
1965}
1966
1967static int MPEGTSStart(struct drxk_state *state)
1968{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001969 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001970
1971 u16 fecOcSncMode = 0;
1972
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001973 /* Allow OC to sync again */
1974 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1975 if (status < 0)
1976 goto error;
1977 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1978 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1979 if (status < 0)
1980 goto error;
1981 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1982error:
1983 if (status < 0)
1984 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001985 return status;
1986}
1987
1988static int MPEGTSDtoInit(struct drxk_state *state)
1989{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001990 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03001991
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03001992 dprintk(1, "\n");
1993
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03001994 /* Rate integration settings */
1995 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1996 if (status < 0)
1997 goto error;
1998 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1999 if (status < 0)
2000 goto error;
2001 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
2002 if (status < 0)
2003 goto error;
2004 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
2005 if (status < 0)
2006 goto error;
2007 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2011 if (status < 0)
2012 goto error;
2013 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2014 if (status < 0)
2015 goto error;
2016 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2017 if (status < 0)
2018 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002019
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002020 /* Additional configuration */
2021 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2022 if (status < 0)
2023 goto error;
2024 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2025 if (status < 0)
2026 goto error;
2027 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2028error:
2029 if (status < 0)
2030 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2031
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002032 return status;
2033}
2034
Oliver Endrissebc7de22011-07-03 13:49:44 -03002035static int MPEGTSDtoSetup(struct drxk_state *state,
2036 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002037{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002038 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002039
Oliver Endrissebc7de22011-07-03 13:49:44 -03002040 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2041 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2042 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2043 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2044 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2045 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2046 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002047 u16 fecOcTmdMode = 0;
2048 u16 fecOcTmdIntUpdRate = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002049 u32 maxBitRate = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002050 bool staticCLK = false;
2051
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002052 dprintk(1, "\n");
2053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002054 /* Check insertion of the Reed-Solomon parity bytes */
2055 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2056 if (status < 0)
2057 goto error;
2058 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2059 if (status < 0)
2060 goto error;
2061 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2062 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2063 if (state->m_insertRSByte == true) {
2064 /* enable parity symbol forward */
2065 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2066 /* MVAL disable during parity bytes */
2067 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2068 /* TS burst length to 204 */
2069 fecOcDtoBurstLen = 204;
2070 }
2071
2072 /* Check serial or parrallel output */
2073 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2074 if (state->m_enableParallel == false) {
2075 /* MPEG data output is serial -> set ipr_mode[0] */
2076 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2077 }
2078
2079 switch (oMode) {
2080 case OM_DVBT:
2081 maxBitRate = state->m_DVBTBitrate;
2082 fecOcTmdMode = 3;
2083 fecOcRcnCtlRate = 0xC00000;
2084 staticCLK = state->m_DVBTStaticCLK;
2085 break;
2086 case OM_QAM_ITU_A: /* fallthrough */
2087 case OM_QAM_ITU_C:
2088 fecOcTmdMode = 0x0004;
2089 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2090 maxBitRate = state->m_DVBCBitrate;
2091 staticCLK = state->m_DVBCStaticCLK;
2092 break;
2093 default:
2094 status = -EINVAL;
2095 } /* switch (standard) */
2096 if (status < 0)
2097 goto error;
2098
2099 /* Configure DTO's */
2100 if (staticCLK) {
2101 u32 bitRate = 0;
2102
2103 /* Rational DTO for MCLK source (static MCLK rate),
2104 Dynamic DTO for optimal grouping
2105 (avoid intra-packet gaps),
2106 DTO offset enable to sync TS burst with MSTRT */
2107 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2108 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2109 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2110 FEC_OC_FCT_MODE_VIRT_ENA__M);
2111
2112 /* Check user defined bitrate */
2113 bitRate = maxBitRate;
2114 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2115 bitRate = 75900000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002116 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002117 /* Rational DTO period:
2118 dto_period = (Fsys / bitrate) - 2
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002120 Result should be floored,
2121 to make sure >= requested bitrate
2122 */
2123 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2124 * 1000) / bitRate);
2125 if (fecOcDtoPeriod <= 2)
2126 fecOcDtoPeriod = 0;
2127 else
2128 fecOcDtoPeriod -= 2;
2129 fecOcTmdIntUpdRate = 8;
2130 } else {
2131 /* (commonAttr->staticCLK == false) => dynamic mode */
2132 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2133 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2134 fecOcTmdIntUpdRate = 5;
2135 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002136
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002137 /* Write appropriate registers with requested configuration */
2138 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2139 if (status < 0)
2140 goto error;
2141 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2142 if (status < 0)
2143 goto error;
2144 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2148 if (status < 0)
2149 goto error;
2150 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2151 if (status < 0)
2152 goto error;
2153 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2154 if (status < 0)
2155 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002156
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002157 /* Rate integration settings */
2158 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2159 if (status < 0)
2160 goto error;
2161 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2162 if (status < 0)
2163 goto error;
2164 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2165error:
2166 if (status < 0)
2167 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002168 return status;
2169}
2170
2171static int MPEGTSConfigurePolarity(struct drxk_state *state)
2172{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002173 u16 fecOcRegIprInvert = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002174
2175 /* Data mask for the output data byte */
2176 u16 InvertDataMask =
Oliver Endrissebc7de22011-07-03 13:49:44 -03002177 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2178 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2179 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2180 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002182 dprintk(1, "\n");
2183
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002184 /* Control selective inversion of output bits */
2185 fecOcRegIprInvert &= (~(InvertDataMask));
2186 if (state->m_invertDATA == true)
2187 fecOcRegIprInvert |= InvertDataMask;
2188 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2189 if (state->m_invertERR == true)
2190 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2191 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2192 if (state->m_invertSTR == true)
2193 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2194 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2195 if (state->m_invertVAL == true)
2196 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2197 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2198 if (state->m_invertCLK == true)
2199 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002200
2201 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002202}
2203
2204#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2205
2206static int SetAgcRf(struct drxk_state *state,
2207 struct SCfgAgc *pAgcCfg, bool isDTV)
2208{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002209 int status = -EINVAL;
2210 u16 data = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002211 struct SCfgAgc *pIfAgcSettings;
2212
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002213 dprintk(1, "\n");
2214
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002215 if (pAgcCfg == NULL)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002216 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002217
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002218 switch (pAgcCfg->ctrlMode) {
2219 case DRXK_AGC_CTRL_AUTO:
2220 /* Enable RF AGC DAC */
2221 status = read16(state, IQM_AF_STDBY__A, &data);
2222 if (status < 0)
2223 goto error;
2224 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2225 status = write16(state, IQM_AF_STDBY__A, data);
2226 if (status < 0)
2227 goto error;
2228 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2229 if (status < 0)
2230 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002231
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002232 /* Enable SCU RF AGC loop */
2233 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002234
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002235 /* Polarity */
2236 if (state->m_RfAgcPol)
2237 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2238 else
2239 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2240 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2241 if (status < 0)
2242 goto error;
2243
2244 /* Set speed (using complementary reduction value) */
2245 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2246 if (status < 0)
2247 goto error;
2248
2249 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2250 data |= (~(pAgcCfg->speed <<
2251 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2252 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2253
2254 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2255 if (status < 0)
2256 goto error;
2257
2258 if (IsDVBT(state))
2259 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2260 else if (IsQAM(state))
2261 pIfAgcSettings = &state->m_qamIfAgcCfg;
2262 else
2263 pIfAgcSettings = &state->m_atvIfAgcCfg;
2264 if (pIfAgcSettings == NULL) {
2265 status = -EINVAL;
2266 goto error;
2267 }
2268
2269 /* Set TOP, only if IF-AGC is in AUTO mode */
2270 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2271 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002272 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002273 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002274
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002275 /* Cut-Off current */
2276 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2277 if (status < 0)
2278 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002279
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002280 /* Max. output level */
2281 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2282 if (status < 0)
2283 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002284
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002285 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002286
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002287 case DRXK_AGC_CTRL_USER:
2288 /* Enable RF AGC DAC */
2289 status = read16(state, IQM_AF_STDBY__A, &data);
2290 if (status < 0)
2291 goto error;
2292 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2293 status = write16(state, IQM_AF_STDBY__A, data);
2294 if (status < 0)
2295 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002296
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002297 /* Disable SCU RF AGC loop */
2298 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2299 if (status < 0)
2300 goto error;
2301 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2302 if (state->m_RfAgcPol)
2303 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2304 else
2305 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2306 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2307 if (status < 0)
2308 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002309
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002310 /* SCU c.o.c. to 0, enabling full control range */
2311 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2312 if (status < 0)
2313 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002314
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002315 /* Write value to output pin */
2316 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2317 if (status < 0)
2318 goto error;
2319 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002320
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002321 case DRXK_AGC_CTRL_OFF:
2322 /* Disable RF AGC DAC */
2323 status = read16(state, IQM_AF_STDBY__A, &data);
2324 if (status < 0)
2325 goto error;
2326 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2327 status = write16(state, IQM_AF_STDBY__A, data);
2328 if (status < 0)
2329 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002330
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002331 /* Disable SCU RF AGC loop */
2332 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2333 if (status < 0)
2334 goto error;
2335 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2336 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2337 if (status < 0)
2338 goto error;
2339 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002340
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002341 default:
2342 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002343
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002344 }
2345error:
2346 if (status < 0)
2347 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002348 return status;
2349}
2350
2351#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2352
Oliver Endrissebc7de22011-07-03 13:49:44 -03002353static int SetAgcIf(struct drxk_state *state,
2354 struct SCfgAgc *pAgcCfg, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002355{
2356 u16 data = 0;
2357 int status = 0;
2358 struct SCfgAgc *pRfAgcSettings;
2359
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002360 dprintk(1, "\n");
2361
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002362 switch (pAgcCfg->ctrlMode) {
2363 case DRXK_AGC_CTRL_AUTO:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002364
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002365 /* Enable IF AGC DAC */
2366 status = read16(state, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002367 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002368 goto error;
2369 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2370 status = write16(state, IQM_AF_STDBY__A, data);
2371 if (status < 0)
2372 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002373
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002374 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2375 if (status < 0)
2376 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002377
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002378 /* Enable SCU IF AGC loop */
2379 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2380
2381 /* Polarity */
2382 if (state->m_IfAgcPol)
2383 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2384 else
2385 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2386 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2387 if (status < 0)
2388 goto error;
2389
2390 /* Set speed (using complementary reduction value) */
2391 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2392 if (status < 0)
2393 goto error;
2394 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2395 data |= (~(pAgcCfg->speed <<
2396 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2397 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2398
2399 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2400 if (status < 0)
2401 goto error;
2402
2403 if (IsQAM(state))
2404 pRfAgcSettings = &state->m_qamRfAgcCfg;
2405 else
2406 pRfAgcSettings = &state->m_atvRfAgcCfg;
2407 if (pRfAgcSettings == NULL)
2408 return -1;
2409 /* Restore TOP */
2410 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2411 if (status < 0)
2412 goto error;
2413 break;
2414
2415 case DRXK_AGC_CTRL_USER:
2416
2417 /* Enable IF AGC DAC */
2418 status = read16(state, IQM_AF_STDBY__A, &data);
2419 if (status < 0)
2420 goto error;
2421 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2422 status = write16(state, IQM_AF_STDBY__A, data);
2423 if (status < 0)
2424 goto error;
2425
2426 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2427 if (status < 0)
2428 goto error;
2429
2430 /* Disable SCU IF AGC loop */
2431 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2432
2433 /* Polarity */
2434 if (state->m_IfAgcPol)
2435 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2436 else
2437 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2438 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2439 if (status < 0)
2440 goto error;
2441
2442 /* Write value to output pin */
2443 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2444 if (status < 0)
2445 goto error;
2446 break;
2447
2448 case DRXK_AGC_CTRL_OFF:
2449
2450 /* Disable If AGC DAC */
2451 status = read16(state, IQM_AF_STDBY__A, &data);
2452 if (status < 0)
2453 goto error;
2454 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2455 status = write16(state, IQM_AF_STDBY__A, data);
2456 if (status < 0)
2457 goto error;
2458
2459 /* Disable SCU IF AGC loop */
2460 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2461 if (status < 0)
2462 goto error;
2463 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2464 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2465 if (status < 0)
2466 goto error;
2467 break;
2468 } /* switch (agcSettingsIf->ctrlMode) */
2469
2470 /* always set the top to support
2471 configurations without if-loop */
2472 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2473error:
2474 if (status < 0)
2475 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002476 return status;
2477}
2478
2479static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2480{
2481 u16 agcDacLvl;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002482 int status;
2483 u16 Level = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002484
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002485 dprintk(1, "\n");
2486
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002487 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2488 if (status < 0) {
2489 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2490 return status;
2491 }
2492
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002493 *pValue = 0;
2494
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002495 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2496 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2497 if (Level < 14000)
2498 *pValue = (14000 - Level) / 4;
2499 else
2500 *pValue = 0;
2501
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002502 return status;
2503}
2504
Oliver Endrissebc7de22011-07-03 13:49:44 -03002505static int GetQAMSignalToNoise(struct drxk_state *state,
2506 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002507{
2508 int status = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002509 u16 qamSlErrPower = 0; /* accum. error between
2510 raw and sliced symbols */
2511 u32 qamSlSigPower = 0; /* used for MER, depends of
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002512 QAM modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002513 u32 qamSlMer = 0; /* QAM MER */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002514
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002515 dprintk(1, "\n");
2516
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002517 /* MER calculation */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002518
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002519 /* get the register value needed for MER */
2520 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2521 if (status < 0) {
2522 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2523 return -EINVAL;
2524 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002525
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002526 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002527 case QAM_16:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2529 break;
2530 case QAM_32:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2532 break;
2533 case QAM_64:
2534 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2535 break;
2536 case QAM_128:
2537 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2538 break;
2539 default:
2540 case QAM_256:
2541 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2542 break;
2543 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002544
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002545 if (qamSlErrPower > 0) {
2546 qamSlMer = Log10Times100(qamSlSigPower) -
2547 Log10Times100((u32) qamSlErrPower);
2548 }
2549 *pSignalToNoise = qamSlMer;
2550
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002551 return status;
2552}
2553
Oliver Endrissebc7de22011-07-03 13:49:44 -03002554static int GetDVBTSignalToNoise(struct drxk_state *state,
2555 s32 *pSignalToNoise)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002556{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002557 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002558 u16 regData = 0;
2559 u32 EqRegTdSqrErrI = 0;
2560 u32 EqRegTdSqrErrQ = 0;
2561 u16 EqRegTdSqrErrExp = 0;
2562 u16 EqRegTdTpsPwrOfs = 0;
2563 u16 EqRegTdReqSmbCnt = 0;
2564 u32 tpsCnt = 0;
2565 u32 SqrErrIQ = 0;
2566 u32 a = 0;
2567 u32 b = 0;
2568 u32 c = 0;
2569 u32 iMER = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002570 u16 transmissionParams = 0;
2571
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002572 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002573
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002574 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2575 if (status < 0)
2576 goto error;
2577 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2578 if (status < 0)
2579 goto error;
2580 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2581 if (status < 0)
2582 goto error;
2583 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2584 if (status < 0)
2585 goto error;
2586 /* Extend SQR_ERR_I operational range */
2587 EqRegTdSqrErrI = (u32) regData;
2588 if ((EqRegTdSqrErrExp > 11) &&
2589 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2590 EqRegTdSqrErrI += 0x00010000UL;
2591 }
2592 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2593 if (status < 0)
2594 goto error;
2595 /* Extend SQR_ERR_Q operational range */
2596 EqRegTdSqrErrQ = (u32) regData;
2597 if ((EqRegTdSqrErrExp > 11) &&
2598 (EqRegTdSqrErrQ < 0x00000FFFUL))
2599 EqRegTdSqrErrQ += 0x00010000UL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002600
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002601 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2602 if (status < 0)
2603 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002604
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002605 /* Check input data for MER */
2606
2607 /* MER calculation (in 0.1 dB) without math.h */
2608 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2609 iMER = 0;
2610 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2611 /* No error at all, this must be the HW reset value
2612 * Apparently no first measurement yet
2613 * Set MER to 0.0 */
2614 iMER = 0;
2615 } else {
2616 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2617 EqRegTdSqrErrExp;
2618 if ((transmissionParams &
2619 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2620 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2621 tpsCnt = 17;
2622 else
2623 tpsCnt = 68;
2624
2625 /* IMER = 100 * log10 (x)
2626 where x = (EqRegTdTpsPwrOfs^2 *
2627 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2628
2629 => IMER = a + b -c
2630 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2631 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2632 c = 100 * log10 (SqrErrIQ)
2633 */
2634
2635 /* log(x) x = 9bits * 9bits->18 bits */
2636 a = Log10Times100(EqRegTdTpsPwrOfs *
2637 EqRegTdTpsPwrOfs);
2638 /* log(x) x = 16bits * 7bits->23 bits */
2639 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2640 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2641 c = Log10Times100(SqrErrIQ);
2642
2643 iMER = a + b;
2644 /* No negative MER, clip to zero */
2645 if (iMER > c)
2646 iMER -= c;
2647 else
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002648 iMER = 0;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002649 }
2650 *pSignalToNoise = iMER;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002651
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002652error:
2653 if (status < 0)
2654 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002655 return status;
2656}
2657
2658static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2659{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002660 dprintk(1, "\n");
2661
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002662 *pSignalToNoise = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002663 switch (state->m_OperationMode) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002664 case OM_DVBT:
2665 return GetDVBTSignalToNoise(state, pSignalToNoise);
2666 case OM_QAM_ITU_A:
2667 case OM_QAM_ITU_C:
2668 return GetQAMSignalToNoise(state, pSignalToNoise);
2669 default:
2670 break;
2671 }
2672 return 0;
2673}
2674
2675#if 0
2676static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2677{
2678 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2679 int status = 0;
2680
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002681 dprintk(1, "\n");
2682
Oliver Endrissebc7de22011-07-03 13:49:44 -03002683 static s32 QE_SN[] = {
2684 51, /* QPSK 1/2 */
2685 69, /* QPSK 2/3 */
2686 79, /* QPSK 3/4 */
2687 89, /* QPSK 5/6 */
2688 97, /* QPSK 7/8 */
2689 108, /* 16-QAM 1/2 */
2690 131, /* 16-QAM 2/3 */
2691 146, /* 16-QAM 3/4 */
2692 156, /* 16-QAM 5/6 */
2693 160, /* 16-QAM 7/8 */
2694 165, /* 64-QAM 1/2 */
2695 187, /* 64-QAM 2/3 */
2696 202, /* 64-QAM 3/4 */
2697 216, /* 64-QAM 5/6 */
2698 225, /* 64-QAM 7/8 */
2699 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002700
2701 *pQuality = 0;
2702
2703 do {
2704 s32 SignalToNoise = 0;
2705 u16 Constellation = 0;
2706 u16 CodeRate = 0;
2707 u32 SignalToNoiseRel;
2708 u32 BERQuality;
2709
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002710 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2711 if (status < 0)
2712 break;
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002713 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002714 if (status < 0)
2715 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002716 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2717
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002718 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002719 if (status < 0)
2720 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002721 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2722
2723 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2724 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2725 break;
2726 SignalToNoiseRel = SignalToNoise -
Oliver Endrissebc7de22011-07-03 13:49:44 -03002727 QE_SN[Constellation * 5 + CodeRate];
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002728 BERQuality = 100;
2729
Oliver Endrissebc7de22011-07-03 13:49:44 -03002730 if (SignalToNoiseRel < -70)
2731 *pQuality = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002732 else if (SignalToNoiseRel < 30)
2733 *pQuality = ((SignalToNoiseRel + 70) *
2734 BERQuality) / 100;
2735 else
2736 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002737 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002738 return 0;
2739};
2740
Oliver Endrissebc7de22011-07-03 13:49:44 -03002741static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002742{
2743 int status = 0;
2744 *pQuality = 0;
2745
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002746 dprintk(1, "\n");
2747
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002748 do {
2749 u32 SignalToNoise = 0;
2750 u32 BERQuality = 100;
2751 u32 SignalToNoiseRel = 0;
2752
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002753 status = GetQAMSignalToNoise(state, &SignalToNoise);
2754 if (status < 0)
2755 break;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002756
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03002757 switch (state->props.modulation) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002758 case QAM_16:
2759 SignalToNoiseRel = SignalToNoise - 200;
2760 break;
2761 case QAM_32:
2762 SignalToNoiseRel = SignalToNoise - 230;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002763 break; /* Not in NorDig */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002764 case QAM_64:
2765 SignalToNoiseRel = SignalToNoise - 260;
2766 break;
2767 case QAM_128:
2768 SignalToNoiseRel = SignalToNoise - 290;
2769 break;
2770 default:
2771 case QAM_256:
2772 SignalToNoiseRel = SignalToNoise - 320;
2773 break;
2774 }
2775
2776 if (SignalToNoiseRel < -70)
2777 *pQuality = 0;
2778 else if (SignalToNoiseRel < 30)
2779 *pQuality = ((SignalToNoiseRel + 70) *
2780 BERQuality) / 100;
2781 else
2782 *pQuality = BERQuality;
Oliver Endrissebc7de22011-07-03 13:49:44 -03002783 } while (0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002784
2785 return status;
2786}
2787
2788static int GetQuality(struct drxk_state *state, s32 *pQuality)
2789{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002790 dprintk(1, "\n");
2791
Oliver Endrissebc7de22011-07-03 13:49:44 -03002792 switch (state->m_OperationMode) {
2793 case OM_DVBT:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002794 return GetDVBTQuality(state, pQuality);
Oliver Endrissebc7de22011-07-03 13:49:44 -03002795 case OM_QAM_ITU_A:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002796 return GetDVBCQuality(state, pQuality);
2797 default:
2798 break;
2799 }
2800
2801 return 0;
2802}
2803#endif
2804
2805/* Free data ram in SIO HI */
2806#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2807#define SIO_HI_RA_RAM_USR_END__A 0x420060
2808
2809#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2810#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2811#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2812#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2813
2814#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2815#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2816#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2817
2818static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2819{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002820 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002821
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002822 dprintk(1, "\n");
2823
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002824 if (state->m_DrxkState == DRXK_UNINITIALIZED)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002825 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002826 if (state->m_DrxkState == DRXK_POWERED_DOWN)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002827 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002828
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03002829 if (state->no_i2c_bridge)
2830 return 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002831
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002832 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2833 if (status < 0)
2834 goto error;
2835 if (bEnableBridge) {
2836 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 -03002837 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002838 goto error;
2839 } else {
2840 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2841 if (status < 0)
2842 goto error;
2843 }
2844
2845 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2846
2847error:
2848 if (status < 0)
2849 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002850 return status;
2851}
2852
Oliver Endrissebc7de22011-07-03 13:49:44 -03002853static int SetPreSaw(struct drxk_state *state,
2854 struct SCfgPreSaw *pPreSawCfg)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002855{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002856 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002857
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002858 dprintk(1, "\n");
2859
Oliver Endrissebc7de22011-07-03 13:49:44 -03002860 if ((pPreSawCfg == NULL)
2861 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002862 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002863
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03002864 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002865error:
2866 if (status < 0)
2867 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002868 return status;
2869}
2870
2871static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
Oliver Endrissebc7de22011-07-03 13:49:44 -03002872 u16 romOffset, u16 nrOfElements, u32 timeOut)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002873{
Oliver Endrissebc7de22011-07-03 13:49:44 -03002874 u16 blStatus = 0;
2875 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2876 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2877 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002878 unsigned long end;
2879
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002880 dprintk(1, "\n");
2881
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002882 mutex_lock(&state->mutex);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002883 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2884 if (status < 0)
2885 goto error;
2886 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2887 if (status < 0)
2888 goto error;
2889 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2890 if (status < 0)
2891 goto error;
2892 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2893 if (status < 0)
2894 goto error;
2895 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2896 if (status < 0)
2897 goto error;
2898 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2899 if (status < 0)
2900 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002901
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002902 end = jiffies + msecs_to_jiffies(timeOut);
2903 do {
2904 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2905 if (status < 0)
2906 goto error;
2907 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2908 if (blStatus == 0x1) {
2909 printk(KERN_ERR "drxk: SIO not ready\n");
2910 status = -EINVAL;
2911 goto error2;
2912 }
2913error:
2914 if (status < 0)
2915 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2916error2:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002917 mutex_unlock(&state->mutex);
2918 return status;
2919
2920}
2921
Oliver Endrissebc7de22011-07-03 13:49:44 -03002922static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002923{
2924 u16 data = 0;
2925 int status;
2926
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002927 dprintk(1, "\n");
2928
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002929 /* Start measurement */
2930 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2931 if (status < 0)
2932 goto error;
2933 status = write16(state, IQM_AF_START_LOCK__A, 1);
2934 if (status < 0)
2935 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002936
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002937 *count = 0;
2938 status = read16(state, IQM_AF_PHASE0__A, &data);
2939 if (status < 0)
2940 goto error;
2941 if (data == 127)
2942 *count = *count + 1;
2943 status = read16(state, IQM_AF_PHASE1__A, &data);
2944 if (status < 0)
2945 goto error;
2946 if (data == 127)
2947 *count = *count + 1;
2948 status = read16(state, IQM_AF_PHASE2__A, &data);
2949 if (status < 0)
2950 goto error;
2951 if (data == 127)
2952 *count = *count + 1;
2953
2954error:
2955 if (status < 0)
2956 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002957 return status;
2958}
2959
2960static int ADCSynchronization(struct drxk_state *state)
2961{
2962 u16 count = 0;
2963 int status;
2964
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03002965 dprintk(1, "\n");
2966
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002967 status = ADCSyncMeasurement(state, &count);
2968 if (status < 0)
2969 goto error;
2970
2971 if (count == 1) {
2972 /* Try sampling on a diffrent edge */
2973 u16 clkNeg = 0;
2974
2975 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2976 if (status < 0)
2977 goto error;
2978 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2979 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2980 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2981 clkNeg |=
2982 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2983 } else {
2984 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2985 clkNeg |=
2986 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2987 }
2988 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2989 if (status < 0)
2990 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03002991 status = ADCSyncMeasurement(state, &count);
2992 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002993 goto error;
2994 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03002995
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03002996 if (count < 2)
2997 status = -EINVAL;
2998error:
2999 if (status < 0)
3000 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003001 return status;
3002}
3003
3004static int SetFrequencyShifter(struct drxk_state *state,
3005 u16 intermediateFreqkHz,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003006 s32 tunerFreqOffset, bool isDTV)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003007{
3008 bool selectPosImage = false;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003009 u32 rfFreqResidual = tunerFreqOffset;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003010 u32 fmFrequencyShift = 0;
3011 bool tunerMirror = !state->m_bMirrorFreqSpect;
3012 u32 adcFreq;
3013 bool adcFlip;
3014 int status;
3015 u32 ifFreqActual;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003016 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003017 u32 frequencyShift;
3018 bool imageToSelect;
3019
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003020 dprintk(1, "\n");
3021
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003022 /*
Oliver Endrissebc7de22011-07-03 13:49:44 -03003023 Program frequency shifter
3024 No need to account for mirroring on RF
3025 */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003026 if (isDTV) {
3027 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3028 (state->m_OperationMode == OM_QAM_ITU_C) ||
3029 (state->m_OperationMode == OM_DVBT))
Oliver Endrissebc7de22011-07-03 13:49:44 -03003030 selectPosImage = true;
3031 else
3032 selectPosImage = false;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003033 }
3034 if (tunerMirror)
3035 /* tuner doesn't mirror */
3036 ifFreqActual = intermediateFreqkHz +
Oliver Endrissebc7de22011-07-03 13:49:44 -03003037 rfFreqResidual + fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003038 else
3039 /* tuner mirrors */
3040 ifFreqActual = intermediateFreqkHz -
Oliver Endrissebc7de22011-07-03 13:49:44 -03003041 rfFreqResidual - fmFrequencyShift;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003042 if (ifFreqActual > samplingFrequency / 2) {
3043 /* adc mirrors */
3044 adcFreq = samplingFrequency - ifFreqActual;
3045 adcFlip = true;
3046 } else {
3047 /* adc doesn't mirror */
3048 adcFreq = ifFreqActual;
3049 adcFlip = false;
3050 }
3051
3052 frequencyShift = adcFreq;
3053 imageToSelect = state->m_rfmirror ^ tunerMirror ^
Oliver Endrissebc7de22011-07-03 13:49:44 -03003054 adcFlip ^ selectPosImage;
3055 state->m_IqmFsRateOfs =
3056 Frac28a((frequencyShift), samplingFrequency);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003057
3058 if (imageToSelect)
3059 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3060
3061 /* Program frequency shifter with tuner offset compensation */
3062 /* frequencyShift += tunerFreqOffset; TODO */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003063 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3064 state->m_IqmFsRateOfs);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003065 if (status < 0)
3066 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003067 return status;
3068}
3069
3070static int InitAGC(struct drxk_state *state, bool isDTV)
3071{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003072 u16 ingainTgt = 0;
3073 u16 ingainTgtMin = 0;
3074 u16 ingainTgtMax = 0;
3075 u16 clpCyclen = 0;
3076 u16 clpSumMin = 0;
3077 u16 clpDirTo = 0;
3078 u16 snsSumMin = 0;
3079 u16 snsSumMax = 0;
3080 u16 clpSumMax = 0;
3081 u16 snsDirTo = 0;
3082 u16 kiInnergainMin = 0;
3083 u16 ifIaccuHiTgt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003084 u16 ifIaccuHiTgtMin = 0;
3085 u16 ifIaccuHiTgtMax = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003086 u16 data = 0;
3087 u16 fastClpCtrlDelay = 0;
3088 u16 clpCtrlMode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003089 int status = 0;
3090
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003091 dprintk(1, "\n");
3092
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003093 /* Common settings */
3094 snsSumMax = 1023;
3095 ifIaccuHiTgtMin = 2047;
3096 clpCyclen = 500;
3097 clpSumMax = 1023;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003098
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003099 /* AGCInit() not available for DVBT; init done in microcode */
3100 if (!IsQAM(state)) {
3101 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3102 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003103 }
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003104
3105 /* FIXME: Analog TV AGC require different settings */
3106
3107 /* Standard specific settings */
3108 clpSumMin = 8;
3109 clpDirTo = (u16) -9;
3110 clpCtrlMode = 0;
3111 snsSumMin = 8;
3112 snsDirTo = (u16) -9;
3113 kiInnergainMin = (u16) -1030;
3114 ifIaccuHiTgtMax = 0x2380;
3115 ifIaccuHiTgt = 0x2380;
3116 ingainTgtMin = 0x0511;
3117 ingainTgt = 0x0511;
3118 ingainTgtMax = 5119;
3119 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003121 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3122 if (status < 0)
3123 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003124
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003125 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3153 if (status < 0)
3154 goto error;
3155 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3156 if (status < 0)
3157 goto error;
3158 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3159 if (status < 0)
3160 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003161
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003162 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3163 if (status < 0)
3164 goto error;
3165 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3166 if (status < 0)
3167 goto error;
3168 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3169 if (status < 0)
3170 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003171
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003172 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3173 if (status < 0)
3174 goto error;
3175 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3176 if (status < 0)
3177 goto error;
3178 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3179 if (status < 0)
3180 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003181
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003182 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3231 if (status < 0)
3232 goto error;
3233 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3234 if (status < 0)
3235 goto error;
3236 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3237 if (status < 0)
3238 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003239
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003240 /* Initialize inner-loop KI gain factors */
3241 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3242 if (status < 0)
3243 goto error;
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03003244
3245 data = 0x0657;
3246 data &= ~SCU_RAM_AGC_KI_RF__M;
3247 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3248 data &= ~SCU_RAM_AGC_KI_IF__M;
3249 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3250
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003251 status = write16(state, SCU_RAM_AGC_KI__A, data);
3252error:
3253 if (status < 0)
3254 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003255 return status;
3256}
3257
Oliver Endrissebc7de22011-07-03 13:49:44 -03003258static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003259{
3260 int status;
3261
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003262 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003263 if (packetErr == NULL)
3264 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3265 else
3266 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3267 if (status < 0)
3268 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003269 return status;
3270}
3271
3272static int DVBTScCommand(struct drxk_state *state,
3273 u16 cmd, u16 subcmd,
3274 u16 param0, u16 param1, u16 param2,
3275 u16 param3, u16 param4)
3276{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003277 u16 curCmd = 0;
3278 u16 errCode = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003279 u16 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003280 u16 scExec = 0;
3281 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003282
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003283 dprintk(1, "\n");
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003284 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003285 if (scExec != 1) {
3286 /* SC is not running */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003287 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003288 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003289 if (status < 0)
3290 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003291
3292 /* Wait until sc is ready to receive command */
Oliver Endrissebc7de22011-07-03 13:49:44 -03003293 retryCnt = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003294 do {
3295 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003296 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003297 retryCnt++;
3298 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003299 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3300 goto error;
3301
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003302 /* Write sub-command */
3303 switch (cmd) {
3304 /* All commands using sub-cmd */
3305 case OFDM_SC_RA_RAM_CMD_PROC_START:
3306 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3307 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003308 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3309 if (status < 0)
3310 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003311 break;
3312 default:
3313 /* Do nothing */
3314 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003315 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003316
3317 /* Write needed parameters and the command */
3318 switch (cmd) {
3319 /* All commands using 5 parameters */
3320 /* All commands using 4 parameters */
3321 /* All commands using 3 parameters */
3322 /* All commands using 2 parameters */
3323 case OFDM_SC_RA_RAM_CMD_PROC_START:
3324 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3325 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003326 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003327 /* All commands using 1 parameters */
3328 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3329 case OFDM_SC_RA_RAM_CMD_USER_IO:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003330 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003331 /* All commands using 0 parameters */
3332 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3333 case OFDM_SC_RA_RAM_CMD_NULL:
3334 /* Write command */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003335 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003336 break;
3337 default:
3338 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003339 status = -EINVAL;
3340 }
3341 if (status < 0)
3342 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003343
3344 /* Wait until sc is ready processing command */
3345 retryCnt = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003346 do {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003347 msleep(1);
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003348 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003349 retryCnt++;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003350 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003351 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3352 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003353
3354 /* Check for illegal cmd */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003355 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003356 if (errCode == 0xFFFF) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003357 /* illegal command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003358 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003359 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003360 if (status < 0)
3361 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003362
3363 /* Retreive results parameters from SC */
3364 switch (cmd) {
3365 /* All commands yielding 5 results */
3366 /* All commands yielding 4 results */
3367 /* All commands yielding 3 results */
3368 /* All commands yielding 2 results */
3369 /* All commands yielding 1 result */
3370 case OFDM_SC_RA_RAM_CMD_USER_IO:
3371 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003372 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003373 /* All commands yielding 0 results */
3374 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3375 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3376 case OFDM_SC_RA_RAM_CMD_PROC_START:
3377 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3378 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3379 case OFDM_SC_RA_RAM_CMD_NULL:
3380 break;
3381 default:
3382 /* Unknown command */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003383 status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003384 break;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003385 } /* switch (cmd->cmd) */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003386error:
3387 if (status < 0)
3388 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003389 return status;
3390}
3391
Oliver Endrissebc7de22011-07-03 13:49:44 -03003392static int PowerUpDVBT(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003393{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003394 enum DRXPowerMode powerMode = DRX_POWER_UP;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003395 int status;
3396
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003397 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003398 status = CtrlPowerMode(state, &powerMode);
3399 if (status < 0)
3400 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003401 return status;
3402}
3403
Oliver Endrissebc7de22011-07-03 13:49:44 -03003404static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003405{
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003406 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03003407
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003408 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003409 if (*enabled == true)
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003410 status = write16(state, IQM_CF_BYPASSDET__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003411 else
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003412 status = write16(state, IQM_CF_BYPASSDET__A, 1);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003413 if (status < 0)
3414 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003415 return status;
3416}
3417
3418#define DEFAULT_FR_THRES_8K 4000
3419static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3420{
3421
3422 int status;
3423
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003424 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003425 if (*enabled == true) {
3426 /* write mask to 1 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003427 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003428 DEFAULT_FR_THRES_8K);
3429 } else {
3430 /* write mask to 0 */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003431 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003432 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003433 if (status < 0)
3434 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003435
3436 return status;
3437}
3438
3439static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3440 struct DRXKCfgDvbtEchoThres_t *echoThres)
3441{
3442 u16 data = 0;
3443 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003444
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003445 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003446 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3447 if (status < 0)
3448 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003449
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003450 switch (echoThres->fftMode) {
3451 case DRX_FFTMODE_2K:
3452 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3453 data |= ((echoThres->threshold <<
3454 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3455 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003456 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003457 case DRX_FFTMODE_8K:
3458 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3459 data |= ((echoThres->threshold <<
3460 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3461 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003462 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003463 default:
3464 return -EINVAL;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003465 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003466
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003467 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3468error:
3469 if (status < 0)
3470 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003471 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003472}
3473
3474static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003475 enum DRXKCfgDvbtSqiSpeed *speed)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003476{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003477 int status = -EINVAL;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003478
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003479 dprintk(1, "\n");
3480
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003481 switch (*speed) {
3482 case DRXK_DVBT_SQI_SPEED_FAST:
3483 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3484 case DRXK_DVBT_SQI_SPEED_SLOW:
3485 break;
3486 default:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003487 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003488 }
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03003489 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
Oliver Endrissebc7de22011-07-03 13:49:44 -03003490 (u16) *speed);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003491error:
3492 if (status < 0)
3493 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003494 return status;
3495}
3496
3497/*============================================================================*/
3498
3499/**
3500* \brief Activate DVBT specific presets
3501* \param demod instance of demodulator.
3502* \return DRXStatus_t.
3503*
3504* Called in DVBTSetStandard
3505*
3506*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003507static int DVBTActivatePresets(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003508{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003509 int status;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003510 bool setincenable = false;
3511 bool setfrenable = true;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003512
Oliver Endrissebc7de22011-07-03 13:49:44 -03003513 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3514 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003515
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003516 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003517 status = DVBTCtrlSetIncEnable(state, &setincenable);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3521 if (status < 0)
3522 goto error;
3523 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3524 if (status < 0)
3525 goto error;
3526 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3527 if (status < 0)
3528 goto error;
3529 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3530error:
3531 if (status < 0)
3532 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003533 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003534}
Oliver Endrissebc7de22011-07-03 13:49:44 -03003535
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003536/*============================================================================*/
3537
3538/**
3539* \brief Initialize channelswitch-independent settings for DVBT.
3540* \param demod instance of demodulator.
3541* \return DRXStatus_t.
3542*
3543* For ROM code channel filter taps are loaded from the bootloader. For microcode
3544* the DVB-T taps from the drxk_filters.h are used.
3545*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003546static int SetDVBTStandard(struct drxk_state *state,
3547 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003548{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003549 u16 cmdResult = 0;
3550 u16 data = 0;
3551 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003552
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003553 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003554
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003555 PowerUpDVBT(state);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003556 /* added antenna switch */
3557 SwitchAntennaToDVBT(state);
3558 /* send OFDM reset command */
3559 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003560 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003561 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003562
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003563 /* send OFDM setenv command */
3564 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3565 if (status < 0)
3566 goto error;
3567
3568 /* reset datapath for OFDM, processors first */
3569 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3570 if (status < 0)
3571 goto error;
3572 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3573 if (status < 0)
3574 goto error;
3575 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3576 if (status < 0)
3577 goto error;
3578
3579 /* IQM setup */
3580 /* synchronize on ofdstate->m_festart */
3581 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3582 if (status < 0)
3583 goto error;
3584 /* window size for clipping ADC detection */
3585 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3586 if (status < 0)
3587 goto error;
3588 /* window size for for sense pre-SAW detection */
3589 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3590 if (status < 0)
3591 goto error;
3592 /* sense threshold for sense pre-SAW detection */
3593 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3594 if (status < 0)
3595 goto error;
3596 status = SetIqmAf(state, true);
3597 if (status < 0)
3598 goto error;
3599
3600 status = write16(state, IQM_AF_AGC_RF__A, 0);
3601 if (status < 0)
3602 goto error;
3603
3604 /* Impulse noise cruncher setup */
3605 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3606 if (status < 0)
3607 goto error;
3608 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3609 if (status < 0)
3610 goto error;
3611 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3612 if (status < 0)
3613 goto error;
3614
3615 status = write16(state, IQM_RC_STRETCH__A, 16);
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3622 if (status < 0)
3623 goto error;
3624 status = write16(state, IQM_CF_SCALE__A, 1600);
3625 if (status < 0)
3626 goto error;
3627 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3628 if (status < 0)
3629 goto error;
3630
3631 /* virtual clipping threshold for clipping ADC detection */
3632 status = write16(state, IQM_AF_CLP_TH__A, 448);
3633 if (status < 0)
3634 goto error;
3635 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3636 if (status < 0)
3637 goto error;
3638
3639 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3640 if (status < 0)
3641 goto error;
3642
3643 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3644 if (status < 0)
3645 goto error;
3646 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3647 if (status < 0)
3648 goto error;
3649 /* enable power measurement interrupt */
3650 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3651 if (status < 0)
3652 goto error;
3653 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3654 if (status < 0)
3655 goto error;
3656
3657 /* IQM will not be reset from here, sync ADC and update/init AGC */
3658 status = ADCSynchronization(state);
3659 if (status < 0)
3660 goto error;
3661 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3662 if (status < 0)
3663 goto error;
3664
3665 /* Halt SCU to enable safe non-atomic accesses */
3666 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3667 if (status < 0)
3668 goto error;
3669
3670 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3671 if (status < 0)
3672 goto error;
3673 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3674 if (status < 0)
3675 goto error;
3676
3677 /* Set Noise Estimation notch width and enable DC fix */
3678 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3679 if (status < 0)
3680 goto error;
3681 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3682 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3683 if (status < 0)
3684 goto error;
3685
3686 /* Activate SCU to enable SCU commands */
3687 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3688 if (status < 0)
3689 goto error;
3690
3691 if (!state->m_DRXK_A3_ROM_CODE) {
3692 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3693 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3694 if (status < 0)
3695 goto error;
3696 }
3697
3698 /* OFDM_SC setup */
3699#ifdef COMPILE_FOR_NONRT
3700 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3701 if (status < 0)
3702 goto error;
3703 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3704 if (status < 0)
3705 goto error;
3706#endif
3707
3708 /* FEC setup */
3709 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3710 if (status < 0)
3711 goto error;
3712
3713
3714#ifdef COMPILE_FOR_NONRT
3715 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3716 if (status < 0)
3717 goto error;
3718#else
3719 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3720 if (status < 0)
3721 goto error;
3722#endif
3723 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3724 if (status < 0)
3725 goto error;
3726
3727 /* Setup MPEG bus */
3728 status = MPEGTSDtoSetup(state, OM_DVBT);
3729 if (status < 0)
3730 goto error;
3731 /* Set DVBT Presets */
3732 status = DVBTActivatePresets(state);
3733 if (status < 0)
3734 goto error;
3735
3736error:
3737 if (status < 0)
3738 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003739 return status;
3740}
3741
3742/*============================================================================*/
3743/**
3744* \brief Start dvbt demodulating for channel.
3745* \param demod instance of demodulator.
3746* \return DRXStatus_t.
3747*/
3748static int DVBTStart(struct drxk_state *state)
3749{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003750 u16 param1;
3751 int status;
3752 /* DRXKOfdmScCmd_t scCmd; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003753
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03003754 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03003755 /* Start correct processes to get in lock */
3756 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003757 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3758 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3759 if (status < 0)
3760 goto error;
3761 /* Start FEC OC */
3762 status = MPEGTSStart(state);
3763 if (status < 0)
3764 goto error;
3765 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3766 if (status < 0)
3767 goto error;
3768error:
3769 if (status < 0)
3770 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03003771 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003772}
3773
3774
3775/*============================================================================*/
3776
3777/**
3778* \brief Set up dvbt demodulator for channel.
3779* \param demod instance of demodulator.
3780* \return DRXStatus_t.
3781* // original DVBTSetChannel()
3782*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03003783static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3784 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003785{
Oliver Endrissebc7de22011-07-03 13:49:44 -03003786 u16 cmdResult = 0;
3787 u16 transmissionParams = 0;
3788 u16 operationMode = 0;
3789 u32 iqmRcRateOfs = 0;
3790 u32 bandwidth = 0;
3791 u16 param1;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003792 int status;
3793
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003794 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003795
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003796 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3797 if (status < 0)
3798 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003799
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003800 /* Halt SCU to enable safe non-atomic accesses */
3801 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3802 if (status < 0)
3803 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003804
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003805 /* Stop processors */
3806 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3807 if (status < 0)
3808 goto error;
3809 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3810 if (status < 0)
3811 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003812
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003813 /* Mandatory fix, always stop CP, required to set spl offset back to
3814 hardware default (is set to 0 by ucode during pilot detection */
3815 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3816 if (status < 0)
3817 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003818
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003819 /*== Write channel settings to device =====================================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003820
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003821 /* mode */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003822 switch (state->props.transmission_mode) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003823 case TRANSMISSION_MODE_AUTO:
3824 default:
3825 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3826 /* fall through , try first guess DRX_FFTMODE_8K */
3827 case TRANSMISSION_MODE_8K:
3828 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003829 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003830 case TRANSMISSION_MODE_2K:
3831 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003832 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003833 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003834
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003835 /* guard */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003836 switch (state->props.guard_interval) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003837 default:
3838 case GUARD_INTERVAL_AUTO:
3839 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3840 /* fall through , try first guess DRX_GUARD_1DIV4 */
3841 case GUARD_INTERVAL_1_4:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003843 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003844 case GUARD_INTERVAL_1_32:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003846 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003847 case GUARD_INTERVAL_1_16:
3848 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003849 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003850 case GUARD_INTERVAL_1_8:
3851 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
Mauro Carvalho Chehab320ed232011-07-15 01:14:17 -03003852 break;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003853 }
3854
3855 /* hierarchy */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003856 switch (state->props.hierarchy) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003857 case HIERARCHY_AUTO:
3858 case HIERARCHY_NONE:
3859 default:
3860 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3861 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3862 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3863 /* break; */
3864 case HIERARCHY_1:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3866 break;
3867 case HIERARCHY_2:
3868 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3869 break;
3870 case HIERARCHY_4:
3871 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3872 break;
3873 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003874
3875
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003876 /* modulation */
3877 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003878 case QAM_AUTO:
3879 default:
3880 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3881 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3882 case QAM_64:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3884 break;
3885 case QPSK:
3886 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3887 break;
3888 case QAM_16:
3889 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3890 break;
3891 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003892#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003893 /* No hierachical channels support in BDA */
3894 /* Priority (only for hierarchical channels) */
3895 switch (channel->priority) {
3896 case DRX_PRIORITY_LOW:
3897 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3898 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3899 OFDM_EC_SB_PRIOR_LO);
3900 break;
3901 case DRX_PRIORITY_HIGH:
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003902 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003903 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3904 OFDM_EC_SB_PRIOR_HI));
3905 break;
3906 case DRX_PRIORITY_UNKNOWN: /* fall through */
3907 default:
3908 status = -EINVAL;
3909 goto error;
3910 }
3911#else
3912 /* Set Priorty high */
3913 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3914 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3915 if (status < 0)
3916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003917#endif
3918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003919 /* coderate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003920 switch (state->props.code_rate_HP) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003921 case FEC_AUTO:
3922 default:
3923 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3924 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3925 case FEC_2_3:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3927 break;
3928 case FEC_1_2:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3930 break;
3931 case FEC_3_4:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3933 break;
3934 case FEC_5_6:
3935 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3936 break;
3937 case FEC_7_8:
3938 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3939 break;
3940 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03003941
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003942 /* SAW filter selection: normaly not necesarry, but if wanted
3943 the application can select a SAW filter via the driver by using UIOs */
3944 /* First determine real bandwidth (Hz) */
3945 /* Also set delay for impulse noise cruncher */
3946 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3947 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3948 functions */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003949 switch (state->props.bandwidth_hz) {
3950 case 0:
3951 state->props.bandwidth_hz = 8000000;
3952 /* fall though */
3953 case 8000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003954 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3955 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03003956 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003957 goto error;
3958 /* cochannel protection for PAL 8 MHz */
3959 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3960 if (status < 0)
3961 goto error;
3962 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3963 if (status < 0)
3964 goto error;
3965 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3966 if (status < 0)
3967 goto error;
3968 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3969 if (status < 0)
3970 goto error;
3971 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003972 case 7000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003973 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3974 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3975 if (status < 0)
3976 goto error;
3977 /* cochannel protection for PAL 7 MHz */
3978 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3979 if (status < 0)
3980 goto error;
3981 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3982 if (status < 0)
3983 goto error;
3984 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3985 if (status < 0)
3986 goto error;
3987 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3988 if (status < 0)
3989 goto error;
3990 break;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03003991 case 6000000:
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03003992 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3993 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3994 if (status < 0)
3995 goto error;
3996 /* cochannel protection for NTSC 6 MHz */
3997 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3998 if (status < 0)
3999 goto error;
4000 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
4001 if (status < 0)
4002 goto error;
4003 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
4004 if (status < 0)
4005 goto error;
4006 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
4007 if (status < 0)
4008 goto error;
4009 break;
4010 default:
4011 status = -EINVAL;
4012 goto error;
4013 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004014
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004015 if (iqmRcRateOfs == 0) {
4016 /* Now compute IQM_RC_RATE_OFS
4017 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4018 =>
4019 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4020 */
4021 /* (SysFreq / BandWidth) * (2^28) */
4022 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4023 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4024 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4025 iqmRcRateOfs = Frac28a((u32)
4026 ((state->m_sysClockFreq *
4027 1000) / 3), bandwidth);
4028 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4029 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4030 iqmRcRateOfs += 0x80L;
4031 iqmRcRateOfs = iqmRcRateOfs >> 7;
4032 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4033 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4034 }
4035
4036 iqmRcRateOfs &=
4037 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4038 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4039 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4040 if (status < 0)
4041 goto error;
4042
4043 /* Bandwidth setting done */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004044
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004045#if 0
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004046 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4047 if (status < 0)
4048 goto error;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004049#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004050 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4051 if (status < 0)
4052 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004053
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004054 /*== Start SC, write channel settings to SC ===============================*/
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004055
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004056 /* Activate SCU to enable SCU commands */
4057 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4058 if (status < 0)
4059 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004061 /* Enable SC after setting all other parameters */
4062 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4063 if (status < 0)
4064 goto error;
4065 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4066 if (status < 0)
4067 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004068
4069
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004070 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4071 if (status < 0)
4072 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004073
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004074 /* Write SC parameter registers, set all AUTO flags in operation mode */
4075 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4076 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4077 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4078 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4079 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4080 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4081 0, transmissionParams, param1, 0, 0, 0);
4082 if (status < 0)
4083 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004084
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004085 if (!state->m_DRXK_A3_ROM_CODE)
4086 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4087error:
4088 if (status < 0)
4089 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004090
4091 return status;
4092}
4093
4094
4095/*============================================================================*/
4096
4097/**
4098* \brief Retreive lock status .
4099* \param demod Pointer to demodulator instance.
4100* \param lockStat Pointer to lock status structure.
4101* \return DRXStatus_t.
4102*
4103*/
4104static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4105{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004106 int status;
4107 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4108 OFDM_SC_RA_RAM_LOCK_FEC__M);
4109 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4110 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004111
Oliver Endrissebc7de22011-07-03 13:49:44 -03004112 u16 ScRaRamLock = 0;
4113 u16 ScCommExec = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004114
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004115 dprintk(1, "\n");
4116
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004117 *pLockStatus = NOT_LOCKED;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004118 /* driver 0.9.0 */
4119 /* Check if SC is running */
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004120 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004121 if (status < 0)
4122 goto end;
4123 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4124 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004125
Mauro Carvalho Chehab5e66b872011-07-09 09:50:21 -03004126 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004127 if (status < 0)
4128 goto end;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004129
Oliver Endrissebc7de22011-07-03 13:49:44 -03004130 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4131 *pLockStatus = MPEG_LOCK;
4132 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4133 *pLockStatus = FEC_LOCK;
4134 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4135 *pLockStatus = DEMOD_LOCK;
4136 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4137 *pLockStatus = NEVER_LOCK;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004138end:
4139 if (status < 0)
4140 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004141
Oliver Endrissebc7de22011-07-03 13:49:44 -03004142 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004143}
4144
Oliver Endrissebc7de22011-07-03 13:49:44 -03004145static int PowerUpQAM(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004146{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004147 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004148 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004149
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004150 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004151 status = CtrlPowerMode(state, &powerMode);
4152 if (status < 0)
4153 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004154
Oliver Endrissebc7de22011-07-03 13:49:44 -03004155 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004156}
4157
4158
Oliver Endrissebc7de22011-07-03 13:49:44 -03004159/** Power Down QAM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004160static int PowerDownQAM(struct drxk_state *state)
4161{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004162 u16 data = 0;
4163 u16 cmdResult;
4164 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004165
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004166 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004167 status = read16(state, SCU_COMM_EXEC__A, &data);
4168 if (status < 0)
4169 goto error;
4170 if (data == SCU_COMM_EXEC_ACTIVE) {
4171 /*
4172 STOP demodulator
4173 QAM and HW blocks
4174 */
4175 /* stop all comstate->m_exec */
4176 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004177 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004178 goto error;
4179 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03004180 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004181 goto error;
4182 }
4183 /* powerdown AFE */
4184 status = SetIqmAf(state, false);
4185
4186error:
4187 if (status < 0)
4188 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004189
Oliver Endrissebc7de22011-07-03 13:49:44 -03004190 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004191}
Oliver Endrissebc7de22011-07-03 13:49:44 -03004192
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004193/*============================================================================*/
4194
4195/**
4196* \brief Setup of the QAM Measurement intervals for signal quality
4197* \param demod instance of demod.
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004198* \param modulation current modulation.
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004199* \return DRXStatus_t.
4200*
4201* NOTE:
4202* Take into account that for certain settings the errorcounters can overflow.
4203* The implementation does not check this.
4204*
4205*/
4206static int SetQAMMeasurement(struct drxk_state *state,
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004207 enum EDrxkConstellation modulation,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004208 u32 symbolRate)
4209{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004210 u32 fecBitsDesired = 0; /* BER accounting period */
4211 u32 fecRsPeriodTotal = 0; /* Total period */
4212 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4213 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004214 int status = 0;
4215
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004216 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004217
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004218 fecRsPrescale = 1;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004219 /* fecBitsDesired = symbolRate [kHz] *
4220 FrameLenght [ms] *
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004221 (modulation + 1) *
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004222 SyncLoss (== 1) *
4223 ViterbiLoss (==1)
4224 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03004225 switch (modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004226 case DRX_CONSTELLATION_QAM16:
4227 fecBitsDesired = 4 * symbolRate;
4228 break;
4229 case DRX_CONSTELLATION_QAM32:
4230 fecBitsDesired = 5 * symbolRate;
4231 break;
4232 case DRX_CONSTELLATION_QAM64:
4233 fecBitsDesired = 6 * symbolRate;
4234 break;
4235 case DRX_CONSTELLATION_QAM128:
4236 fecBitsDesired = 7 * symbolRate;
4237 break;
4238 case DRX_CONSTELLATION_QAM256:
4239 fecBitsDesired = 8 * symbolRate;
4240 break;
4241 default:
4242 status = -EINVAL;
4243 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03004244 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004245 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004246
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004247 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4248 fecBitsDesired *= 500; /* meas. period [ms] */
4249
4250 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4251 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4252 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4253
4254 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4255 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4256 if (fecRsPrescale == 0) {
4257 /* Divide by zero (though impossible) */
4258 status = -EINVAL;
4259 if (status < 0)
4260 goto error;
4261 }
4262 fecRsPeriod =
4263 ((u16) fecRsPeriodTotal +
4264 (fecRsPrescale >> 1)) / fecRsPrescale;
4265
4266 /* write corresponding registers */
4267 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4268 if (status < 0)
4269 goto error;
4270 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4271 if (status < 0)
4272 goto error;
4273 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4274error:
4275 if (status < 0)
4276 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004277 return status;
4278}
4279
Oliver Endrissebc7de22011-07-03 13:49:44 -03004280static int SetQAM16(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004281{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004282 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004283
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004284 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004285 /* QAM Equalizer Setup */
4286 /* Equalizer */
4287 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4288 if (status < 0)
4289 goto error;
4290 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4291 if (status < 0)
4292 goto error;
4293 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4294 if (status < 0)
4295 goto error;
4296 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4297 if (status < 0)
4298 goto error;
4299 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4300 if (status < 0)
4301 goto error;
4302 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4303 if (status < 0)
4304 goto error;
4305 /* Decision Feedback Equalizer */
4306 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4307 if (status < 0)
4308 goto error;
4309 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4310 if (status < 0)
4311 goto error;
4312 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4313 if (status < 0)
4314 goto error;
4315 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4316 if (status < 0)
4317 goto error;
4318 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4319 if (status < 0)
4320 goto error;
4321 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4322 if (status < 0)
4323 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004324
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004325 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4326 if (status < 0)
4327 goto error;
4328 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4329 if (status < 0)
4330 goto error;
4331 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4332 if (status < 0)
4333 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004335 /* QAM Slicer Settings */
4336 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4337 if (status < 0)
4338 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004339
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004340 /* QAM Loop Controller Coeficients */
4341 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4342 if (status < 0)
4343 goto error;
4344 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4345 if (status < 0)
4346 goto error;
4347 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4348 if (status < 0)
4349 goto error;
4350 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4351 if (status < 0)
4352 goto error;
4353 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4354 if (status < 0)
4355 goto error;
4356 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4357 if (status < 0)
4358 goto error;
4359 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4360 if (status < 0)
4361 goto error;
4362 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4363 if (status < 0)
4364 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004365
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004366 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4367 if (status < 0)
4368 goto error;
4369 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4370 if (status < 0)
4371 goto error;
4372 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4373 if (status < 0)
4374 goto error;
4375 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4376 if (status < 0)
4377 goto error;
4378 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4379 if (status < 0)
4380 goto error;
4381 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4382 if (status < 0)
4383 goto error;
4384 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4385 if (status < 0)
4386 goto error;
4387 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4388 if (status < 0)
4389 goto error;
4390 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4391 if (status < 0)
4392 goto error;
4393 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4394 if (status < 0)
4395 goto error;
4396 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4397 if (status < 0)
4398 goto error;
4399 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4400 if (status < 0)
4401 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004402
4403
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004404 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004405
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004406 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4407 if (status < 0)
4408 goto error;
4409 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4410 if (status < 0)
4411 goto error;
4412 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4413 if (status < 0)
4414 goto error;
4415 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4416 if (status < 0)
4417 goto error;
4418 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4419 if (status < 0)
4420 goto error;
4421 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4422 if (status < 0)
4423 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004424
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004425 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4426 if (status < 0)
4427 goto error;
4428 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4429 if (status < 0)
4430 goto error;
4431 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4432 if (status < 0)
4433 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004434
4435
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004436 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004437
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004438 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4439 if (status < 0)
4440 goto error;
4441 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4442 if (status < 0)
4443 goto error;
4444 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4445 if (status < 0)
4446 goto error;
4447 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4448 if (status < 0)
4449 goto error;
4450 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4451 if (status < 0)
4452 goto error;
4453 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4454 if (status < 0)
4455 goto error;
4456 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4457 if (status < 0)
4458 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004459
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004460error:
4461 if (status < 0)
4462 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004463 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004464}
4465
4466/*============================================================================*/
4467
4468/**
4469* \brief QAM32 specific setup
4470* \param demod instance of demod.
4471* \return DRXStatus_t.
4472*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004473static int SetQAM32(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004474{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004475 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004476
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004477 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004478
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004479 /* QAM Equalizer Setup */
4480 /* Equalizer */
4481 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4482 if (status < 0)
4483 goto error;
4484 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4485 if (status < 0)
4486 goto error;
4487 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4488 if (status < 0)
4489 goto error;
4490 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4491 if (status < 0)
4492 goto error;
4493 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4497 if (status < 0)
4498 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004499
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004500 /* Decision Feedback Equalizer */
4501 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4502 if (status < 0)
4503 goto error;
4504 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4505 if (status < 0)
4506 goto error;
4507 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4508 if (status < 0)
4509 goto error;
4510 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4511 if (status < 0)
4512 goto error;
4513 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4514 if (status < 0)
4515 goto error;
4516 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4517 if (status < 0)
4518 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004519
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004520 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4521 if (status < 0)
4522 goto error;
4523 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4524 if (status < 0)
4525 goto error;
4526 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4527 if (status < 0)
4528 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004529
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004530 /* QAM Slicer Settings */
4531
4532 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4533 if (status < 0)
4534 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004535
4536
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004537 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004538
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004539 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4540 if (status < 0)
4541 goto error;
4542 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4543 if (status < 0)
4544 goto error;
4545 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4546 if (status < 0)
4547 goto error;
4548 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4549 if (status < 0)
4550 goto error;
4551 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4552 if (status < 0)
4553 goto error;
4554 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4555 if (status < 0)
4556 goto error;
4557 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4558 if (status < 0)
4559 goto error;
4560 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4561 if (status < 0)
4562 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004563
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004564 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4565 if (status < 0)
4566 goto error;
4567 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4568 if (status < 0)
4569 goto error;
4570 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4571 if (status < 0)
4572 goto error;
4573 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4574 if (status < 0)
4575 goto error;
4576 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4577 if (status < 0)
4578 goto error;
4579 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4580 if (status < 0)
4581 goto error;
4582 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4583 if (status < 0)
4584 goto error;
4585 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4586 if (status < 0)
4587 goto error;
4588 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4589 if (status < 0)
4590 goto error;
4591 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4592 if (status < 0)
4593 goto error;
4594 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4595 if (status < 0)
4596 goto error;
4597 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4598 if (status < 0)
4599 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004600
4601
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004602 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004603
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004604 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4605 if (status < 0)
4606 goto error;
4607 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4608 if (status < 0)
4609 goto error;
4610 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4611 if (status < 0)
4612 goto error;
4613 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4614 if (status < 0)
4615 goto error;
4616 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4617 if (status < 0)
4618 goto error;
4619 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4620 if (status < 0)
4621 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004622
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004623 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4624 if (status < 0)
4625 goto error;
4626 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4627 if (status < 0)
4628 goto error;
4629 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4630 if (status < 0)
4631 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004632
4633
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004634 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004635
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004636 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4637 if (status < 0)
4638 goto error;
4639 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4640 if (status < 0)
4641 goto error;
4642 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4643 if (status < 0)
4644 goto error;
4645 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4646 if (status < 0)
4647 goto error;
4648 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4649 if (status < 0)
4650 goto error;
4651 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4652 if (status < 0)
4653 goto error;
4654 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4655error:
4656 if (status < 0)
4657 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03004658 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004659}
4660
4661/*============================================================================*/
4662
4663/**
4664* \brief QAM64 specific setup
4665* \param demod instance of demod.
4666* \return DRXStatus_t.
4667*/
Oliver Endrissebc7de22011-07-03 13:49:44 -03004668static int SetQAM64(struct drxk_state *state)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004669{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004670 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004671
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004672 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004673 /* QAM Equalizer Setup */
4674 /* Equalizer */
4675 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4676 if (status < 0)
4677 goto error;
4678 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4679 if (status < 0)
4680 goto error;
4681 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4682 if (status < 0)
4683 goto error;
4684 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4685 if (status < 0)
4686 goto error;
4687 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4691 if (status < 0)
4692 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004693
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004694 /* Decision Feedback Equalizer */
4695 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4696 if (status < 0)
4697 goto error;
4698 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4699 if (status < 0)
4700 goto error;
4701 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4702 if (status < 0)
4703 goto error;
4704 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4705 if (status < 0)
4706 goto error;
4707 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4708 if (status < 0)
4709 goto error;
4710 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4711 if (status < 0)
4712 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004713
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004714 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4715 if (status < 0)
4716 goto error;
4717 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4718 if (status < 0)
4719 goto error;
4720 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4721 if (status < 0)
4722 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004723
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004724 /* QAM Slicer Settings */
4725 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4726 if (status < 0)
4727 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004728
4729
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004730 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004731
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004732 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4733 if (status < 0)
4734 goto error;
4735 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4736 if (status < 0)
4737 goto error;
4738 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4739 if (status < 0)
4740 goto error;
4741 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4742 if (status < 0)
4743 goto error;
4744 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4745 if (status < 0)
4746 goto error;
4747 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4748 if (status < 0)
4749 goto error;
4750 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4751 if (status < 0)
4752 goto error;
4753 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4754 if (status < 0)
4755 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004757 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4758 if (status < 0)
4759 goto error;
4760 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4761 if (status < 0)
4762 goto error;
4763 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4764 if (status < 0)
4765 goto error;
4766 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4767 if (status < 0)
4768 goto error;
4769 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4770 if (status < 0)
4771 goto error;
4772 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4773 if (status < 0)
4774 goto error;
4775 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4776 if (status < 0)
4777 goto error;
4778 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4779 if (status < 0)
4780 goto error;
4781 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4782 if (status < 0)
4783 goto error;
4784 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4785 if (status < 0)
4786 goto error;
4787 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4788 if (status < 0)
4789 goto error;
4790 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4791 if (status < 0)
4792 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004793
4794
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004795 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004796
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004797 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4798 if (status < 0)
4799 goto error;
4800 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4801 if (status < 0)
4802 goto error;
4803 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4804 if (status < 0)
4805 goto error;
4806 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4807 if (status < 0)
4808 goto error;
4809 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4810 if (status < 0)
4811 goto error;
4812 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4813 if (status < 0)
4814 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004815
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004816 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4817 if (status < 0)
4818 goto error;
4819 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4820 if (status < 0)
4821 goto error;
4822 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4823 if (status < 0)
4824 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004825
4826
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004827 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004828
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004829 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4830 if (status < 0)
4831 goto error;
4832 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4833 if (status < 0)
4834 goto error;
4835 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4836 if (status < 0)
4837 goto error;
4838 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4839 if (status < 0)
4840 goto error;
4841 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4842 if (status < 0)
4843 goto error;
4844 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4845 if (status < 0)
4846 goto error;
4847 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4848error:
4849 if (status < 0)
4850 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004851
Oliver Endrissebc7de22011-07-03 13:49:44 -03004852 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004853}
4854
4855/*============================================================================*/
4856
4857/**
4858* \brief QAM128 specific setup
4859* \param demod: instance of demod.
4860* \return DRXStatus_t.
4861*/
4862static int SetQAM128(struct drxk_state *state)
4863{
Oliver Endrissebc7de22011-07-03 13:49:44 -03004864 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004865
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03004866 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004867 /* QAM Equalizer Setup */
4868 /* Equalizer */
4869 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4870 if (status < 0)
4871 goto error;
4872 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4873 if (status < 0)
4874 goto error;
4875 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4876 if (status < 0)
4877 goto error;
4878 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4879 if (status < 0)
4880 goto error;
4881 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4885 if (status < 0)
4886 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004887
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004888 /* Decision Feedback Equalizer */
4889 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4890 if (status < 0)
4891 goto error;
4892 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4893 if (status < 0)
4894 goto error;
4895 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4896 if (status < 0)
4897 goto error;
4898 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4899 if (status < 0)
4900 goto error;
4901 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4902 if (status < 0)
4903 goto error;
4904 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4905 if (status < 0)
4906 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03004907
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004908 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4909 if (status < 0)
4910 goto error;
4911 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4912 if (status < 0)
4913 goto error;
4914 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4915 if (status < 0)
4916 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004917
4918
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004919 /* QAM Slicer Settings */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004920
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004921 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4922 if (status < 0)
4923 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004924
4925
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004926 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004927
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004928 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4929 if (status < 0)
4930 goto error;
4931 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4932 if (status < 0)
4933 goto error;
4934 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4935 if (status < 0)
4936 goto error;
4937 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4938 if (status < 0)
4939 goto error;
4940 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4941 if (status < 0)
4942 goto error;
4943 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4944 if (status < 0)
4945 goto error;
4946 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4947 if (status < 0)
4948 goto error;
4949 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4950 if (status < 0)
4951 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004952
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004953 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4954 if (status < 0)
4955 goto error;
4956 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4957 if (status < 0)
4958 goto error;
4959 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4960 if (status < 0)
4961 goto error;
4962 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4963 if (status < 0)
4964 goto error;
4965 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4966 if (status < 0)
4967 goto error;
4968 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4969 if (status < 0)
4970 goto error;
4971 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4972 if (status < 0)
4973 goto error;
4974 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4975 if (status < 0)
4976 goto error;
4977 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4978 if (status < 0)
4979 goto error;
4980 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4981 if (status < 0)
4982 goto error;
4983 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4984 if (status < 0)
4985 goto error;
4986 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4987 if (status < 0)
4988 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004989
4990
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004991 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03004992
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03004993 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4994 if (status < 0)
4995 goto error;
4996 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4997 if (status < 0)
4998 goto error;
4999 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5000 if (status < 0)
5001 goto error;
5002 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5003 if (status < 0)
5004 goto error;
5005 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
5006 if (status < 0)
5007 goto error;
5008 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5009 if (status < 0)
5010 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005011
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005012 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5013 if (status < 0)
5014 goto error;
5015 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5016 if (status < 0)
5017 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005018
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005019 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5020 if (status < 0)
5021 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005022
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005023 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005024
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005025 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5026 if (status < 0)
5027 goto error;
5028 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5029 if (status < 0)
5030 goto error;
5031 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5032 if (status < 0)
5033 goto error;
5034 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5035 if (status < 0)
5036 goto error;
5037 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5038 if (status < 0)
5039 goto error;
5040 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5041 if (status < 0)
5042 goto error;
5043 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5044error:
5045 if (status < 0)
5046 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005047
Oliver Endrissebc7de22011-07-03 13:49:44 -03005048 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005049}
5050
5051/*============================================================================*/
5052
5053/**
5054* \brief QAM256 specific setup
5055* \param demod: instance of demod.
5056* \return DRXStatus_t.
5057*/
5058static int SetQAM256(struct drxk_state *state)
5059{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005060 int status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005061
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005062 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005063 /* QAM Equalizer Setup */
5064 /* Equalizer */
5065 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5066 if (status < 0)
5067 goto error;
5068 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5069 if (status < 0)
5070 goto error;
5071 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5072 if (status < 0)
5073 goto error;
5074 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5075 if (status < 0)
5076 goto error;
5077 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5081 if (status < 0)
5082 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005083
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005084 /* Decision Feedback Equalizer */
5085 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5086 if (status < 0)
5087 goto error;
5088 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5089 if (status < 0)
5090 goto error;
5091 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5092 if (status < 0)
5093 goto error;
5094 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5095 if (status < 0)
5096 goto error;
5097 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5098 if (status < 0)
5099 goto error;
5100 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5101 if (status < 0)
5102 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005103
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005104 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5105 if (status < 0)
5106 goto error;
5107 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5108 if (status < 0)
5109 goto error;
5110 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5111 if (status < 0)
5112 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005113
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005114 /* QAM Slicer Settings */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005115
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005116 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5117 if (status < 0)
5118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005119
5120
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005121 /* QAM Loop Controller Coeficients */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005122
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005123 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5124 if (status < 0)
5125 goto error;
5126 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5127 if (status < 0)
5128 goto error;
5129 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5130 if (status < 0)
5131 goto error;
5132 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5133 if (status < 0)
5134 goto error;
5135 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5136 if (status < 0)
5137 goto error;
5138 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5139 if (status < 0)
5140 goto error;
5141 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5142 if (status < 0)
5143 goto error;
5144 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5145 if (status < 0)
5146 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005147
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005148 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5149 if (status < 0)
5150 goto error;
5151 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5152 if (status < 0)
5153 goto error;
5154 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5155 if (status < 0)
5156 goto error;
5157 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5158 if (status < 0)
5159 goto error;
5160 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5161 if (status < 0)
5162 goto error;
5163 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5164 if (status < 0)
5165 goto error;
5166 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5167 if (status < 0)
5168 goto error;
5169 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5170 if (status < 0)
5171 goto error;
5172 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5173 if (status < 0)
5174 goto error;
5175 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5176 if (status < 0)
5177 goto error;
5178 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5179 if (status < 0)
5180 goto error;
5181 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5182 if (status < 0)
5183 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005184
5185
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005186 /* QAM State Machine (FSM) Thresholds */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005187
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005188 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5189 if (status < 0)
5190 goto error;
5191 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5192 if (status < 0)
5193 goto error;
5194 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5195 if (status < 0)
5196 goto error;
5197 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5198 if (status < 0)
5199 goto error;
5200 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5201 if (status < 0)
5202 goto error;
5203 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5204 if (status < 0)
5205 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005206
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005207 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5208 if (status < 0)
5209 goto error;
5210 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5211 if (status < 0)
5212 goto error;
5213 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5214 if (status < 0)
5215 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005216
5217
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005218 /* QAM FSM Tracking Parameters */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005219
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005220 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5221 if (status < 0)
5222 goto error;
5223 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5224 if (status < 0)
5225 goto error;
5226 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5227 if (status < 0)
5228 goto error;
5229 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5230 if (status < 0)
5231 goto error;
5232 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5233 if (status < 0)
5234 goto error;
5235 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5236 if (status < 0)
5237 goto error;
5238 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5239error:
5240 if (status < 0)
5241 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005242 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005243}
5244
5245
5246/*============================================================================*/
5247/**
5248* \brief Reset QAM block.
5249* \param demod: instance of demod.
5250* \param channel: pointer to channel data.
5251* \return DRXStatus_t.
5252*/
5253static int QAMResetQAM(struct drxk_state *state)
5254{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005255 int status;
5256 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005257
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005258 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005259 /* Stop QAM comstate->m_exec */
5260 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5261 if (status < 0)
5262 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005263
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005264 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5265error:
5266 if (status < 0)
5267 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005268 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005269}
5270
5271/*============================================================================*/
5272
5273/**
5274* \brief Set QAM symbolrate.
5275* \param demod: instance of demod.
5276* \param channel: pointer to channel data.
5277* \return DRXStatus_t.
5278*/
5279static int QAMSetSymbolrate(struct drxk_state *state)
5280{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005281 u32 adcFrequency = 0;
5282 u32 symbFreq = 0;
5283 u32 iqmRcRate = 0;
5284 u16 ratesel = 0;
5285 u32 lcSymbRate = 0;
5286 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005287
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005288 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005289 /* Select & calculate correct IQM rate */
5290 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5291 ratesel = 0;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005292 /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
5293 if (state->props.symbol_rate <= 1188750)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005294 ratesel = 3;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005295 else if (state->props.symbol_rate <= 2377500)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005296 ratesel = 2;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005297 else if (state->props.symbol_rate <= 4755000)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005298 ratesel = 1;
5299 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5300 if (status < 0)
5301 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005302
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005303 /*
5304 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5305 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005306 symbFreq = state->props.symbol_rate * (1 << ratesel);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005307 if (symbFreq == 0) {
5308 /* Divide by zero */
5309 status = -EINVAL;
5310 goto error;
5311 }
5312 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5313 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5314 (1 << 23);
5315 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5316 if (status < 0)
5317 goto error;
5318 state->m_iqmRcRate = iqmRcRate;
5319 /*
5320 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5321 */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005322 symbFreq = state->props.symbol_rate;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005323 if (adcFrequency == 0) {
5324 /* Divide by zero */
5325 status = -EINVAL;
5326 goto error;
5327 }
5328 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5329 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5330 16);
5331 if (lcSymbRate > 511)
5332 lcSymbRate = 511;
5333 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005334
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005335error:
5336 if (status < 0)
5337 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005338 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005339}
5340
5341/*============================================================================*/
5342
5343/**
5344* \brief Get QAM lock status.
5345* \param demod: instance of demod.
5346* \param channel: pointer to channel data.
5347* \return DRXStatus_t.
5348*/
5349
5350static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5351{
5352 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005353 u16 Result[2] = { 0, 0 };
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005354
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005355 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005356 *pLockStatus = NOT_LOCKED;
5357 status = scu_command(state,
Oliver Endrissebc7de22011-07-03 13:49:44 -03005358 SCU_RAM_COMMAND_STANDARD_QAM |
5359 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5360 Result);
5361 if (status < 0)
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005362 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005363
5364 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005365 /* 0x0000 NOT LOCKED */
Oliver Endrissebc7de22011-07-03 13:49:44 -03005366 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005367 /* 0x4000 DEMOD LOCKED */
5368 *pLockStatus = DEMOD_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005369 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005370 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5371 *pLockStatus = MPEG_LOCK;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005372 } else {
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005373 /* 0xC000 NEVER LOCKED */
5374 /* (system will never be able to lock to the signal) */
5375 /* TODO: check this, intermediate & standard specific lock states are not
5376 taken into account here */
5377 *pLockStatus = NEVER_LOCK;
5378 }
5379 return status;
5380}
5381
5382#define QAM_MIRROR__M 0x03
5383#define QAM_MIRROR_NORMAL 0x00
5384#define QAM_MIRRORED 0x01
5385#define QAM_MIRROR_AUTO_ON 0x02
5386#define QAM_LOCKRANGE__M 0x10
5387#define QAM_LOCKRANGE_NORMAL 0x10
5388
Oliver Endrissebc7de22011-07-03 13:49:44 -03005389static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5390 s32 tunerFreqOffset)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005391{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005392 int status;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005393 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5394 u16 cmdResult;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005395
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005396 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005397 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005398 * STEP 1: reset demodulator
5399 * resets FEC DI and FEC RS
5400 * resets QAM block
5401 * resets SCU variables
5402 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005403 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005404 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005405 goto error;
5406 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5407 if (status < 0)
5408 goto error;
5409 status = QAMResetQAM(state);
5410 if (status < 0)
5411 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005412
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005413 /*
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005414 * STEP 2: configure demodulator
5415 * -set params; resets IQM,QAM,FEC HW; initializes some
5416 * SCU variables
5417 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005418 status = QAMSetSymbolrate(state);
5419 if (status < 0)
5420 goto error;
5421
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005422 /* Set params */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005423 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005424 case QAM_256:
5425 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5426 break;
5427 case QAM_AUTO:
5428 case QAM_64:
5429 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5430 break;
5431 case QAM_16:
5432 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5433 break;
5434 case QAM_32:
5435 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5436 break;
5437 case QAM_128:
5438 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5439 break;
5440 default:
5441 status = -EINVAL;
5442 break;
5443 }
5444 if (status < 0)
5445 goto error;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005446 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005447 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005448 if (state->m_OperationMode == OM_QAM_ITU_C)
5449 setParamParameters[2] = QAM_TOP_ANNEX_C;
5450 else
5451 setParamParameters[2] = QAM_TOP_ANNEX_A;
5452 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5453 /* Env parameters */
5454 /* check for LOCKRANGE Extented */
5455 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005456
5457 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005458 if (status < 0) {
5459 /* Fall-back to the simpler call */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005460 if (state->m_OperationMode == OM_QAM_ITU_C)
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005461 setParamParameters[0] = QAM_TOP_ANNEX_C;
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005462 else
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005463 setParamParameters[0] = QAM_TOP_ANNEX_A;
5464 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5465 if (status < 0)
5466 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005467
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005468 setParamParameters[0] = state->m_Constellation; /* modulation */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005469 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
Mauro Carvalho Chehab5eee2bb2011-07-10 14:33:29 -03005470 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5471 }
5472 if (status < 0)
5473 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005474
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005475 /*
5476 * STEP 3: enable the system in a mode where the ADC provides valid
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005477 * signal setup modulation independent registers
Mauro Carvalho Chehab119faf92011-07-24 09:11:36 -03005478 */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005479#if 0
5480 status = SetFrequency(channel, tunerFreqOffset));
5481 if (status < 0)
5482 goto error;
5483#endif
5484 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5485 if (status < 0)
5486 goto error;
5487
5488 /* Setup BER measurement */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005489 status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005490 if (status < 0)
5491 goto error;
5492
5493 /* Reset default values */
5494 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5498 if (status < 0)
5499 goto error;
5500
5501 /* Reset default LC values */
5502 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5503 if (status < 0)
5504 goto error;
5505 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5506 if (status < 0)
5507 goto error;
5508 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5509 if (status < 0)
5510 goto error;
5511 status = write16(state, QAM_LC_MODE__A, 7);
5512 if (status < 0)
5513 goto error;
5514
5515 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5516 if (status < 0)
5517 goto error;
5518 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5519 if (status < 0)
5520 goto error;
5521 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5522 if (status < 0)
5523 goto error;
5524 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5525 if (status < 0)
5526 goto error;
5527 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5528 if (status < 0)
5529 goto error;
5530 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5531 if (status < 0)
5532 goto error;
5533 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5534 if (status < 0)
5535 goto error;
5536 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5537 if (status < 0)
5538 goto error;
5539 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5540 if (status < 0)
5541 goto error;
5542 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5543 if (status < 0)
5544 goto error;
5545 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5546 if (status < 0)
5547 goto error;
5548 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5549 if (status < 0)
5550 goto error;
5551 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5552 if (status < 0)
5553 goto error;
5554 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5555 if (status < 0)
5556 goto error;
5557 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5558 if (status < 0)
5559 goto error;
5560
5561 /* Mirroring, QAM-block starting point not inverted */
5562 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5563 if (status < 0)
5564 goto error;
5565
5566 /* Halt SCU to enable safe non-atomic accesses */
5567 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5568 if (status < 0)
5569 goto error;
5570
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005571 /* STEP 4: modulation specific setup */
5572 switch (state->props.modulation) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005573 case QAM_16:
5574 status = SetQAM16(state);
5575 break;
5576 case QAM_32:
5577 status = SetQAM32(state);
5578 break;
5579 case QAM_AUTO:
5580 case QAM_64:
5581 status = SetQAM64(state);
5582 break;
5583 case QAM_128:
5584 status = SetQAM128(state);
5585 break;
5586 case QAM_256:
5587 status = SetQAM256(state);
5588 break;
5589 default:
5590 status = -EINVAL;
5591 break;
5592 }
5593 if (status < 0)
5594 goto error;
5595
5596 /* Activate SCU to enable SCU commands */
5597 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5598 if (status < 0)
5599 goto error;
5600
5601 /* Re-configure MPEG output, requires knowledge of channel bitrate */
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03005602 /* extAttr->currentChannel.modulation = channel->modulation; */
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005603 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5604 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5605 if (status < 0)
5606 goto error;
5607
5608 /* Start processes */
5609 status = MPEGTSStart(state);
5610 if (status < 0)
5611 goto error;
5612 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5613 if (status < 0)
5614 goto error;
5615 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5616 if (status < 0)
5617 goto error;
5618 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5619 if (status < 0)
5620 goto error;
5621
5622 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5623 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5624 if (status < 0)
5625 goto error;
5626
5627 /* update global DRXK data container */
5628/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5629
5630error:
5631 if (status < 0)
5632 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005633 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005634}
5635
Oliver Endrissebc7de22011-07-03 13:49:44 -03005636static int SetQAMStandard(struct drxk_state *state,
5637 enum OperationMode oMode)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005638{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005639 int status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005640#ifdef DRXK_QAM_TAPS
5641#define DRXK_QAMA_TAPS_SELECT
5642#include "drxk_filters.h"
5643#undef DRXK_QAMA_TAPS_SELECT
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005644#endif
5645
Mauro Carvalho Chehabf1b82972011-07-10 13:08:44 -03005646 dprintk(1, "\n");
5647
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005648 /* added antenna switch */
5649 SwitchAntennaToQAM(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005650
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005651 /* Ensure correct power-up mode */
5652 status = PowerUpQAM(state);
5653 if (status < 0)
5654 goto error;
5655 /* Reset QAM block */
5656 status = QAMResetQAM(state);
5657 if (status < 0)
5658 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005659
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005660 /* Setup IQM */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005661
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005662 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5663 if (status < 0)
5664 goto error;
5665 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5666 if (status < 0)
5667 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005668
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005669 /* Upload IQM Channel Filter settings by
5670 boot loader from ROM table */
5671 switch (oMode) {
5672 case OM_QAM_ITU_A:
5673 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5674 break;
5675 case OM_QAM_ITU_C:
5676 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005677 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005678 goto error;
5679 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5680 break;
5681 default:
5682 status = -EINVAL;
5683 }
5684 if (status < 0)
5685 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005686
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005687 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5688 if (status < 0)
5689 goto error;
5690 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5691 if (status < 0)
5692 goto error;
5693 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5694 if (status < 0)
5695 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005696
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005697 status = write16(state, IQM_RC_STRETCH__A, 21);
5698 if (status < 0)
5699 goto error;
5700 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5701 if (status < 0)
5702 goto error;
5703 status = write16(state, IQM_AF_CLP_TH__A, 448);
5704 if (status < 0)
5705 goto error;
5706 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5707 if (status < 0)
5708 goto error;
5709 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5710 if (status < 0)
5711 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005712
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005713 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5714 if (status < 0)
5715 goto error;
5716 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5717 if (status < 0)
5718 goto error;
5719 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5720 if (status < 0)
5721 goto error;
5722 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5723 if (status < 0)
5724 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005725
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005726 /* IQM Impulse Noise Processing Unit */
5727 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5728 if (status < 0)
5729 goto error;
5730 status = write16(state, IQM_CF_DATATH__A, 1000);
5731 if (status < 0)
5732 goto error;
5733 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5734 if (status < 0)
5735 goto error;
5736 status = write16(state, IQM_CF_DET_LCT__A, 0);
5737 if (status < 0)
5738 goto error;
5739 status = write16(state, IQM_CF_WND_LEN__A, 1);
5740 if (status < 0)
5741 goto error;
5742 status = write16(state, IQM_CF_PKDTH__A, 1);
5743 if (status < 0)
5744 goto error;
5745 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5746 if (status < 0)
5747 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005748
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005749 /* turn on IQMAF. Must be done before setAgc**() */
5750 status = SetIqmAf(state, true);
5751 if (status < 0)
5752 goto error;
5753 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5754 if (status < 0)
5755 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005756
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005757 /* IQM will not be reset from here, sync ADC and update/init AGC */
5758 status = ADCSynchronization(state);
5759 if (status < 0)
5760 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005761
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005762 /* Set the FSM step period */
5763 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5764 if (status < 0)
5765 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005766
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005767 /* Halt SCU to enable safe non-atomic accesses */
5768 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5769 if (status < 0)
5770 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005771
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005772 /* No more resets of the IQM, current standard correctly set =>
5773 now AGCs can be configured. */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005774
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005775 status = InitAGC(state, true);
5776 if (status < 0)
5777 goto error;
5778 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5779 if (status < 0)
5780 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005781
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005782 /* Configure AGC's */
5783 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5784 if (status < 0)
5785 goto error;
5786 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5787 if (status < 0)
5788 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005789
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005790 /* Activate SCU to enable SCU commands */
5791 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5792error:
5793 if (status < 0)
5794 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005795 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005796}
5797
5798static int WriteGPIO(struct drxk_state *state)
5799{
Oliver Endrissebc7de22011-07-03 13:49:44 -03005800 int status;
5801 u16 value = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005802
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005803 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005804 /* stop lock indicator process */
5805 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5806 if (status < 0)
5807 goto error;
5808
5809 /* Write magic word to enable pdr reg write */
5810 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5811 if (status < 0)
5812 goto error;
5813
5814 if (state->m_hasSAWSW) {
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005815 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5816 /* write to io pad configuration register - output mode */
5817 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5818 if (status < 0)
5819 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005820
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005821 /* use corresponding bit in io data output registar */
5822 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5823 if (status < 0)
5824 goto error;
5825 if ((state->m_GPIO & 0x0001) == 0)
5826 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5827 else
5828 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5829 /* write back to io data output register */
5830 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5831 if (status < 0)
5832 goto error;
5833 }
5834 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5835 /* write to io pad configuration register - output mode */
5836 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5837 if (status < 0)
5838 goto error;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005839
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005840 /* use corresponding bit in io data output registar */
5841 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5842 if (status < 0)
5843 goto error;
5844 if ((state->m_GPIO & 0x0002) == 0)
5845 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5846 else
5847 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5848 /* write back to io data output register */
5849 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5850 if (status < 0)
5851 goto error;
5852 }
5853 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5854 /* write to io pad configuration register - output mode */
5855 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5856 if (status < 0)
5857 goto error;
5858
5859 /* use corresponding bit in io data output registar */
5860 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5861 if (status < 0)
5862 goto error;
5863 if ((state->m_GPIO & 0x0004) == 0)
5864 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5865 else
5866 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5867 /* write back to io data output register */
5868 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5869 if (status < 0)
5870 goto error;
5871 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005872 }
5873 /* Write magic word to disable pdr reg write */
5874 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5875error:
5876 if (status < 0)
5877 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005878 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005879}
5880
5881static int SwitchAntennaToQAM(struct drxk_state *state)
5882{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005883 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005884 bool gpio_state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005885
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005886 dprintk(1, "\n");
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005887
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005888 if (!state->antenna_gpio)
5889 return 0;
5890
5891 gpio_state = state->m_GPIO & state->antenna_gpio;
5892
5893 if (state->antenna_dvbt ^ gpio_state) {
5894 /* Antenna is on DVB-T mode. Switch */
5895 if (state->antenna_dvbt)
5896 state->m_GPIO &= ~state->antenna_gpio;
5897 else
5898 state->m_GPIO |= state->antenna_gpio;
5899 status = WriteGPIO(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005900 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005901 if (status < 0)
5902 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005903 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005904}
5905
5906static int SwitchAntennaToDVBT(struct drxk_state *state)
5907{
Mauro Carvalho Chehab147e1102011-07-10 08:24:26 -03005908 int status = 0;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005909 bool gpio_state;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005910
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005911 dprintk(1, "\n");
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03005912
5913 if (!state->antenna_gpio)
5914 return 0;
5915
5916 gpio_state = state->m_GPIO & state->antenna_gpio;
5917
5918 if (!(state->antenna_dvbt ^ gpio_state)) {
5919 /* Antenna is on DVB-C mode. Switch */
5920 if (state->antenna_dvbt)
5921 state->m_GPIO |= state->antenna_gpio;
5922 else
5923 state->m_GPIO &= ~state->antenna_gpio;
5924 status = WriteGPIO(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005925 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005926 if (status < 0)
5927 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005928 return status;
5929}
5930
5931
5932static int PowerDownDevice(struct drxk_state *state)
5933{
5934 /* Power down to requested mode */
5935 /* Backup some register settings */
5936 /* Set pins with possible pull-ups connected to them in input mode */
5937 /* Analog power down */
5938 /* ADC power down */
5939 /* Power down device */
5940 int status;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005941
5942 dprintk(1, "\n");
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005943 if (state->m_bPDownOpenBridge) {
5944 /* Open I2C bridge before power down of DRXK */
5945 status = ConfigureI2CBridge(state, true);
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -03005946 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005947 goto error;
5948 }
5949 /* driver 0.9.0 */
5950 status = DVBTEnableOFDMTokenRing(state, false);
Oliver Endrissebc7de22011-07-03 13:49:44 -03005951 if (status < 0)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005952 goto error;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005953
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005954 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5955 if (status < 0)
5956 goto error;
5957 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5958 if (status < 0)
5959 goto error;
5960 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5961 status = HI_CfgCommand(state);
5962error:
5963 if (status < 0)
5964 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5965
5966 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005967}
5968
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03005969static int load_microcode(struct drxk_state *state, const char *mc_name)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005970{
5971 const struct firmware *fw = NULL;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005972 int err = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005973
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005974 dprintk(1, "\n");
5975
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005976 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5977 if (err < 0) {
5978 printk(KERN_ERR
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005979 "drxk: Could not load firmware file %s.\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005980 printk(KERN_INFO
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03005981 "drxk: Copy %s to your hotplug directory!\n", mc_name);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005982 return err;
5983 }
Oliver Endrissebc7de22011-07-03 13:49:44 -03005984 err = DownloadMicrocode(state, fw->data, fw->size);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005985 release_firmware(fw);
5986 return err;
5987}
5988
5989static int init_drxk(struct drxk_state *state)
5990{
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005991 int status = 0;
Oliver Endrissebc7de22011-07-03 13:49:44 -03005992 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005993 u16 driverVersion;
5994
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03005995 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03005996 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03005997 status = PowerUpDevice(state);
5998 if (status < 0)
5999 goto error;
6000 status = DRXX_Open(state);
6001 if (status < 0)
6002 goto error;
6003 /* Soft reset of OFDM-, sys- and osc-clockdomain */
6004 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);
6005 if (status < 0)
6006 goto error;
6007 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6008 if (status < 0)
6009 goto error;
6010 /* TODO is this needed, if yes how much delay in worst case scenario */
6011 msleep(1);
6012 state->m_DRXK_A3_PATCH_CODE = true;
6013 status = GetDeviceCapabilities(state);
6014 if (status < 0)
6015 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006016
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006017 /* Bridge delay, uses oscilator clock */
6018 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6019 /* SDA brdige delay */
6020 state->m_HICfgBridgeDelay =
6021 (u16) ((state->m_oscClockFreq / 1000) *
6022 HI_I2C_BRIDGE_DELAY) / 1000;
6023 /* Clipping */
6024 if (state->m_HICfgBridgeDelay >
6025 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
Oliver Endrissebc7de22011-07-03 13:49:44 -03006026 state->m_HICfgBridgeDelay =
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006027 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6028 }
6029 /* SCL bridge delay, same as SDA for now */
6030 state->m_HICfgBridgeDelay +=
6031 state->m_HICfgBridgeDelay <<
6032 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006033
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006034 status = InitHI(state);
6035 if (status < 0)
6036 goto error;
6037 /* disable various processes */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006038#if NOA1ROM
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006039 if (!(state->m_DRXK_A1_ROM_CODE)
6040 && !(state->m_DRXK_A2_ROM_CODE))
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006041#endif
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006042 {
6043 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6044 if (status < 0)
6045 goto error;
6046 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006047
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006048 /* disable MPEG port */
6049 status = MPEGTSDisable(state);
6050 if (status < 0)
6051 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006052
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006053 /* Stop AUD and SCU */
6054 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6055 if (status < 0)
6056 goto error;
6057 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6058 if (status < 0)
6059 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006060
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006061 /* enable token-ring bus through OFDM block for possible ucode upload */
6062 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6063 if (status < 0)
6064 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006065
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006066 /* include boot loader section */
6067 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6068 if (status < 0)
6069 goto error;
6070 status = BLChainCmd(state, 0, 6, 100);
6071 if (status < 0)
6072 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006073
Mauro Carvalho Chehabda989e02011-07-24 09:25:39 -03006074 if (state->microcode_name)
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006075 load_microcode(state, state->microcode_name);
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006076
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006077 /* disable token-ring bus through OFDM block for possible ucode upload */
6078 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6079 if (status < 0)
6080 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006081
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006082 /* Run SCU for a little while to initialize microcode version numbers */
6083 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6084 if (status < 0)
6085 goto error;
6086 status = DRXX_Open(state);
6087 if (status < 0)
6088 goto error;
6089 /* added for test */
6090 msleep(30);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006091
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006092 powerMode = DRXK_POWER_DOWN_OFDM;
6093 status = CtrlPowerMode(state, &powerMode);
6094 if (status < 0)
6095 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006096
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006097 /* Stamp driver version number in SCU data RAM in BCD code
6098 Done to enable field application engineers to retreive drxdriver version
6099 via I2C from SCU RAM.
6100 Not using SCU command interface for SCU register access since no
6101 microcode may be present.
6102 */
6103 driverVersion =
6104 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6105 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6106 ((DRXK_VERSION_MAJOR % 10) << 4) +
6107 (DRXK_VERSION_MINOR % 10);
6108 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6109 if (status < 0)
6110 goto error;
6111 driverVersion =
6112 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6113 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6114 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6115 (DRXK_VERSION_PATCH % 10);
6116 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6117 if (status < 0)
6118 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006119
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006120 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6121 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6122 DRXK_VERSION_PATCH);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006123
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006124 /* Dirty fix of default values for ROM/PATCH microcode
6125 Dirty because this fix makes it impossible to setup suitable values
6126 before calling DRX_Open. This solution requires changes to RF AGC speed
6127 to be done via the CTRL function after calling DRX_Open */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006128
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006129 /* m_dvbtRfAgcCfg.speed = 3; */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006130
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006131 /* Reset driver debug flags to 0 */
6132 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6133 if (status < 0)
6134 goto error;
6135 /* driver 0.9.0 */
6136 /* Setup FEC OC:
6137 NOTE: No more full FEC resets allowed afterwards!! */
6138 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6139 if (status < 0)
6140 goto error;
6141 /* MPEGTS functions are still the same */
6142 status = MPEGTSDtoInit(state);
6143 if (status < 0)
6144 goto error;
6145 status = MPEGTSStop(state);
6146 if (status < 0)
6147 goto error;
6148 status = MPEGTSConfigurePolarity(state);
6149 if (status < 0)
6150 goto error;
6151 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6152 if (status < 0)
6153 goto error;
6154 /* added: configure GPIO */
6155 status = WriteGPIO(state);
6156 if (status < 0)
6157 goto error;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006158
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006159 state->m_DrxkState = DRXK_STOPPED;
6160
6161 if (state->m_bPowerDown) {
6162 status = PowerDownDevice(state);
6163 if (status < 0)
6164 goto error;
6165 state->m_DrxkState = DRXK_POWERED_DOWN;
6166 } else
Oliver Endrissebc7de22011-07-03 13:49:44 -03006167 state->m_DrxkState = DRXK_STOPPED;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006168 }
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006169error:
6170 if (status < 0)
6171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006172
Mauro Carvalho Chehabe716ada2011-07-21 19:35:04 -03006173 return status;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006174}
6175
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006176static void drxk_release(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006177{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006178 struct drxk_state *state = fe->demodulator_priv;
6179
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006180 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006181 kfree(state);
6182}
6183
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006184static int drxk_sleep(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006185{
Oliver Endrissebc7de22011-07-03 13:49:44 -03006186 struct drxk_state *state = fe->demodulator_priv;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006187
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006188 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006189 ShutDown(state);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006190 return 0;
6191}
6192
Oliver Endrissebc7de22011-07-03 13:49:44 -03006193static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006194{
6195 struct drxk_state *state = fe->demodulator_priv;
6196
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006197 dprintk(1, "%s\n", enable ? "enable" : "disable");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006198 return ConfigureI2CBridge(state, enable ? true : false);
6199}
6200
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006201static int drxk_set_parameters(struct dvb_frontend *fe)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006202{
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006203 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006204 u32 delsys = p->delivery_system, old_delsys;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006205 struct drxk_state *state = fe->demodulator_priv;
6206 u32 IF;
6207
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006208 dprintk(1, "\n");
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006209
6210 if (!fe->ops.tuner_ops.get_if_frequency) {
6211 printk(KERN_ERR
6212 "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
6213 return -EINVAL;
6214 }
6215
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006216 if (fe->ops.i2c_gate_ctrl)
6217 fe->ops.i2c_gate_ctrl(fe, 1);
6218 if (fe->ops.tuner_ops.set_params)
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03006219 fe->ops.tuner_ops.set_params(fe);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006220 if (fe->ops.i2c_gate_ctrl)
6221 fe->ops.i2c_gate_ctrl(fe, 0);
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006222
6223 old_delsys = state->props.delivery_system;
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006224 state->props = *p;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006225
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006226 if (old_delsys != delsys) {
6227 ShutDown(state);
6228 switch (delsys) {
6229 case SYS_DVBC_ANNEX_A:
6230 case SYS_DVBC_ANNEX_C:
6231 if (!state->m_hasDVBC)
6232 return -EINVAL;
6233 state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
6234 if (state->m_itut_annex_c)
6235 SetOperationMode(state, OM_QAM_ITU_C);
6236 else
6237 SetOperationMode(state, OM_QAM_ITU_A);
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006238 break;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006239 case SYS_DVBT:
6240 if (!state->m_hasDVBT)
6241 return -EINVAL;
6242 SetOperationMode(state, OM_DVBT);
6243 break;
6244 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006245 return -EINVAL;
Mauro Carvalho Chehab6cb393c2012-01-05 09:26:40 -02006246 }
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006247 }
6248
Mauro Carvalho Chehab8513e142011-09-03 11:40:02 -03006249 fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006250 Start(state, 0, IF);
6251
Mauro Carvalho Chehabe0e6eca2011-07-04 08:27:47 -03006252 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
Oliver Endrissebc7de22011-07-03 13:49:44 -03006253
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006254 return 0;
6255}
6256
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006257static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6258{
6259 struct drxk_state *state = fe->demodulator_priv;
6260 u32 stat;
6261
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006262 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006263 *status = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006264 GetLockStatus(state, &stat, 0);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006265 if (stat == MPEG_LOCK)
6266 *status |= 0x1f;
6267 if (stat == FEC_LOCK)
6268 *status |= 0x0f;
6269 if (stat == DEMOD_LOCK)
6270 *status |= 0x07;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006271 return 0;
6272}
6273
6274static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6275{
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006276 dprintk(1, "\n");
6277
Oliver Endrissebc7de22011-07-03 13:49:44 -03006278 *ber = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006279 return 0;
6280}
6281
Oliver Endrissebc7de22011-07-03 13:49:44 -03006282static int drxk_read_signal_strength(struct dvb_frontend *fe,
6283 u16 *strength)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006284{
6285 struct drxk_state *state = fe->demodulator_priv;
Mauro Carvalho Chehabbe44eb22011-07-10 01:49:53 -03006286 u32 val = 0;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006287
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006288 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006289 ReadIFAgc(state, &val);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006290 *strength = val & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006291 return 0;
6292}
6293
6294static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6295{
6296 struct drxk_state *state = fe->demodulator_priv;
6297 s32 snr2;
6298
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006299 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006300 GetSignalToNoise(state, &snr2);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006301 *snr = snr2 & 0xffff;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006302 return 0;
6303}
6304
6305static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6306{
6307 struct drxk_state *state = fe->demodulator_priv;
6308 u16 err;
6309
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006310 dprintk(1, "\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006311 DVBTQAMGetAccPktErr(state, &err);
6312 *ucblocks = (u32) err;
6313 return 0;
6314}
6315
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006316static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
Oliver Endrissebc7de22011-07-03 13:49:44 -03006317 *sets)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006318{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006319 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006320
6321 dprintk(1, "\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006322 switch (p->delivery_system) {
6323 case SYS_DVBC_ANNEX_A:
6324 case SYS_DVBC_ANNEX_C:
Jose Alberto Reguerodc66d7f2012-01-27 18:34:49 -03006325 case SYS_DVBT:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006326 sets->min_delay_ms = 3000;
6327 sets->max_drift = 0;
6328 sets->step_size = 0;
6329 return 0;
6330 default:
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006331 return -EINVAL;
6332 }
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006333}
6334
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006335static struct dvb_frontend_ops drxk_ops = {
6336 /* .delsys will be filled dynamically */
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006337 .info = {
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006338 .name = "DRXK",
6339 .frequency_min = 47000000,
6340 .frequency_max = 865000000,
6341 /* For DVB-C */
6342 .symbol_rate_min = 870000,
6343 .symbol_rate_max = 11700000,
6344 /* For DVB-T */
6345 .frequency_stepsize = 166667,
6346
6347 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6348 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
6349 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
6350 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
6351 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
6352 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
6353 },
6354
6355 .release = drxk_release,
6356 .sleep = drxk_sleep,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006357 .i2c_gate_ctrl = drxk_gate_ctrl,
6358
Mauro Carvalho Chehabed5452a2011-12-26 09:57:11 -03006359 .set_frontend = drxk_set_parameters,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006360 .get_tune_settings = drxk_get_tune_settings,
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006361
6362 .read_status = drxk_read_status,
6363 .read_ber = drxk_read_ber,
6364 .read_signal_strength = drxk_read_signal_strength,
6365 .read_snr = drxk_read_snr,
6366 .read_ucblocks = drxk_read_ucblocks,
6367};
6368
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006369struct dvb_frontend *drxk_attach(const struct drxk_config *config,
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006370 struct i2c_adapter *i2c)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006371{
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006372 int n;
6373
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006374 struct drxk_state *state = NULL;
Mauro Carvalho Chehab0fc55e82011-07-09 12:36:58 -03006375 u8 adr = config->adr;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006376
Mauro Carvalho Chehab2da67502011-07-04 17:39:21 -03006377 dprintk(1, "\n");
Oliver Endrissebc7de22011-07-03 13:49:44 -03006378 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006379 if (!state)
6380 return NULL;
6381
Oliver Endrissebc7de22011-07-03 13:49:44 -03006382 state->i2c = i2c;
6383 state->demod_address = adr;
Mauro Carvalho Chehabe076c922011-07-09 13:06:12 -03006384 state->single_master = config->single_master;
Mauro Carvalho Chehabe4f4f872011-07-09 17:35:26 -03006385 state->microcode_name = config->microcode_name;
Mauro Carvalho Chehabf1fe1b72011-07-09 21:59:33 -03006386 state->no_i2c_bridge = config->no_i2c_bridge;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006387 state->antenna_gpio = config->antenna_gpio;
6388 state->antenna_dvbt = config->antenna_dvbt;
Eddi De Pieri82e7dbb2011-11-19 11:37:14 -03006389 state->m_ChunkSize = config->chunk_size;
Mauro Carvalho Chehabd5856812012-01-21 07:57:06 -03006390 state->enable_merr_cfg = config->enable_merr_cfg;
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006391
Mauro Carvalho Chehab67f04612012-01-20 18:30:58 -03006392 if (config->dynamic_clk) {
6393 state->m_DVBTStaticCLK = 0;
6394 state->m_DVBCStaticCLK = 0;
6395 } else {
6396 state->m_DVBTStaticCLK = 1;
6397 state->m_DVBCStaticCLK = 1;
6398 }
6399
Mauro Carvalho Chehab6fb65a62012-01-20 19:13:07 -03006400
6401 if (config->mpeg_out_clk_strength)
6402 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6403 else
6404 state->m_TSClockkStrength = 0x06;
6405
Mauro Carvalho Chehab534e0482011-07-24 14:59:20 -03006406 if (config->parallel_ts)
6407 state->m_enableParallel = true;
6408 else
6409 state->m_enableParallel = false;
6410
Mauro Carvalho Chehab90796ac2011-07-10 09:36:30 -03006411 /* NOTE: as more UIO bits will be used, add them to the mask */
6412 state->UIO_mask = config->antenna_gpio;
6413
6414 /* Default gpio to DVB-C */
6415 if (!state->antenna_dvbt && state->antenna_gpio)
6416 state->m_GPIO |= state->antenna_gpio;
6417 else
6418 state->m_GPIO &= ~state->antenna_gpio;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006419
6420 mutex_init(&state->mutex);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006421
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006422 memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
6423 state->frontend.demodulator_priv = state;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006424
6425 init_state(state);
Oliver Endrissebc7de22011-07-03 13:49:44 -03006426 if (init_drxk(state) < 0)
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006427 goto error;
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006428
6429 /* Initialize the supported delivery systems */
6430 n = 0;
6431 if (state->m_hasDVBC) {
6432 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
6433 state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
6434 strlcat(state->frontend.ops.info.name, " DVB-C",
6435 sizeof(state->frontend.ops.info.name));
6436 }
6437 if (state->m_hasDVBT) {
6438 state->frontend.ops.delsys[n++] = SYS_DVBT;
6439 strlcat(state->frontend.ops.info.name, " DVB-T",
6440 sizeof(state->frontend.ops.info.name));
6441 }
Mauro Carvalho Chehabcf694b12011-07-10 10:26:06 -03006442
Mauro Carvalho Chehab0d3e6fe2011-07-22 12:34:41 -03006443 printk(KERN_INFO "drxk: frontend initialized.\n");
Mauro Carvalho Chehabfa4b2a12012-01-05 08:07:32 -02006444 return &state->frontend;
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006445
6446error:
Oliver Endrissebc7de22011-07-03 13:49:44 -03006447 printk(KERN_ERR "drxk: not found\n");
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006448 kfree(state);
6449 return NULL;
6450}
Oliver Endrissebc7de22011-07-03 13:49:44 -03006451EXPORT_SYMBOL(drxk_attach);
Ralph Metzler43dd07f2011-07-03 13:42:18 -03006452
6453MODULE_DESCRIPTION("DRX-K driver");
6454MODULE_AUTHOR("Ralph Metzler");
6455MODULE_LICENSE("GPL");