189ee7f4fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29a0bf528SMauro Carvalho Chehab /*
39a0bf528SMauro Carvalho Chehab  * drxk_hard: DRX-K DVB-C/T demodulator driver
49a0bf528SMauro Carvalho Chehab  *
59a0bf528SMauro Carvalho Chehab  * Copyright (C) 2010-2011 Digital Devices GmbH
69a0bf528SMauro Carvalho Chehab  */
79a0bf528SMauro Carvalho Chehab 
83a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
93a4398f5SMauro Carvalho Chehab 
109a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
119a0bf528SMauro Carvalho Chehab #include <linux/module.h>
129a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
139a0bf528SMauro Carvalho Chehab #include <linux/init.h>
149a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
159a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
169a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
179a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
189a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
199a0bf528SMauro Carvalho Chehab 
20fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
219a0bf528SMauro Carvalho Chehab #include "drxk.h"
229a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
23f97fa3dcSAndy Shevchenko #include <linux/int_log.h>
249a0bf528SMauro Carvalho Chehab 
25cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
26cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state);
27cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
28cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
29cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
30cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode);
31cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
32cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset);
33cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
34cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
35cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state);
36cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
37cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset);
38cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
39cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
40cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state);
41cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state);
429a0bf528SMauro Carvalho Chehab 
is_dvbt(struct drxk_state * state)43cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state)
449a0bf528SMauro Carvalho Chehab {
45cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_DVBT;
469a0bf528SMauro Carvalho Chehab }
479a0bf528SMauro Carvalho Chehab 
is_qam(struct drxk_state * state)48cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state)
499a0bf528SMauro Carvalho Chehab {
50cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_QAM_ITU_A ||
51cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_B ||
52cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_C;
539a0bf528SMauro Carvalho Chehab }
549a0bf528SMauro Carvalho Chehab 
559a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
569a0bf528SMauro Carvalho Chehab 
579a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
589a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
599a0bf528SMauro Carvalho Chehab 
609a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83  165
619a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93  250
629a0bf528SMauro Carvalho Chehab 
639a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
649a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
659a0bf528SMauro Carvalho Chehab #endif
669a0bf528SMauro Carvalho Chehab 
679a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
689a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
699a0bf528SMauro Carvalho Chehab #endif
709a0bf528SMauro Carvalho Chehab 
719a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
729a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
739a0bf528SMauro Carvalho Chehab 
749a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
759a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV   4
769a0bf528SMauro Carvalho Chehab #endif
779a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
789a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV   6
799a0bf528SMauro Carvalho Chehab #endif
809a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
819a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV   7
829a0bf528SMauro Carvalho Chehab #endif
839a0bf528SMauro Carvalho Chehab 
849a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
859a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM   3
869a0bf528SMauro Carvalho Chehab #endif
879a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
889a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM   4
899a0bf528SMauro Carvalho Chehab #endif
909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
919a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM   7
929a0bf528SMauro Carvalho Chehab #endif
939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
949a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
959a0bf528SMauro Carvalho Chehab #endif
969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
979a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
989a0bf528SMauro Carvalho Chehab #endif
999a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1009a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
1019a0bf528SMauro Carvalho Chehab #endif
1029a0bf528SMauro Carvalho Chehab 
1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1049a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1059a0bf528SMauro Carvalho Chehab #endif
1069a0bf528SMauro Carvalho Chehab 
1079a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1089a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
1099a0bf528SMauro Carvalho Chehab #endif
1109a0bf528SMauro Carvalho Chehab 
1119a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1129a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
1139a0bf528SMauro Carvalho Chehab #endif
1149a0bf528SMauro Carvalho Chehab 
1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1169a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
1179a0bf528SMauro Carvalho Chehab #endif
1189a0bf528SMauro Carvalho Chehab 
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1209a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab 
1239a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
1249a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
1259a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
1269a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG      24
1279a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
1289a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
1299a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM      48
1309a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE        0
1319a0bf528SMauro Carvalho Chehab 
1329a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT                100
1339a0bf528SMauro Carvalho Chehab 
1349a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS      2
1359a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE     6
1369a0bf528SMauro Carvalho Chehab 
1379a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS      28
1389a0bf528SMauro Carvalho Chehab 
1399a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1409a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
1419a0bf528SMauro Carvalho Chehab #endif
1429a0bf528SMauro Carvalho Chehab 
1439a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
1449a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
1459a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
1469a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
1479a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
1489a0bf528SMauro Carvalho Chehab 
1499a0bf528SMauro Carvalho Chehab static unsigned int debug;
1509a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1519a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1529a0bf528SMauro Carvalho Chehab 
1539a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do {				\
1549a0bf528SMauro Carvalho Chehab if (debug >= level)							\
15552ee29feSMauro Carvalho Chehab 	printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg);	\
1569a0bf528SMauro Carvalho Chehab } while (0)
1579a0bf528SMauro Carvalho Chehab 
Frac28a(u32 a,u32 c)158ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c)
1599a0bf528SMauro Carvalho Chehab {
1609a0bf528SMauro Carvalho Chehab 	int i = 0;
1619a0bf528SMauro Carvalho Chehab 	u32 Q1 = 0;
1629a0bf528SMauro Carvalho Chehab 	u32 R0 = 0;
1639a0bf528SMauro Carvalho Chehab 
1649a0bf528SMauro Carvalho Chehab 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
165ab5060cdSMauro Carvalho Chehab 	Q1 = a / c;		/*
166ab5060cdSMauro Carvalho Chehab 				 * integer part, only the 4 least significant
167ab5060cdSMauro Carvalho Chehab 				 * bits will be visible in the result
168ab5060cdSMauro Carvalho Chehab 				 */
1699a0bf528SMauro Carvalho Chehab 
1709a0bf528SMauro Carvalho Chehab 	/* division using radix 16, 7 nibbles in the result */
1719a0bf528SMauro Carvalho Chehab 	for (i = 0; i < 7; i++) {
1729a0bf528SMauro Carvalho Chehab 		Q1 = (Q1 << 4) | (R0 / c);
1739a0bf528SMauro Carvalho Chehab 		R0 = (R0 % c) << 4;
1749a0bf528SMauro Carvalho Chehab 	}
1759a0bf528SMauro Carvalho Chehab 	/* rounding */
1769a0bf528SMauro Carvalho Chehab 	if ((R0 >> 3) >= c)
1779a0bf528SMauro Carvalho Chehab 		Q1++;
1789a0bf528SMauro Carvalho Chehab 
1799a0bf528SMauro Carvalho Chehab 	return Q1;
1809a0bf528SMauro Carvalho Chehab }
1819a0bf528SMauro Carvalho Chehab 
log10times100(u32 value)182b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value)
1839a0bf528SMauro Carvalho Chehab {
184b5e9eb6fSMauro Carvalho Chehab 	return (100L * intlog10(value)) >> 24;
1859a0bf528SMauro Carvalho Chehab }
1869a0bf528SMauro Carvalho Chehab 
18734eb9751SMauro Carvalho Chehab /***************************************************************************/
1889a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
18934eb9751SMauro Carvalho Chehab /***************************************************************************/
1909a0bf528SMauro Carvalho Chehab 
drxk_i2c_lock(struct drxk_state * state)1919a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
1929a0bf528SMauro Carvalho Chehab {
193c060a9feSPeter Rosin 	i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
1949a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = true;
1959a0bf528SMauro Carvalho Chehab 
1969a0bf528SMauro Carvalho Chehab 	return 0;
1979a0bf528SMauro Carvalho Chehab }
1989a0bf528SMauro Carvalho Chehab 
drxk_i2c_unlock(struct drxk_state * state)1999a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
2009a0bf528SMauro Carvalho Chehab {
2019a0bf528SMauro Carvalho Chehab 	if (!state->drxk_i2c_exclusive_lock)
2029a0bf528SMauro Carvalho Chehab 		return;
2039a0bf528SMauro Carvalho Chehab 
204c060a9feSPeter Rosin 	i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
2059a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = false;
2069a0bf528SMauro Carvalho Chehab }
2079a0bf528SMauro Carvalho Chehab 
drxk_i2c_transfer(struct drxk_state * state,struct i2c_msg * msgs,unsigned len)2089a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
2099a0bf528SMauro Carvalho Chehab 			     unsigned len)
2109a0bf528SMauro Carvalho Chehab {
2119a0bf528SMauro Carvalho Chehab 	if (state->drxk_i2c_exclusive_lock)
2129a0bf528SMauro Carvalho Chehab 		return __i2c_transfer(state->i2c, msgs, len);
2139a0bf528SMauro Carvalho Chehab 	else
2149a0bf528SMauro Carvalho Chehab 		return i2c_transfer(state->i2c, msgs, len);
2159a0bf528SMauro Carvalho Chehab }
2169a0bf528SMauro Carvalho Chehab 
i2c_read1(struct drxk_state * state,u8 adr,u8 * val)2179a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
2189a0bf528SMauro Carvalho Chehab {
2199a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
2209a0bf528SMauro Carvalho Chehab 				    .buf = val, .len = 1}
2219a0bf528SMauro Carvalho Chehab 	};
2229a0bf528SMauro Carvalho Chehab 
2239a0bf528SMauro Carvalho Chehab 	return drxk_i2c_transfer(state, msgs, 1);
2249a0bf528SMauro Carvalho Chehab }
2259a0bf528SMauro Carvalho Chehab 
i2c_write(struct drxk_state * state,u8 adr,u8 * data,int len)2269a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
2279a0bf528SMauro Carvalho Chehab {
2289a0bf528SMauro Carvalho Chehab 	int status;
2299a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg = {
2309a0bf528SMauro Carvalho Chehab 	    .addr = adr, .flags = 0, .buf = data, .len = len };
2319a0bf528SMauro Carvalho Chehab 
23278e9ab0fSAndy Shevchenko 	dprintk(3, ": %*ph\n", len, data);
23378e9ab0fSAndy Shevchenko 
2349a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, &msg, 1);
2359a0bf528SMauro Carvalho Chehab 	if (status >= 0 && status != 1)
2369a0bf528SMauro Carvalho Chehab 		status = -EIO;
2379a0bf528SMauro Carvalho Chehab 
2389a0bf528SMauro Carvalho Chehab 	if (status < 0)
2393a4398f5SMauro Carvalho Chehab 		pr_err("i2c write error at addr 0x%02x\n", adr);
2409a0bf528SMauro Carvalho Chehab 
2419a0bf528SMauro Carvalho Chehab 	return status;
2429a0bf528SMauro Carvalho Chehab }
2439a0bf528SMauro Carvalho Chehab 
i2c_read(struct drxk_state * state,u8 adr,u8 * msg,int len,u8 * answ,int alen)2449a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
2459a0bf528SMauro Carvalho Chehab 		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
2469a0bf528SMauro Carvalho Chehab {
2479a0bf528SMauro Carvalho Chehab 	int status;
2489a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[2] = {
2499a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = 0,
2509a0bf528SMauro Carvalho Chehab 				    .buf = msg, .len = len},
2519a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = I2C_M_RD,
2529a0bf528SMauro Carvalho Chehab 		 .buf = answ, .len = alen}
2539a0bf528SMauro Carvalho Chehab 	};
2549a0bf528SMauro Carvalho Chehab 
2559a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, msgs, 2);
2569a0bf528SMauro Carvalho Chehab 	if (status != 2) {
2579a0bf528SMauro Carvalho Chehab 		if (debug > 2)
2580fb220f2SMauro Carvalho Chehab 			pr_cont(": ERROR!\n");
2599a0bf528SMauro Carvalho Chehab 		if (status >= 0)
2609a0bf528SMauro Carvalho Chehab 			status = -EIO;
2619a0bf528SMauro Carvalho Chehab 
2623a4398f5SMauro Carvalho Chehab 		pr_err("i2c read error at addr 0x%02x\n", adr);
2639a0bf528SMauro Carvalho Chehab 		return status;
2649a0bf528SMauro Carvalho Chehab 	}
26578e9ab0fSAndy Shevchenko 	dprintk(3, ": read from %*ph, value = %*ph\n", len, msg, alen, answ);
2669a0bf528SMauro Carvalho Chehab 	return 0;
2679a0bf528SMauro Carvalho Chehab }
2689a0bf528SMauro Carvalho Chehab 
read16_flags(struct drxk_state * state,u32 reg,u16 * data,u8 flags)2699a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
2709a0bf528SMauro Carvalho Chehab {
2719a0bf528SMauro Carvalho Chehab 	int status;
2729a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[2], len;
2739a0bf528SMauro Carvalho Chehab 
2749a0bf528SMauro Carvalho Chehab 	if (state->single_master)
2759a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
2769a0bf528SMauro Carvalho Chehab 
2779a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
2789a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
2799a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
2809a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
2819a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
2829a0bf528SMauro Carvalho Chehab 		len = 4;
2839a0bf528SMauro Carvalho Chehab 	} else {
2849a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
2859a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
2869a0bf528SMauro Carvalho Chehab 		len = 2;
2879a0bf528SMauro Carvalho Chehab 	}
2889a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
2899a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 2);
2909a0bf528SMauro Carvalho Chehab 	if (status < 0)
2919a0bf528SMauro Carvalho Chehab 		return status;
2929a0bf528SMauro Carvalho Chehab 	if (data)
2939a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8);
2949a0bf528SMauro Carvalho Chehab 
2959a0bf528SMauro Carvalho Chehab 	return 0;
2969a0bf528SMauro Carvalho Chehab }
2979a0bf528SMauro Carvalho Chehab 
read16(struct drxk_state * state,u32 reg,u16 * data)2989a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
2999a0bf528SMauro Carvalho Chehab {
3009a0bf528SMauro Carvalho Chehab 	return read16_flags(state, reg, data, 0);
3019a0bf528SMauro Carvalho Chehab }
3029a0bf528SMauro Carvalho Chehab 
read32_flags(struct drxk_state * state,u32 reg,u32 * data,u8 flags)3039a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
3049a0bf528SMauro Carvalho Chehab {
3059a0bf528SMauro Carvalho Chehab 	int status;
3069a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[4], len;
3079a0bf528SMauro Carvalho Chehab 
3089a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3099a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3109a0bf528SMauro Carvalho Chehab 
3119a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3129a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3139a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3149a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3159a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3169a0bf528SMauro Carvalho Chehab 		len = 4;
3179a0bf528SMauro Carvalho Chehab 	} else {
3189a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3199a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3209a0bf528SMauro Carvalho Chehab 		len = 2;
3219a0bf528SMauro Carvalho Chehab 	}
3229a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3239a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 4);
3249a0bf528SMauro Carvalho Chehab 	if (status < 0)
3259a0bf528SMauro Carvalho Chehab 		return status;
3269a0bf528SMauro Carvalho Chehab 	if (data)
3279a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8) |
3289a0bf528SMauro Carvalho Chehab 		    (mm2[2] << 16) | (mm2[3] << 24);
3299a0bf528SMauro Carvalho Chehab 
3309a0bf528SMauro Carvalho Chehab 	return 0;
3319a0bf528SMauro Carvalho Chehab }
3329a0bf528SMauro Carvalho Chehab 
read32(struct drxk_state * state,u32 reg,u32 * data)3339a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
3349a0bf528SMauro Carvalho Chehab {
3359a0bf528SMauro Carvalho Chehab 	return read32_flags(state, reg, data, 0);
3369a0bf528SMauro Carvalho Chehab }
3379a0bf528SMauro Carvalho Chehab 
write16_flags(struct drxk_state * state,u32 reg,u16 data,u8 flags)3389a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
3399a0bf528SMauro Carvalho Chehab {
3409a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[6], len;
3419a0bf528SMauro Carvalho Chehab 
3429a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3439a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3449a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3459a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3469a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3479a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3489a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3499a0bf528SMauro Carvalho Chehab 		len = 4;
3509a0bf528SMauro Carvalho Chehab 	} else {
3519a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3529a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3539a0bf528SMauro Carvalho Chehab 		len = 2;
3549a0bf528SMauro Carvalho Chehab 	}
3559a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3569a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
3579a0bf528SMauro Carvalho Chehab 
3589a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
3599a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 2);
3609a0bf528SMauro Carvalho Chehab }
3619a0bf528SMauro Carvalho Chehab 
write16(struct drxk_state * state,u32 reg,u16 data)3629a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
3639a0bf528SMauro Carvalho Chehab {
3649a0bf528SMauro Carvalho Chehab 	return write16_flags(state, reg, data, 0);
3659a0bf528SMauro Carvalho Chehab }
3669a0bf528SMauro Carvalho Chehab 
write32_flags(struct drxk_state * state,u32 reg,u32 data,u8 flags)3679a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
3689a0bf528SMauro Carvalho Chehab {
3699a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[8], len;
3709a0bf528SMauro Carvalho Chehab 
3719a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3729a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3739a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3749a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3759a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3769a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3779a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3789a0bf528SMauro Carvalho Chehab 		len = 4;
3799a0bf528SMauro Carvalho Chehab 	} else {
3809a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3819a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3829a0bf528SMauro Carvalho Chehab 		len = 2;
3839a0bf528SMauro Carvalho Chehab 	}
3849a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3859a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
3869a0bf528SMauro Carvalho Chehab 	mm[len + 2] = (data >> 16) & 0xff;
3879a0bf528SMauro Carvalho Chehab 	mm[len + 3] = (data >> 24) & 0xff;
3889a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
3899a0bf528SMauro Carvalho Chehab 
3909a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 4);
3919a0bf528SMauro Carvalho Chehab }
3929a0bf528SMauro Carvalho Chehab 
write32(struct drxk_state * state,u32 reg,u32 data)3939a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
3949a0bf528SMauro Carvalho Chehab {
3959a0bf528SMauro Carvalho Chehab 	return write32_flags(state, reg, data, 0);
3969a0bf528SMauro Carvalho Chehab }
3979a0bf528SMauro Carvalho Chehab 
write_block(struct drxk_state * state,u32 address,const int block_size,const u8 p_block[])398cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address,
399cd7a67a4SMauro Carvalho Chehab 		      const int block_size, const u8 p_block[])
4009a0bf528SMauro Carvalho Chehab {
401cd7a67a4SMauro Carvalho Chehab 	int status = 0, blk_size = block_size;
402cd7a67a4SMauro Carvalho Chehab 	u8 flags = 0;
4039a0bf528SMauro Carvalho Chehab 
4049a0bf528SMauro Carvalho Chehab 	if (state->single_master)
405cd7a67a4SMauro Carvalho Chehab 		flags |= 0xC0;
4069a0bf528SMauro Carvalho Chehab 
407cd7a67a4SMauro Carvalho Chehab 	while (blk_size > 0) {
408cd7a67a4SMauro Carvalho Chehab 		int chunk = blk_size > state->m_chunk_size ?
409cd7a67a4SMauro Carvalho Chehab 		    state->m_chunk_size : blk_size;
410cd7a67a4SMauro Carvalho Chehab 		u8 *adr_buf = &state->chunk[0];
411cd7a67a4SMauro Carvalho Chehab 		u32 adr_length = 0;
4129a0bf528SMauro Carvalho Chehab 
413cd7a67a4SMauro Carvalho Chehab 		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
414cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
415cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = ((address >> 16) & 0xFF);
416cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] = ((address >> 24) & 0xFF);
417cd7a67a4SMauro Carvalho Chehab 			adr_buf[3] = ((address >> 7) & 0xFF);
418cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] |= flags;
419cd7a67a4SMauro Carvalho Chehab 			adr_length = 4;
420cd7a67a4SMauro Carvalho Chehab 			if (chunk == state->m_chunk_size)
421cd7a67a4SMauro Carvalho Chehab 				chunk -= 2;
4229a0bf528SMauro Carvalho Chehab 		} else {
423cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = ((address << 1) & 0xFF);
424cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = (((address >> 16) & 0x0F) |
425cd7a67a4SMauro Carvalho Chehab 				     ((address >> 18) & 0xF0));
426cd7a67a4SMauro Carvalho Chehab 			adr_length = 2;
4279a0bf528SMauro Carvalho Chehab 		}
428cd7a67a4SMauro Carvalho Chehab 		memcpy(&state->chunk[adr_length], p_block, chunk);
429cd7a67a4SMauro Carvalho Chehab 		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
430cd7a67a4SMauro Carvalho Chehab 		if (p_block)
43178e9ab0fSAndy Shevchenko 			dprintk(2, "%*ph\n", chunk, p_block);
4329a0bf528SMauro Carvalho Chehab 		status = i2c_write(state, state->demod_address,
433cd7a67a4SMauro Carvalho Chehab 				   &state->chunk[0], chunk + adr_length);
4349a0bf528SMauro Carvalho Chehab 		if (status < 0) {
4353a4398f5SMauro Carvalho Chehab 			pr_err("%s: i2c write error at addr 0x%02x\n",
436cd7a67a4SMauro Carvalho Chehab 			       __func__, address);
4379a0bf528SMauro Carvalho Chehab 			break;
4389a0bf528SMauro Carvalho Chehab 		}
439cd7a67a4SMauro Carvalho Chehab 		p_block += chunk;
440cd7a67a4SMauro Carvalho Chehab 		address += (chunk >> 1);
441cd7a67a4SMauro Carvalho Chehab 		blk_size -= chunk;
4429a0bf528SMauro Carvalho Chehab 	}
4439a0bf528SMauro Carvalho Chehab 	return status;
4449a0bf528SMauro Carvalho Chehab }
4459a0bf528SMauro Carvalho Chehab 
4469a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
4479a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
4489a0bf528SMauro Carvalho Chehab #endif
4499a0bf528SMauro Carvalho Chehab 
power_up_device(struct drxk_state * state)450cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state)
4519a0bf528SMauro Carvalho Chehab {
4529a0bf528SMauro Carvalho Chehab 	int status;
4539a0bf528SMauro Carvalho Chehab 	u8 data = 0;
454cd7a67a4SMauro Carvalho Chehab 	u16 retry_count = 0;
4559a0bf528SMauro Carvalho Chehab 
4569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4579a0bf528SMauro Carvalho Chehab 
4589a0bf528SMauro Carvalho Chehab 	status = i2c_read1(state, state->demod_address, &data);
4599a0bf528SMauro Carvalho Chehab 	if (status < 0) {
4609a0bf528SMauro Carvalho Chehab 		do {
4619a0bf528SMauro Carvalho Chehab 			data = 0;
4629a0bf528SMauro Carvalho Chehab 			status = i2c_write(state, state->demod_address,
4639a0bf528SMauro Carvalho Chehab 					   &data, 1);
464b72852baSMauro Carvalho Chehab 			usleep_range(10000, 11000);
465cd7a67a4SMauro Carvalho Chehab 			retry_count++;
4669a0bf528SMauro Carvalho Chehab 			if (status < 0)
4679a0bf528SMauro Carvalho Chehab 				continue;
4689a0bf528SMauro Carvalho Chehab 			status = i2c_read1(state, state->demod_address,
4699a0bf528SMauro Carvalho Chehab 					   &data);
4709a0bf528SMauro Carvalho Chehab 		} while (status < 0 &&
471cd7a67a4SMauro Carvalho Chehab 			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
472cd7a67a4SMauro Carvalho Chehab 		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
4739a0bf528SMauro Carvalho Chehab 			goto error;
4749a0bf528SMauro Carvalho Chehab 	}
4759a0bf528SMauro Carvalho Chehab 
4769a0bf528SMauro Carvalho Chehab 	/* Make sure all clk domains are active */
4779a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
4789a0bf528SMauro Carvalho Chehab 	if (status < 0)
4799a0bf528SMauro Carvalho Chehab 		goto error;
4809a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
4819a0bf528SMauro Carvalho Chehab 	if (status < 0)
4829a0bf528SMauro Carvalho Chehab 		goto error;
4839a0bf528SMauro Carvalho Chehab 	/* Enable pll lock tests */
4849a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PLL_LOCK__A, 1);
4859a0bf528SMauro Carvalho Chehab 	if (status < 0)
4869a0bf528SMauro Carvalho Chehab 		goto error;
4879a0bf528SMauro Carvalho Chehab 
488cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_UP;
4899a0bf528SMauro Carvalho Chehab 
4909a0bf528SMauro Carvalho Chehab error:
4919a0bf528SMauro Carvalho Chehab 	if (status < 0)
4923a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
4939a0bf528SMauro Carvalho Chehab 
4949a0bf528SMauro Carvalho Chehab 	return status;
4959a0bf528SMauro Carvalho Chehab }
4969a0bf528SMauro Carvalho Chehab 
4979a0bf528SMauro Carvalho Chehab 
init_state(struct drxk_state * state)4989a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
4999a0bf528SMauro Carvalho Chehab {
5009a0bf528SMauro Carvalho Chehab 	/*
5015a13e40bSMauro Carvalho Chehab 	 * FIXME: most (all?) of the values below should be moved into
5029a0bf528SMauro Carvalho Chehab 	 * struct drxk_config, as they are probably board-specific
5039a0bf528SMauro Carvalho Chehab 	 */
504cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
505cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_output_level = 0;
506cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_min_level = 0;
507cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_max_level = 0x7FFF;
508cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_speed = 3;
5099a0bf528SMauro Carvalho Chehab 
510cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
511cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_output_level = 0;
512cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_min_level = 0;
513cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
514cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_speed = 3;
515cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_top = 9500;
516cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_cut_off_current = 4000;
5179a0bf528SMauro Carvalho Chehab 
518cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
519cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_output_level = 0;
520cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_min_level = 0;
521cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_max_level = 0;
522cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_speed = 3;
5239a0bf528SMauro Carvalho Chehab 
524cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
525cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_output_level = 0;
526cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_min_level = 0;
527cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_max_level = 0;
528cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_top = 9500;
529cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_cut_off_current = 4000;
530cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_speed = 3;
5319a0bf528SMauro Carvalho Chehab 
5329a0bf528SMauro Carvalho Chehab 	u32 ulQual83 = DEFAULT_MER_83;
5339a0bf528SMauro Carvalho Chehab 	u32 ulQual93 = DEFAULT_MER_93;
5349a0bf528SMauro Carvalho Chehab 
535cd7a67a4SMauro Carvalho Chehab 	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
536cd7a67a4SMauro Carvalho Chehab 	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
5379a0bf528SMauro Carvalho Chehab 
5389a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
5399a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_mode output mode is drive always */
5409a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
541cd7a67a4SMauro Carvalho Chehab 	u32 ul_gpio_cfg = 0x0113;
542cd7a67a4SMauro Carvalho Chehab 	u32 ul_invert_ts_clock = 0;
543cd7a67a4SMauro Carvalho Chehab 	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
544cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbt_bitrate = 50000000;
545cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
5469a0bf528SMauro Carvalho Chehab 
547cd7a67a4SMauro Carvalho Chehab 	u32 ul_insert_rs_byte = 0;
5489a0bf528SMauro Carvalho Chehab 
549cd7a67a4SMauro Carvalho Chehab 	u32 ul_rf_mirror = 1;
550cd7a67a4SMauro Carvalho Chehab 	u32 ul_power_down = 0;
5519a0bf528SMauro Carvalho Chehab 
5529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5539a0bf528SMauro Carvalho Chehab 
554cd7a67a4SMauro Carvalho Chehab 	state->m_has_lna = false;
555cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbt = false;
556cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbc = false;
557cd7a67a4SMauro Carvalho Chehab 	state->m_has_atv = false;
558cd7a67a4SMauro Carvalho Chehab 	state->m_has_oob = false;
559cd7a67a4SMauro Carvalho Chehab 	state->m_has_audio = false;
5609a0bf528SMauro Carvalho Chehab 
561cd7a67a4SMauro Carvalho Chehab 	if (!state->m_chunk_size)
562cd7a67a4SMauro Carvalho Chehab 		state->m_chunk_size = 124;
5639a0bf528SMauro Carvalho Chehab 
564cd7a67a4SMauro Carvalho Chehab 	state->m_osc_clock_freq = 0;
565cd7a67a4SMauro Carvalho Chehab 	state->m_smart_ant_inverted = false;
566cd7a67a4SMauro Carvalho Chehab 	state->m_b_p_down_open_bridge = false;
5679a0bf528SMauro Carvalho Chehab 
5689a0bf528SMauro Carvalho Chehab 	/* real system clock frequency in kHz */
569cd7a67a4SMauro Carvalho Chehab 	state->m_sys_clock_freq = 151875;
5709a0bf528SMauro Carvalho Chehab 	/* Timing div, 250ns/Psys */
5719a0bf528SMauro Carvalho Chehab 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
572cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
5739a0bf528SMauro Carvalho Chehab 				   HI_I2C_DELAY) / 1000;
5749a0bf528SMauro Carvalho Chehab 	/* Clipping */
575cd7a67a4SMauro Carvalho Chehab 	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
576cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
577cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
5789a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
579cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
5809a0bf528SMauro Carvalho Chehab 
581cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = (ul_power_down != 0);
5829a0bf528SMauro Carvalho Chehab 
583cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_a3_patch_code = false;
5849a0bf528SMauro Carvalho Chehab 
5859a0bf528SMauro Carvalho Chehab 	/* Init AGC and PGA parameters */
5869a0bf528SMauro Carvalho Chehab 	/* VSB IF */
587949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
588949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
589949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
590949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
591949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
592cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pga_cfg = 140;
5939a0bf528SMauro Carvalho Chehab 
5949a0bf528SMauro Carvalho Chehab 	/* VSB RF */
595949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
596949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
597949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
598949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
599949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
600949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
601949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
602cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.reference = 0x07;
603cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
6049a0bf528SMauro Carvalho Chehab 
6059a0bf528SMauro Carvalho Chehab 	state->m_Quality83percent = DEFAULT_MER_83;
6069a0bf528SMauro Carvalho Chehab 	state->m_Quality93percent = DEFAULT_MER_93;
6079a0bf528SMauro Carvalho Chehab 	if (ulQual93 <= 500 && ulQual83 < ulQual93) {
6089a0bf528SMauro Carvalho Chehab 		state->m_Quality83percent = ulQual83;
6099a0bf528SMauro Carvalho Chehab 		state->m_Quality93percent = ulQual93;
6109a0bf528SMauro Carvalho Chehab 	}
6119a0bf528SMauro Carvalho Chehab 
6129a0bf528SMauro Carvalho Chehab 	/* ATV IF */
613949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
614949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
615949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
616949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
617949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
6189a0bf528SMauro Carvalho Chehab 
6199a0bf528SMauro Carvalho Chehab 	/* ATV RF */
620949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
621949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
622949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
623949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
624949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
625949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
626949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
627cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.reference = 0x04;
628cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.use_pre_saw = true;
6299a0bf528SMauro Carvalho Chehab 
6309a0bf528SMauro Carvalho Chehab 
6319a0bf528SMauro Carvalho Chehab 	/* DVBT RF */
632cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
633cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.output_level = 0;
634cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
635cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
636cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.top = 0x2100;
637cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
638cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.speed = 1;
6399a0bf528SMauro Carvalho Chehab 
6409a0bf528SMauro Carvalho Chehab 
6419a0bf528SMauro Carvalho Chehab 	/* DVBT IF */
642cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
643cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.output_level = 0;
644cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.min_output_level = 0;
645cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
646cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.top = 13424;
647cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
648cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.speed = 3;
649cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
650cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
6519a0bf528SMauro Carvalho Chehab 	/* state->m_dvbtPgaCfg = 140; */
6529a0bf528SMauro Carvalho Chehab 
653cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.reference = 4;
654cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
6559a0bf528SMauro Carvalho Chehab 
6569a0bf528SMauro Carvalho Chehab 	/* QAM RF */
657cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
658cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.output_level = 0;
659cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.min_output_level = 6023;
660cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.max_output_level = 27000;
661cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.top = 0x2380;
662cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
663cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.speed = 3;
6649a0bf528SMauro Carvalho Chehab 
6659a0bf528SMauro Carvalho Chehab 	/* QAM IF */
666cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
667cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.output_level = 0;
668cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.min_output_level = 0;
669cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.max_output_level = 9000;
670cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.top = 0x0511;
671cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.cut_off_current = 0;
672cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.speed = 3;
673cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
674cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
6759a0bf528SMauro Carvalho Chehab 
676cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pga_cfg = 140;
677cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.reference = 4;
678cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.use_pre_saw = false;
6799a0bf528SMauro Carvalho Chehab 
680cd7a67a4SMauro Carvalho Chehab 	state->m_operation_mode = OM_NONE;
681cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_state = DRXK_UNINITIALIZED;
6829a0bf528SMauro Carvalho Chehab 
6839a0bf528SMauro Carvalho Chehab 	/* MPEG output configuration */
684868c9a17SMauro Carvalho Chehab 	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG output */
685cd7a67a4SMauro Carvalho Chehab 	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
686cd7a67a4SMauro Carvalho Chehab 	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
687cd7a67a4SMauro Carvalho Chehab 	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
688cd7a67a4SMauro Carvalho Chehab 	state->m_invert_str = false;	/* If TRUE; invert STR signals */
689cd7a67a4SMauro Carvalho Chehab 	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
690cd7a67a4SMauro Carvalho Chehab 	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
6919a0bf528SMauro Carvalho Chehab 
6929a0bf528SMauro Carvalho Chehab 	/* If TRUE; static MPEG clockrate will be used;
6939a0bf528SMauro Carvalho Chehab 	   otherwise clockrate will adapt to the bitrate of the TS */
6949a0bf528SMauro Carvalho Chehab 
695cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_bitrate = ul_dvbt_bitrate;
696cd7a67a4SMauro Carvalho Chehab 	state->m_dvbc_bitrate = ul_dvbc_bitrate;
6979a0bf528SMauro Carvalho Chehab 
698cd7a67a4SMauro Carvalho Chehab 	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
6999a0bf528SMauro Carvalho Chehab 
7009a0bf528SMauro Carvalho Chehab 	/* Maximum bitrate in b/s in case static clockrate is selected */
701cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_ts_static_bitrate = 19392658;
702cd7a67a4SMauro Carvalho Chehab 	state->m_disable_te_ihandling = false;
7039a0bf528SMauro Carvalho Chehab 
704cd7a67a4SMauro Carvalho Chehab 	if (ul_insert_rs_byte)
705cd7a67a4SMauro Carvalho Chehab 		state->m_insert_rs_byte = true;
7069a0bf528SMauro Carvalho Chehab 
707cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
708cd7a67a4SMauro Carvalho Chehab 	if (ul_mpeg_lock_time_out < 10000)
709cd7a67a4SMauro Carvalho Chehab 		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
710cd7a67a4SMauro Carvalho Chehab 	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
711cd7a67a4SMauro Carvalho Chehab 	if (ul_demod_lock_time_out < 10000)
712cd7a67a4SMauro Carvalho Chehab 		state->m_demod_lock_time_out = ul_demod_lock_time_out;
7139a0bf528SMauro Carvalho Chehab 
7149a0bf528SMauro Carvalho Chehab 	/* QAM defaults */
715cd7a67a4SMauro Carvalho Chehab 	state->m_constellation = DRX_CONSTELLATION_AUTO;
716cd7a67a4SMauro Carvalho Chehab 	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
717cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
718cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_prescale = 1;
7199a0bf528SMauro Carvalho Chehab 
720cd7a67a4SMauro Carvalho Chehab 	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
721cd7a67a4SMauro Carvalho Chehab 	state->m_agcfast_clip_ctrl_delay = 0;
7229a0bf528SMauro Carvalho Chehab 
723949dd08dSMauro Carvalho Chehab 	state->m_gpio_cfg = ul_gpio_cfg;
7249a0bf528SMauro Carvalho Chehab 
725cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = false;
726cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_DOWN;
7279a0bf528SMauro Carvalho Chehab 
728cd7a67a4SMauro Carvalho Chehab 	state->m_rfmirror = (ul_rf_mirror == 0);
729cd7a67a4SMauro Carvalho Chehab 	state->m_if_agc_pol = false;
7309a0bf528SMauro Carvalho Chehab 	return 0;
7319a0bf528SMauro Carvalho Chehab }
7329a0bf528SMauro Carvalho Chehab 
drxx_open(struct drxk_state * state)733cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state)
7349a0bf528SMauro Carvalho Chehab {
7359a0bf528SMauro Carvalho Chehab 	int status = 0;
7369a0bf528SMauro Carvalho Chehab 	u32 jtag = 0;
7379a0bf528SMauro Carvalho Chehab 	u16 bid = 0;
7389a0bf528SMauro Carvalho Chehab 	u16 key = 0;
7399a0bf528SMauro Carvalho Chehab 
7409a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7419a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
742ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
743ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7449a0bf528SMauro Carvalho Chehab 	if (status < 0)
7459a0bf528SMauro Carvalho Chehab 		goto error;
7469a0bf528SMauro Carvalho Chehab 	/* Check device id */
7479a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_TOP_COMM_KEY__A, &key);
7489a0bf528SMauro Carvalho Chehab 	if (status < 0)
7499a0bf528SMauro Carvalho Chehab 		goto error;
7509a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7519a0bf528SMauro Carvalho Chehab 	if (status < 0)
7529a0bf528SMauro Carvalho Chehab 		goto error;
7539a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
7549a0bf528SMauro Carvalho Chehab 	if (status < 0)
7559a0bf528SMauro Carvalho Chehab 		goto error;
7569a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
7579a0bf528SMauro Carvalho Chehab 	if (status < 0)
7589a0bf528SMauro Carvalho Chehab 		goto error;
7599a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
7609a0bf528SMauro Carvalho Chehab error:
7619a0bf528SMauro Carvalho Chehab 	if (status < 0)
7623a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
7639a0bf528SMauro Carvalho Chehab 	return status;
7649a0bf528SMauro Carvalho Chehab }
7659a0bf528SMauro Carvalho Chehab 
get_device_capabilities(struct drxk_state * state)766cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state)
7679a0bf528SMauro Carvalho Chehab {
768cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_ohw_cfg = 0;
769cd7a67a4SMauro Carvalho Chehab 	u32 sio_top_jtagid_lo = 0;
7709a0bf528SMauro Carvalho Chehab 	int status;
7719a0bf528SMauro Carvalho Chehab 	const char *spin = "";
7729a0bf528SMauro Carvalho Chehab 
7739a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7749a0bf528SMauro Carvalho Chehab 
7759a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
7769a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
777ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
778ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7799a0bf528SMauro Carvalho Chehab 	if (status < 0)
7809a0bf528SMauro Carvalho Chehab 		goto error;
7818418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7829a0bf528SMauro Carvalho Chehab 	if (status < 0)
7839a0bf528SMauro Carvalho Chehab 		goto error;
784cd7a67a4SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
7859a0bf528SMauro Carvalho Chehab 	if (status < 0)
7869a0bf528SMauro Carvalho Chehab 		goto error;
7879a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
7889a0bf528SMauro Carvalho Chehab 	if (status < 0)
7899a0bf528SMauro Carvalho Chehab 		goto error;
7909a0bf528SMauro Carvalho Chehab 
791cd7a67a4SMauro Carvalho Chehab 	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
7929a0bf528SMauro Carvalho Chehab 	case 0:
7939a0bf528SMauro Carvalho Chehab 		/* ignore (bypass ?) */
7949a0bf528SMauro Carvalho Chehab 		break;
7959a0bf528SMauro Carvalho Chehab 	case 1:
7969a0bf528SMauro Carvalho Chehab 		/* 27 MHz */
797cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 27000;
7989a0bf528SMauro Carvalho Chehab 		break;
7999a0bf528SMauro Carvalho Chehab 	case 2:
8009a0bf528SMauro Carvalho Chehab 		/* 20.25 MHz */
801cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8029a0bf528SMauro Carvalho Chehab 		break;
8039a0bf528SMauro Carvalho Chehab 	case 3:
8049a0bf528SMauro Carvalho Chehab 		/* 4 MHz */
805cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8069a0bf528SMauro Carvalho Chehab 		break;
8079a0bf528SMauro Carvalho Chehab 	default:
8083a4398f5SMauro Carvalho Chehab 		pr_err("Clock Frequency is unknown\n");
8099a0bf528SMauro Carvalho Chehab 		return -EINVAL;
8109a0bf528SMauro Carvalho Chehab 	}
8119a0bf528SMauro Carvalho Chehab 	/*
8129a0bf528SMauro Carvalho Chehab 		Determine device capabilities
8139a0bf528SMauro Carvalho Chehab 		Based on pinning v14
8149a0bf528SMauro Carvalho Chehab 		*/
815cd7a67a4SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
8169a0bf528SMauro Carvalho Chehab 	if (status < 0)
8179a0bf528SMauro Carvalho Chehab 		goto error;
8189a0bf528SMauro Carvalho Chehab 
8193a4398f5SMauro Carvalho Chehab 	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
8209a0bf528SMauro Carvalho Chehab 
8219a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
822cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
8239a0bf528SMauro Carvalho Chehab 	case 0:
824cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A1;
8259a0bf528SMauro Carvalho Chehab 		spin = "A1";
8269a0bf528SMauro Carvalho Chehab 		break;
8279a0bf528SMauro Carvalho Chehab 	case 2:
828cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A2;
8299a0bf528SMauro Carvalho Chehab 		spin = "A2";
8309a0bf528SMauro Carvalho Chehab 		break;
8319a0bf528SMauro Carvalho Chehab 	case 3:
832cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A3;
8339a0bf528SMauro Carvalho Chehab 		spin = "A3";
8349a0bf528SMauro Carvalho Chehab 		break;
8359a0bf528SMauro Carvalho Chehab 	default:
836cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_UNKNOWN;
8379a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
8383a4398f5SMauro Carvalho Chehab 		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
8399a0bf528SMauro Carvalho Chehab 		goto error2;
8409a0bf528SMauro Carvalho Chehab 	}
841cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
8429a0bf528SMauro Carvalho Chehab 	case 0x13:
8439a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3913K_TYPE_ID */
844cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
845cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
846cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = false;
847cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
848cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
849cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
850cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
851cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = false;
852cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = false;
853cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8549a0bf528SMauro Carvalho Chehab 		break;
8559a0bf528SMauro Carvalho Chehab 	case 0x15:
8569a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3915K_TYPE_ID */
857cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
858cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
859cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
860cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
861cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
862cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
863cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
864cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
865cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
866cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8679a0bf528SMauro Carvalho Chehab 		break;
8689a0bf528SMauro Carvalho Chehab 	case 0x16:
8699a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3916K_TYPE_ID */
870cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
871cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
872cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
873cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
874cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
875cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
876cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
877cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
878cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
879cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8809a0bf528SMauro Carvalho Chehab 		break;
8819a0bf528SMauro Carvalho Chehab 	case 0x18:
8829a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3918K_TYPE_ID */
883cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
884cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
885cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
886cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
887cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
888cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
889cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
890cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
891cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
892cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8939a0bf528SMauro Carvalho Chehab 		break;
8949a0bf528SMauro Carvalho Chehab 	case 0x21:
8959a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3921K_TYPE_ID */
896cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
897cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
898cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
899cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
900cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
901cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
902cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
903cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
904cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
905cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9069a0bf528SMauro Carvalho Chehab 		break;
9079a0bf528SMauro Carvalho Chehab 	case 0x23:
9089a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3923K_TYPE_ID */
909cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
910cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
911cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
912cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
913cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
914cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
915cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
916cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
917cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
918cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9199a0bf528SMauro Carvalho Chehab 		break;
9209a0bf528SMauro Carvalho Chehab 	case 0x25:
9219a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3925K_TYPE_ID */
922cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
923cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
924cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
925cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
926cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
927cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
928cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
929cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
930cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
931cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9329a0bf528SMauro Carvalho Chehab 		break;
9339a0bf528SMauro Carvalho Chehab 	case 0x26:
9349a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3926K_TYPE_ID */
935cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
936cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
937cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
938cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
939cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
940cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
941cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
942cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
943cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
944cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9459a0bf528SMauro Carvalho Chehab 		break;
9469a0bf528SMauro Carvalho Chehab 	default:
9473a4398f5SMauro Carvalho Chehab 		pr_err("DeviceID 0x%02x not supported\n",
948cd7a67a4SMauro Carvalho Chehab 			((sio_top_jtagid_lo >> 12) & 0xFF));
9499a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
9509a0bf528SMauro Carvalho Chehab 		goto error2;
9519a0bf528SMauro Carvalho Chehab 	}
9529a0bf528SMauro Carvalho Chehab 
9533a4398f5SMauro Carvalho Chehab 	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
954cd7a67a4SMauro Carvalho Chehab 	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
955cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq / 1000,
956cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq % 1000);
9579a0bf528SMauro Carvalho Chehab 
9589a0bf528SMauro Carvalho Chehab error:
9599a0bf528SMauro Carvalho Chehab 	if (status < 0)
9603a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
9619a0bf528SMauro Carvalho Chehab 
9629a0bf528SMauro Carvalho Chehab error2:
9639a0bf528SMauro Carvalho Chehab 	return status;
9649a0bf528SMauro Carvalho Chehab }
9659a0bf528SMauro Carvalho Chehab 
hi_command(struct drxk_state * state,u16 cmd,u16 * p_result)966cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
9679a0bf528SMauro Carvalho Chehab {
9689a0bf528SMauro Carvalho Chehab 	int status;
9699a0bf528SMauro Carvalho Chehab 	bool powerdown_cmd;
9709a0bf528SMauro Carvalho Chehab 
9719a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
9729a0bf528SMauro Carvalho Chehab 
9739a0bf528SMauro Carvalho Chehab 	/* Write command */
9749a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
9759a0bf528SMauro Carvalho Chehab 	if (status < 0)
9769a0bf528SMauro Carvalho Chehab 		goto error;
9779a0bf528SMauro Carvalho Chehab 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
978b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
9799a0bf528SMauro Carvalho Chehab 
9809a0bf528SMauro Carvalho Chehab 	powerdown_cmd =
9819a0bf528SMauro Carvalho Chehab 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
982cd7a67a4SMauro Carvalho Chehab 		    ((state->m_hi_cfg_ctrl) &
9839a0bf528SMauro Carvalho Chehab 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
9849a0bf528SMauro Carvalho Chehab 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
9855a7f7b79SMauro Carvalho Chehab 	if (!powerdown_cmd) {
9869a0bf528SMauro Carvalho Chehab 		/* Wait until command rdy */
987cd7a67a4SMauro Carvalho Chehab 		u32 retry_count = 0;
988cd7a67a4SMauro Carvalho Chehab 		u16 wait_cmd;
9899a0bf528SMauro Carvalho Chehab 
9909a0bf528SMauro Carvalho Chehab 		do {
991b72852baSMauro Carvalho Chehab 			usleep_range(1000, 2000);
992cd7a67a4SMauro Carvalho Chehab 			retry_count += 1;
9939a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
994cd7a67a4SMauro Carvalho Chehab 					  &wait_cmd);
995c386e079SHans Verkuil 		} while ((status < 0 || wait_cmd) && (retry_count < DRXK_MAX_RETRIES));
9969a0bf528SMauro Carvalho Chehab 		if (status < 0)
9979a0bf528SMauro Carvalho Chehab 			goto error;
998cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
9999a0bf528SMauro Carvalho Chehab 	}
10009a0bf528SMauro Carvalho Chehab error:
10019a0bf528SMauro Carvalho Chehab 	if (status < 0)
10023a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10039a0bf528SMauro Carvalho Chehab 
10049a0bf528SMauro Carvalho Chehab 	return status;
10059a0bf528SMauro Carvalho Chehab }
10069a0bf528SMauro Carvalho Chehab 
hi_cfg_command(struct drxk_state * state)1007cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state)
10089a0bf528SMauro Carvalho Chehab {
10099a0bf528SMauro Carvalho Chehab 	int status;
10109a0bf528SMauro Carvalho Chehab 
10119a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10129a0bf528SMauro Carvalho Chehab 
10139a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
10149a0bf528SMauro Carvalho Chehab 
1015ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1016ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timeout);
10179a0bf528SMauro Carvalho Chehab 	if (status < 0)
10189a0bf528SMauro Carvalho Chehab 		goto error;
1019ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1020ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_ctrl);
10219a0bf528SMauro Carvalho Chehab 	if (status < 0)
10229a0bf528SMauro Carvalho Chehab 		goto error;
1023ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1024ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_wake_up_key);
10259a0bf528SMauro Carvalho Chehab 	if (status < 0)
10269a0bf528SMauro Carvalho Chehab 		goto error;
1027ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1028ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_bridge_delay);
10299a0bf528SMauro Carvalho Chehab 	if (status < 0)
10309a0bf528SMauro Carvalho Chehab 		goto error;
1031ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1032ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timing_div);
10339a0bf528SMauro Carvalho Chehab 	if (status < 0)
10349a0bf528SMauro Carvalho Chehab 		goto error;
1035ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1036ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
10379a0bf528SMauro Carvalho Chehab 	if (status < 0)
10389a0bf528SMauro Carvalho Chehab 		goto error;
1039b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
10409a0bf528SMauro Carvalho Chehab 	if (status < 0)
10419a0bf528SMauro Carvalho Chehab 		goto error;
10429a0bf528SMauro Carvalho Chehab 
1043cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
10449a0bf528SMauro Carvalho Chehab error:
10459a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
10469a0bf528SMauro Carvalho Chehab 	if (status < 0)
10473a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10489a0bf528SMauro Carvalho Chehab 	return status;
10499a0bf528SMauro Carvalho Chehab }
10509a0bf528SMauro Carvalho Chehab 
init_hi(struct drxk_state * state)1051cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state)
10529a0bf528SMauro Carvalho Chehab {
10539a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10549a0bf528SMauro Carvalho Chehab 
1055cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1056cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timeout = 0x96FF;
10579a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
1058cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
10599a0bf528SMauro Carvalho Chehab 
1060cd7a67a4SMauro Carvalho Chehab 	return hi_cfg_command(state);
10619a0bf528SMauro Carvalho Chehab }
10629a0bf528SMauro Carvalho Chehab 
mpegts_configure_pins(struct drxk_state * state,bool mpeg_enable)1063cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
10649a0bf528SMauro Carvalho Chehab {
106543c4dc3fSColin Ian King 	int status;
1066cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mclk_cfg = 0;
1067cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mdx_cfg = 0;
10689a0bf528SMauro Carvalho Chehab 	u16 err_cfg = 0;
10699a0bf528SMauro Carvalho Chehab 
10709a0bf528SMauro Carvalho Chehab 	dprintk(1, ": mpeg %s, %s mode\n",
1071cd7a67a4SMauro Carvalho Chehab 		mpeg_enable ? "enable" : "disable",
1072cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel ? "parallel" : "serial");
10739a0bf528SMauro Carvalho Chehab 
10749a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
1075ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1076ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
10779a0bf528SMauro Carvalho Chehab 	if (status < 0)
10789a0bf528SMauro Carvalho Chehab 		goto error;
10799a0bf528SMauro Carvalho Chehab 
10809a0bf528SMauro Carvalho Chehab 	/*  MPEG TS pad configuration */
10818418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
10829a0bf528SMauro Carvalho Chehab 	if (status < 0)
10839a0bf528SMauro Carvalho Chehab 		goto error;
10849a0bf528SMauro Carvalho Chehab 
10855a7f7b79SMauro Carvalho Chehab 	if (!mpeg_enable) {
10869a0bf528SMauro Carvalho Chehab 		/*  Set MPEG TS pads to inputmode */
10879a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
10889a0bf528SMauro Carvalho Chehab 		if (status < 0)
10899a0bf528SMauro Carvalho Chehab 			goto error;
10909a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
10919a0bf528SMauro Carvalho Chehab 		if (status < 0)
10929a0bf528SMauro Carvalho Chehab 			goto error;
10939a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
10949a0bf528SMauro Carvalho Chehab 		if (status < 0)
10959a0bf528SMauro Carvalho Chehab 			goto error;
10969a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
10979a0bf528SMauro Carvalho Chehab 		if (status < 0)
10989a0bf528SMauro Carvalho Chehab 			goto error;
10999a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
11009a0bf528SMauro Carvalho Chehab 		if (status < 0)
11019a0bf528SMauro Carvalho Chehab 			goto error;
11029a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11039a0bf528SMauro Carvalho Chehab 		if (status < 0)
11049a0bf528SMauro Carvalho Chehab 			goto error;
11059a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11069a0bf528SMauro Carvalho Chehab 		if (status < 0)
11079a0bf528SMauro Carvalho Chehab 			goto error;
11089a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11099a0bf528SMauro Carvalho Chehab 		if (status < 0)
11109a0bf528SMauro Carvalho Chehab 			goto error;
11119a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11129a0bf528SMauro Carvalho Chehab 		if (status < 0)
11139a0bf528SMauro Carvalho Chehab 			goto error;
11149a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11159a0bf528SMauro Carvalho Chehab 		if (status < 0)
11169a0bf528SMauro Carvalho Chehab 			goto error;
11179a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11189a0bf528SMauro Carvalho Chehab 		if (status < 0)
11199a0bf528SMauro Carvalho Chehab 			goto error;
11209a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
11219a0bf528SMauro Carvalho Chehab 		if (status < 0)
11229a0bf528SMauro Carvalho Chehab 			goto error;
11239a0bf528SMauro Carvalho Chehab 	} else {
11249a0bf528SMauro Carvalho Chehab 		/* Enable MPEG output */
1125cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mdx_cfg =
1126cd7a67a4SMauro Carvalho Chehab 			((state->m_ts_data_strength <<
11279a0bf528SMauro Carvalho Chehab 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1128cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
11299a0bf528SMauro Carvalho Chehab 					SIO_PDR_MCLK_CFG_DRIVE__B) |
11309a0bf528SMauro Carvalho Chehab 					0x0003);
11319a0bf528SMauro Carvalho Chehab 
1132cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
11339a0bf528SMauro Carvalho Chehab 		if (status < 0)
11349a0bf528SMauro Carvalho Chehab 			goto error;
11359a0bf528SMauro Carvalho Chehab 
11369a0bf528SMauro Carvalho Chehab 		if (state->enable_merr_cfg)
1137cd7a67a4SMauro Carvalho Chehab 			err_cfg = sio_pdr_mdx_cfg;
11389a0bf528SMauro Carvalho Chehab 
11399a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
11409a0bf528SMauro Carvalho Chehab 		if (status < 0)
11419a0bf528SMauro Carvalho Chehab 			goto error;
11429a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
11439a0bf528SMauro Carvalho Chehab 		if (status < 0)
11449a0bf528SMauro Carvalho Chehab 			goto error;
11459a0bf528SMauro Carvalho Chehab 
11465a7f7b79SMauro Carvalho Chehab 		if (state->m_enable_parallel) {
114739c1cb2bSJonathan McCrohan 			/* parallel -> enable MD1 to MD7 */
1148ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A,
1149ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11509a0bf528SMauro Carvalho Chehab 			if (status < 0)
11519a0bf528SMauro Carvalho Chehab 				goto error;
1152ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A,
1153ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11549a0bf528SMauro Carvalho Chehab 			if (status < 0)
11559a0bf528SMauro Carvalho Chehab 				goto error;
1156ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A,
1157ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11589a0bf528SMauro Carvalho Chehab 			if (status < 0)
11599a0bf528SMauro Carvalho Chehab 				goto error;
1160ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A,
1161ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11629a0bf528SMauro Carvalho Chehab 			if (status < 0)
11639a0bf528SMauro Carvalho Chehab 				goto error;
1164ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A,
1165ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11669a0bf528SMauro Carvalho Chehab 			if (status < 0)
11679a0bf528SMauro Carvalho Chehab 				goto error;
1168ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A,
1169ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11709a0bf528SMauro Carvalho Chehab 			if (status < 0)
11719a0bf528SMauro Carvalho Chehab 				goto error;
1172ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A,
1173ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11749a0bf528SMauro Carvalho Chehab 			if (status < 0)
11759a0bf528SMauro Carvalho Chehab 				goto error;
11769a0bf528SMauro Carvalho Chehab 		} else {
1177cd7a67a4SMauro Carvalho Chehab 			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
11789a0bf528SMauro Carvalho Chehab 						SIO_PDR_MD0_CFG_DRIVE__B)
11799a0bf528SMauro Carvalho Chehab 					| 0x0003);
11809a0bf528SMauro Carvalho Chehab 			/* serial -> disable MD1 to MD7 */
11819a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11829a0bf528SMauro Carvalho Chehab 			if (status < 0)
11839a0bf528SMauro Carvalho Chehab 				goto error;
11849a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11859a0bf528SMauro Carvalho Chehab 			if (status < 0)
11869a0bf528SMauro Carvalho Chehab 				goto error;
11879a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11889a0bf528SMauro Carvalho Chehab 			if (status < 0)
11899a0bf528SMauro Carvalho Chehab 				goto error;
11909a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11919a0bf528SMauro Carvalho Chehab 			if (status < 0)
11929a0bf528SMauro Carvalho Chehab 				goto error;
11939a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11949a0bf528SMauro Carvalho Chehab 			if (status < 0)
11959a0bf528SMauro Carvalho Chehab 				goto error;
11969a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11979a0bf528SMauro Carvalho Chehab 			if (status < 0)
11989a0bf528SMauro Carvalho Chehab 				goto error;
11999a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12009a0bf528SMauro Carvalho Chehab 			if (status < 0)
12019a0bf528SMauro Carvalho Chehab 				goto error;
12029a0bf528SMauro Carvalho Chehab 		}
1203cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
12049a0bf528SMauro Carvalho Chehab 		if (status < 0)
12059a0bf528SMauro Carvalho Chehab 			goto error;
1206cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
12079a0bf528SMauro Carvalho Chehab 		if (status < 0)
12089a0bf528SMauro Carvalho Chehab 			goto error;
12099a0bf528SMauro Carvalho Chehab 	}
12109a0bf528SMauro Carvalho Chehab 	/*  Enable MB output over MPEG pads and ctl input */
12119a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
12129a0bf528SMauro Carvalho Chehab 	if (status < 0)
12139a0bf528SMauro Carvalho Chehab 		goto error;
12149a0bf528SMauro Carvalho Chehab 	/*  Write nomagic word to enable pdr reg write */
12159a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
12169a0bf528SMauro Carvalho Chehab error:
12179a0bf528SMauro Carvalho Chehab 	if (status < 0)
12183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12199a0bf528SMauro Carvalho Chehab 	return status;
12209a0bf528SMauro Carvalho Chehab }
12219a0bf528SMauro Carvalho Chehab 
mpegts_disable(struct drxk_state * state)1222cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state)
12239a0bf528SMauro Carvalho Chehab {
12249a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12259a0bf528SMauro Carvalho Chehab 
1226cd7a67a4SMauro Carvalho Chehab 	return mpegts_configure_pins(state, false);
12279a0bf528SMauro Carvalho Chehab }
12289a0bf528SMauro Carvalho Chehab 
bl_chain_cmd(struct drxk_state * state,u16 rom_offset,u16 nr_of_elements,u32 time_out)1229cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state,
1230cd7a67a4SMauro Carvalho Chehab 		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
12319a0bf528SMauro Carvalho Chehab {
1232cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
12339a0bf528SMauro Carvalho Chehab 	int status;
12349a0bf528SMauro Carvalho Chehab 	unsigned long end;
12359a0bf528SMauro Carvalho Chehab 
12369a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12379a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
12389a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
12399a0bf528SMauro Carvalho Chehab 	if (status < 0)
12409a0bf528SMauro Carvalho Chehab 		goto error;
1241cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
12429a0bf528SMauro Carvalho Chehab 	if (status < 0)
12439a0bf528SMauro Carvalho Chehab 		goto error;
1244cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
12459a0bf528SMauro Carvalho Chehab 	if (status < 0)
12469a0bf528SMauro Carvalho Chehab 		goto error;
12479a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
12489a0bf528SMauro Carvalho Chehab 	if (status < 0)
12499a0bf528SMauro Carvalho Chehab 		goto error;
12509a0bf528SMauro Carvalho Chehab 
1251cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
12529a0bf528SMauro Carvalho Chehab 	do {
1253b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1254cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
12559a0bf528SMauro Carvalho Chehab 		if (status < 0)
12569a0bf528SMauro Carvalho Chehab 			goto error;
1257cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) &&
12589a0bf528SMauro Carvalho Chehab 			((time_is_after_jiffies(end))));
12599a0bf528SMauro Carvalho Chehab 
1260cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
12613a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
12629a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
12639a0bf528SMauro Carvalho Chehab 		goto error2;
12649a0bf528SMauro Carvalho Chehab 	}
12659a0bf528SMauro Carvalho Chehab error:
12669a0bf528SMauro Carvalho Chehab 	if (status < 0)
12673a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12689a0bf528SMauro Carvalho Chehab error2:
12699a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
12709a0bf528SMauro Carvalho Chehab 	return status;
12719a0bf528SMauro Carvalho Chehab }
12729a0bf528SMauro Carvalho Chehab 
12739a0bf528SMauro Carvalho Chehab 
download_microcode(struct drxk_state * state,const u8 p_mc_image[],u32 length)1274cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state,
1275cd7a67a4SMauro Carvalho Chehab 			     const u8 p_mc_image[], u32 length)
12769a0bf528SMauro Carvalho Chehab {
1277cd7a67a4SMauro Carvalho Chehab 	const u8 *p_src = p_mc_image;
1278cd7a67a4SMauro Carvalho Chehab 	u32 address;
1279cd7a67a4SMauro Carvalho Chehab 	u16 n_blocks;
1280cd7a67a4SMauro Carvalho Chehab 	u16 block_size;
12819a0bf528SMauro Carvalho Chehab 	u32 offset = 0;
12829a0bf528SMauro Carvalho Chehab 	u32 i;
12839a0bf528SMauro Carvalho Chehab 	int status = 0;
12849a0bf528SMauro Carvalho Chehab 
12859a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12869a0bf528SMauro Carvalho Chehab 
12879a0bf528SMauro Carvalho Chehab 	/* down the drain (we don't care about MAGIC_WORD) */
12889a0bf528SMauro Carvalho Chehab #if 0
12899a0bf528SMauro Carvalho Chehab 	/* For future reference */
1290cd7a67a4SMauro Carvalho Chehab 	drain = (p_src[0] << 8) | p_src[1];
12919a0bf528SMauro Carvalho Chehab #endif
1292cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
12939a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
1294cd7a67a4SMauro Carvalho Chehab 	n_blocks = (p_src[0] << 8) | p_src[1];
1295cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
12969a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
12979a0bf528SMauro Carvalho Chehab 
1298cd7a67a4SMauro Carvalho Chehab 	for (i = 0; i < n_blocks; i += 1) {
1299cd7a67a4SMauro Carvalho Chehab 		address = (p_src[0] << 24) | (p_src[1] << 16) |
1300cd7a67a4SMauro Carvalho Chehab 		    (p_src[2] << 8) | p_src[3];
1301cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u32);
13029a0bf528SMauro Carvalho Chehab 		offset += sizeof(u32);
13039a0bf528SMauro Carvalho Chehab 
1304cd7a67a4SMauro Carvalho Chehab 		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1305cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13069a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13079a0bf528SMauro Carvalho Chehab 
13089a0bf528SMauro Carvalho Chehab #if 0
13099a0bf528SMauro Carvalho Chehab 		/* For future reference */
1310cd7a67a4SMauro Carvalho Chehab 		flags = (p_src[0] << 8) | p_src[1];
13119a0bf528SMauro Carvalho Chehab #endif
1312cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13139a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13149a0bf528SMauro Carvalho Chehab 
13159a0bf528SMauro Carvalho Chehab #if 0
13169a0bf528SMauro Carvalho Chehab 		/* For future reference */
1317cd7a67a4SMauro Carvalho Chehab 		block_crc = (p_src[0] << 8) | p_src[1];
13189a0bf528SMauro Carvalho Chehab #endif
1319cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13209a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13219a0bf528SMauro Carvalho Chehab 
1322cd7a67a4SMauro Carvalho Chehab 		if (offset + block_size > length) {
13233a4398f5SMauro Carvalho Chehab 			pr_err("Firmware is corrupted.\n");
13249a0bf528SMauro Carvalho Chehab 			return -EINVAL;
13259a0bf528SMauro Carvalho Chehab 		}
13269a0bf528SMauro Carvalho Chehab 
1327cd7a67a4SMauro Carvalho Chehab 		status = write_block(state, address, block_size, p_src);
13289a0bf528SMauro Carvalho Chehab 		if (status < 0) {
13293a4398f5SMauro Carvalho Chehab 			pr_err("Error %d while loading firmware\n", status);
13309a0bf528SMauro Carvalho Chehab 			break;
13319a0bf528SMauro Carvalho Chehab 		}
1332cd7a67a4SMauro Carvalho Chehab 		p_src += block_size;
1333cd7a67a4SMauro Carvalho Chehab 		offset += block_size;
13349a0bf528SMauro Carvalho Chehab 	}
13359a0bf528SMauro Carvalho Chehab 	return status;
13369a0bf528SMauro Carvalho Chehab }
13379a0bf528SMauro Carvalho Chehab 
dvbt_enable_ofdm_token_ring(struct drxk_state * state,bool enable)1338cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
13399a0bf528SMauro Carvalho Chehab {
13409a0bf528SMauro Carvalho Chehab 	int status;
13419a0bf528SMauro Carvalho Chehab 	u16 data = 0;
1342cd7a67a4SMauro Carvalho Chehab 	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1343cd7a67a4SMauro Carvalho Chehab 	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
13449a0bf528SMauro Carvalho Chehab 	unsigned long end;
13459a0bf528SMauro Carvalho Chehab 
13469a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13479a0bf528SMauro Carvalho Chehab 
13485a7f7b79SMauro Carvalho Chehab 	if (!enable) {
1349cd7a67a4SMauro Carvalho Chehab 		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1350cd7a67a4SMauro Carvalho Chehab 		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
13519a0bf528SMauro Carvalho Chehab 	}
13529a0bf528SMauro Carvalho Chehab 
13539a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1354cd7a67a4SMauro Carvalho Chehab 	if (status >= 0 && data == desired_status) {
13559a0bf528SMauro Carvalho Chehab 		/* tokenring already has correct status */
13569a0bf528SMauro Carvalho Chehab 		return status;
13579a0bf528SMauro Carvalho Chehab 	}
13589a0bf528SMauro Carvalho Chehab 	/* Disable/enable dvbt tokenring bridge   */
1359cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
13609a0bf528SMauro Carvalho Chehab 
13619a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
13629a0bf528SMauro Carvalho Chehab 	do {
13639a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1364ab5060cdSMauro Carvalho Chehab 		if ((status >= 0 && data == desired_status)
1365ab5060cdSMauro Carvalho Chehab 		    || time_is_after_jiffies(end))
13669a0bf528SMauro Carvalho Chehab 			break;
1367b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
13689a0bf528SMauro Carvalho Chehab 	} while (1);
1369cd7a67a4SMauro Carvalho Chehab 	if (data != desired_status) {
13703a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
13719a0bf528SMauro Carvalho Chehab 		return -EINVAL;
13729a0bf528SMauro Carvalho Chehab 	}
13739a0bf528SMauro Carvalho Chehab 	return status;
13749a0bf528SMauro Carvalho Chehab }
13759a0bf528SMauro Carvalho Chehab 
mpegts_stop(struct drxk_state * state)1376cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state)
13779a0bf528SMauro Carvalho Chehab {
13789a0bf528SMauro Carvalho Chehab 	int status = 0;
1379cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
1380cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_ipr_mode = 0;
13819a0bf528SMauro Carvalho Chehab 
13829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13839a0bf528SMauro Carvalho Chehab 
138439c1cb2bSJonathan McCrohan 	/* Graceful shutdown (byte boundaries) */
1385cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
13869a0bf528SMauro Carvalho Chehab 	if (status < 0)
13879a0bf528SMauro Carvalho Chehab 		goto error;
1388cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1389cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
13909a0bf528SMauro Carvalho Chehab 	if (status < 0)
13919a0bf528SMauro Carvalho Chehab 		goto error;
13929a0bf528SMauro Carvalho Chehab 
13939a0bf528SMauro Carvalho Chehab 	/* Suppress MCLK during absence of data */
1394cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
13959a0bf528SMauro Carvalho Chehab 	if (status < 0)
13969a0bf528SMauro Carvalho Chehab 		goto error;
1397cd7a67a4SMauro Carvalho Chehab 	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1398cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
13999a0bf528SMauro Carvalho Chehab 
14009a0bf528SMauro Carvalho Chehab error:
14019a0bf528SMauro Carvalho Chehab 	if (status < 0)
14023a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14039a0bf528SMauro Carvalho Chehab 
14049a0bf528SMauro Carvalho Chehab 	return status;
14059a0bf528SMauro Carvalho Chehab }
14069a0bf528SMauro Carvalho Chehab 
scu_command(struct drxk_state * state,u16 cmd,u8 parameter_len,u16 * parameter,u8 result_len,u16 * result)14079a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
1408cd7a67a4SMauro Carvalho Chehab 		       u16 cmd, u8 parameter_len,
1409cd7a67a4SMauro Carvalho Chehab 		       u16 *parameter, u8 result_len, u16 *result)
14109a0bf528SMauro Carvalho Chehab {
14119a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
14129a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
14139a0bf528SMauro Carvalho Chehab #endif
1414cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
14159a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
14169a0bf528SMauro Carvalho Chehab 	unsigned long end;
14179a0bf528SMauro Carvalho Chehab 	u8 buffer[34];
14189a0bf528SMauro Carvalho Chehab 	int cnt = 0, ii;
14199a0bf528SMauro Carvalho Chehab 	const char *p;
14209a0bf528SMauro Carvalho Chehab 	char errname[30];
14219a0bf528SMauro Carvalho Chehab 
14229a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14239a0bf528SMauro Carvalho Chehab 
1424cd7a67a4SMauro Carvalho Chehab 	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1425cd7a67a4SMauro Carvalho Chehab 	    ((result_len > 0) && (result == NULL))) {
14263a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14279a0bf528SMauro Carvalho Chehab 		return status;
14289a0bf528SMauro Carvalho Chehab 	}
14299a0bf528SMauro Carvalho Chehab 
14309a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
14319a0bf528SMauro Carvalho Chehab 
14329a0bf528SMauro Carvalho Chehab 	/* assume that the command register is ready
14339a0bf528SMauro Carvalho Chehab 		since it is checked afterwards */
1434daad52c8SMauro Carvalho Chehab 	if (parameter) {
1435cd7a67a4SMauro Carvalho Chehab 		for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
14369a0bf528SMauro Carvalho Chehab 			buffer[cnt++] = (parameter[ii] & 0xFF);
14379a0bf528SMauro Carvalho Chehab 			buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
14389a0bf528SMauro Carvalho Chehab 		}
1439daad52c8SMauro Carvalho Chehab 	}
14409a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = (cmd & 0xFF);
14419a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
14429a0bf528SMauro Carvalho Chehab 
14439a0bf528SMauro Carvalho Chehab 	write_block(state, SCU_RAM_PARAM_0__A -
1444cd7a67a4SMauro Carvalho Chehab 			(parameter_len - 1), cnt, buffer);
14459a0bf528SMauro Carvalho Chehab 	/* Wait until SCU has processed command */
14469a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
14479a0bf528SMauro Carvalho Chehab 	do {
1448b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1449cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
14509a0bf528SMauro Carvalho Chehab 		if (status < 0)
14519a0bf528SMauro Carvalho Chehab 			goto error;
1452cd7a67a4SMauro Carvalho Chehab 	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1453cd7a67a4SMauro Carvalho Chehab 	if (cur_cmd != DRX_SCU_READY) {
14543a4398f5SMauro Carvalho Chehab 		pr_err("SCU not ready\n");
14559a0bf528SMauro Carvalho Chehab 		status = -EIO;
14569a0bf528SMauro Carvalho Chehab 		goto error2;
14579a0bf528SMauro Carvalho Chehab 	}
14589a0bf528SMauro Carvalho Chehab 	/* read results */
1459cd7a67a4SMauro Carvalho Chehab 	if ((result_len > 0) && (result != NULL)) {
14609a0bf528SMauro Carvalho Chehab 		s16 err;
14619a0bf528SMauro Carvalho Chehab 		int ii;
14629a0bf528SMauro Carvalho Chehab 
1463cd7a67a4SMauro Carvalho Chehab 		for (ii = result_len - 1; ii >= 0; ii -= 1) {
1464ab5060cdSMauro Carvalho Chehab 			status = read16(state, SCU_RAM_PARAM_0__A - ii,
1465ab5060cdSMauro Carvalho Chehab 					&result[ii]);
14669a0bf528SMauro Carvalho Chehab 			if (status < 0)
14679a0bf528SMauro Carvalho Chehab 				goto error;
14689a0bf528SMauro Carvalho Chehab 		}
14699a0bf528SMauro Carvalho Chehab 
14709a0bf528SMauro Carvalho Chehab 		/* Check if an error was reported by SCU */
14719a0bf528SMauro Carvalho Chehab 		err = (s16)result[0];
14729a0bf528SMauro Carvalho Chehab 		if (err >= 0)
14739a0bf528SMauro Carvalho Chehab 			goto error;
14749a0bf528SMauro Carvalho Chehab 
14759a0bf528SMauro Carvalho Chehab 		/* check for the known error codes */
14769a0bf528SMauro Carvalho Chehab 		switch (err) {
14779a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKCMD:
14789a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKCMD";
14799a0bf528SMauro Carvalho Chehab 			break;
14809a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKSTD:
14819a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKSTD";
14829a0bf528SMauro Carvalho Chehab 			break;
14839a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_SIZE:
14849a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_SIZE";
14859a0bf528SMauro Carvalho Chehab 			break;
14869a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_INVPAR:
14879a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_INVPAR";
14889a0bf528SMauro Carvalho Chehab 			break;
14899a0bf528SMauro Carvalho Chehab 		default: /* Other negative values are errors */
14909a0bf528SMauro Carvalho Chehab 			sprintf(errname, "ERROR: %d\n", err);
14919a0bf528SMauro Carvalho Chehab 			p = errname;
14929a0bf528SMauro Carvalho Chehab 		}
14933a4398f5SMauro Carvalho Chehab 		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
14949a0bf528SMauro Carvalho Chehab 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
14959a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
14969a0bf528SMauro Carvalho Chehab 		goto error2;
14979a0bf528SMauro Carvalho Chehab 	}
14989a0bf528SMauro Carvalho Chehab 
14999a0bf528SMauro Carvalho Chehab error:
15009a0bf528SMauro Carvalho Chehab 	if (status < 0)
15013a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15029a0bf528SMauro Carvalho Chehab error2:
15039a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
15049a0bf528SMauro Carvalho Chehab 	return status;
15059a0bf528SMauro Carvalho Chehab }
15069a0bf528SMauro Carvalho Chehab 
set_iqm_af(struct drxk_state * state,bool active)1507cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active)
15089a0bf528SMauro Carvalho Chehab {
15099a0bf528SMauro Carvalho Chehab 	u16 data = 0;
15109a0bf528SMauro Carvalho Chehab 	int status;
15119a0bf528SMauro Carvalho Chehab 
15129a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15139a0bf528SMauro Carvalho Chehab 
15149a0bf528SMauro Carvalho Chehab 	/* Configure IQM */
15159a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_STDBY__A, &data);
15169a0bf528SMauro Carvalho Chehab 	if (status < 0)
15179a0bf528SMauro Carvalho Chehab 		goto error;
15189a0bf528SMauro Carvalho Chehab 
15199a0bf528SMauro Carvalho Chehab 	if (!active) {
15209a0bf528SMauro Carvalho Chehab 		data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
15219a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_AMP_STANDBY
15229a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_PD_STANDBY
15239a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
15249a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
15259a0bf528SMauro Carvalho Chehab 	} else {
15269a0bf528SMauro Carvalho Chehab 		data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
15279a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
15289a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_PD_STANDBY)
15299a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
15309a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
15319a0bf528SMauro Carvalho Chehab 			);
15329a0bf528SMauro Carvalho Chehab 	}
15339a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_STDBY__A, data);
15349a0bf528SMauro Carvalho Chehab 
15359a0bf528SMauro Carvalho Chehab error:
15369a0bf528SMauro Carvalho Chehab 	if (status < 0)
15373a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15389a0bf528SMauro Carvalho Chehab 	return status;
15399a0bf528SMauro Carvalho Chehab }
15409a0bf528SMauro Carvalho Chehab 
ctrl_power_mode(struct drxk_state * state,enum drx_power_mode * mode)1541cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
15429a0bf528SMauro Carvalho Chehab {
15439a0bf528SMauro Carvalho Chehab 	int status = 0;
1544cd7a67a4SMauro Carvalho Chehab 	u16 sio_cc_pwd_mode = 0;
15459a0bf528SMauro Carvalho Chehab 
15469a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15479a0bf528SMauro Carvalho Chehab 
15489a0bf528SMauro Carvalho Chehab 	/* Check arguments */
15499a0bf528SMauro Carvalho Chehab 	if (mode == NULL)
15509a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15519a0bf528SMauro Carvalho Chehab 
15529a0bf528SMauro Carvalho Chehab 	switch (*mode) {
15539a0bf528SMauro Carvalho Chehab 	case DRX_POWER_UP:
1554cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
15559a0bf528SMauro Carvalho Chehab 		break;
15569a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_OFDM:
1557cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
15589a0bf528SMauro Carvalho Chehab 		break;
15599a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_CORE:
1560cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
15619a0bf528SMauro Carvalho Chehab 		break;
15629a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_PLL:
1563cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
15649a0bf528SMauro Carvalho Chehab 		break;
15659a0bf528SMauro Carvalho Chehab 	case DRX_POWER_DOWN:
1566cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
15679a0bf528SMauro Carvalho Chehab 		break;
15689a0bf528SMauro Carvalho Chehab 	default:
1569e78da4daSJonathan Neuschäfer 		/* Unknown sleep mode */
15709a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15719a0bf528SMauro Carvalho Chehab 	}
15729a0bf528SMauro Carvalho Chehab 
15739a0bf528SMauro Carvalho Chehab 	/* If already in requested power mode, do nothing */
1574cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode == *mode)
15759a0bf528SMauro Carvalho Chehab 		return 0;
15769a0bf528SMauro Carvalho Chehab 
15779a0bf528SMauro Carvalho Chehab 	/* For next steps make sure to start from DRX_POWER_UP mode */
1578cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode != DRX_POWER_UP) {
1579cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
15809a0bf528SMauro Carvalho Chehab 		if (status < 0)
15819a0bf528SMauro Carvalho Chehab 			goto error;
1582cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, true);
15839a0bf528SMauro Carvalho Chehab 		if (status < 0)
15849a0bf528SMauro Carvalho Chehab 			goto error;
15859a0bf528SMauro Carvalho Chehab 	}
15869a0bf528SMauro Carvalho Chehab 
15879a0bf528SMauro Carvalho Chehab 	if (*mode == DRX_POWER_UP) {
15882c149601SMasahiro Yamada 		/* Restore analog & pin configuration */
15899a0bf528SMauro Carvalho Chehab 	} else {
15909a0bf528SMauro Carvalho Chehab 		/* Power down to requested mode */
15919a0bf528SMauro Carvalho Chehab 		/* Backup some register settings */
15929a0bf528SMauro Carvalho Chehab 		/* Set pins with possible pull-ups connected
15939a0bf528SMauro Carvalho Chehab 		   to them in input mode */
15949a0bf528SMauro Carvalho Chehab 		/* Analog power down */
15959a0bf528SMauro Carvalho Chehab 		/* ADC power down */
15969a0bf528SMauro Carvalho Chehab 		/* Power down device */
15979a0bf528SMauro Carvalho Chehab 		/* stop all comm_exec */
15989a0bf528SMauro Carvalho Chehab 		/* Stop and power down previous standard */
1599cd7a67a4SMauro Carvalho Chehab 		switch (state->m_operation_mode) {
16009a0bf528SMauro Carvalho Chehab 		case OM_DVBT:
1601cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16029a0bf528SMauro Carvalho Chehab 			if (status < 0)
16039a0bf528SMauro Carvalho Chehab 				goto error;
1604cd7a67a4SMauro Carvalho Chehab 			status = power_down_dvbt(state, false);
16059a0bf528SMauro Carvalho Chehab 			if (status < 0)
16069a0bf528SMauro Carvalho Chehab 				goto error;
16079a0bf528SMauro Carvalho Chehab 			break;
16089a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_A:
16099a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_C:
1610cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16119a0bf528SMauro Carvalho Chehab 			if (status < 0)
16129a0bf528SMauro Carvalho Chehab 				goto error;
1613cd7a67a4SMauro Carvalho Chehab 			status = power_down_qam(state);
16149a0bf528SMauro Carvalho Chehab 			if (status < 0)
16159a0bf528SMauro Carvalho Chehab 				goto error;
16169a0bf528SMauro Carvalho Chehab 			break;
16179a0bf528SMauro Carvalho Chehab 		default:
16189a0bf528SMauro Carvalho Chehab 			break;
16199a0bf528SMauro Carvalho Chehab 		}
1620cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, false);
16219a0bf528SMauro Carvalho Chehab 		if (status < 0)
16229a0bf528SMauro Carvalho Chehab 			goto error;
1623cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
16249a0bf528SMauro Carvalho Chehab 		if (status < 0)
16259a0bf528SMauro Carvalho Chehab 			goto error;
16269a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
16279a0bf528SMauro Carvalho Chehab 		if (status < 0)
16289a0bf528SMauro Carvalho Chehab 			goto error;
16299a0bf528SMauro Carvalho Chehab 
16309a0bf528SMauro Carvalho Chehab 		if (*mode != DRXK_POWER_DOWN_OFDM) {
1631cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_ctrl |=
16329a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1633cd7a67a4SMauro Carvalho Chehab 			status = hi_cfg_command(state);
16349a0bf528SMauro Carvalho Chehab 			if (status < 0)
16359a0bf528SMauro Carvalho Chehab 				goto error;
16369a0bf528SMauro Carvalho Chehab 		}
16379a0bf528SMauro Carvalho Chehab 	}
1638cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = *mode;
16399a0bf528SMauro Carvalho Chehab 
16409a0bf528SMauro Carvalho Chehab error:
16419a0bf528SMauro Carvalho Chehab 	if (status < 0)
16423a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
16439a0bf528SMauro Carvalho Chehab 
16449a0bf528SMauro Carvalho Chehab 	return status;
16459a0bf528SMauro Carvalho Chehab }
16469a0bf528SMauro Carvalho Chehab 
power_down_dvbt(struct drxk_state * state,bool set_power_mode)1647cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
16489a0bf528SMauro Carvalho Chehab {
1649cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1650cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
16519a0bf528SMauro Carvalho Chehab 	u16 data = 0;
16529a0bf528SMauro Carvalho Chehab 	int status;
16539a0bf528SMauro Carvalho Chehab 
16549a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
16559a0bf528SMauro Carvalho Chehab 
16569a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
16579a0bf528SMauro Carvalho Chehab 	if (status < 0)
16589a0bf528SMauro Carvalho Chehab 		goto error;
16599a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
16609a0bf528SMauro Carvalho Chehab 		/* Send OFDM stop command */
1661ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1662ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1663ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1664ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
16659a0bf528SMauro Carvalho Chehab 		if (status < 0)
16669a0bf528SMauro Carvalho Chehab 			goto error;
16679a0bf528SMauro Carvalho Chehab 		/* Send OFDM reset command */
1668ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1669ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1670ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1671ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
16729a0bf528SMauro Carvalho Chehab 		if (status < 0)
16739a0bf528SMauro Carvalho Chehab 			goto error;
16749a0bf528SMauro Carvalho Chehab 	}
16759a0bf528SMauro Carvalho Chehab 
16769a0bf528SMauro Carvalho Chehab 	/* Reset datapath for OFDM, processors first */
16779a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
16789a0bf528SMauro Carvalho Chehab 	if (status < 0)
16799a0bf528SMauro Carvalho Chehab 		goto error;
16809a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
16819a0bf528SMauro Carvalho Chehab 	if (status < 0)
16829a0bf528SMauro Carvalho Chehab 		goto error;
16839a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
16849a0bf528SMauro Carvalho Chehab 	if (status < 0)
16859a0bf528SMauro Carvalho Chehab 		goto error;
16869a0bf528SMauro Carvalho Chehab 
16879a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
1688cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
16899a0bf528SMauro Carvalho Chehab 	if (status < 0)
16909a0bf528SMauro Carvalho Chehab 		goto error;
16919a0bf528SMauro Carvalho Chehab 
16929a0bf528SMauro Carvalho Chehab 	/* powerdown to OFDM mode          */
1693cd7a67a4SMauro Carvalho Chehab 	if (set_power_mode) {
1694cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
16959a0bf528SMauro Carvalho Chehab 		if (status < 0)
16969a0bf528SMauro Carvalho Chehab 			goto error;
16979a0bf528SMauro Carvalho Chehab 	}
16989a0bf528SMauro Carvalho Chehab error:
16999a0bf528SMauro Carvalho Chehab 	if (status < 0)
17003a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
17019a0bf528SMauro Carvalho Chehab 	return status;
17029a0bf528SMauro Carvalho Chehab }
17039a0bf528SMauro Carvalho Chehab 
setoperation_mode(struct drxk_state * state,enum operation_mode o_mode)1704cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state,
1705cd7a67a4SMauro Carvalho Chehab 			    enum operation_mode o_mode)
17069a0bf528SMauro Carvalho Chehab {
17079a0bf528SMauro Carvalho Chehab 	int status = 0;
17089a0bf528SMauro Carvalho Chehab 
17099a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17109a0bf528SMauro Carvalho Chehab 	/*
17119a0bf528SMauro Carvalho Chehab 	   Stop and power down previous standard
17129a0bf528SMauro Carvalho Chehab 	   TODO investigate total power down instead of partial
17139a0bf528SMauro Carvalho Chehab 	   power down depending on "previous" standard.
17149a0bf528SMauro Carvalho Chehab 	 */
17159a0bf528SMauro Carvalho Chehab 
17169a0bf528SMauro Carvalho Chehab 	/* disable HW lock indicator */
1717ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1718ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
17199a0bf528SMauro Carvalho Chehab 	if (status < 0)
17209a0bf528SMauro Carvalho Chehab 		goto error;
17219a0bf528SMauro Carvalho Chehab 
17229a0bf528SMauro Carvalho Chehab 	/* Device is already at the required mode */
1723cd7a67a4SMauro Carvalho Chehab 	if (state->m_operation_mode == o_mode)
17249a0bf528SMauro Carvalho Chehab 		return 0;
17259a0bf528SMauro Carvalho Chehab 
1726cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
17279a0bf528SMauro Carvalho Chehab 		/* OM_NONE was added for start up */
17289a0bf528SMauro Carvalho Chehab 	case OM_NONE:
17299a0bf528SMauro Carvalho Chehab 		break;
17309a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1731cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17329a0bf528SMauro Carvalho Chehab 		if (status < 0)
17339a0bf528SMauro Carvalho Chehab 			goto error;
1734cd7a67a4SMauro Carvalho Chehab 		status = power_down_dvbt(state, true);
17359a0bf528SMauro Carvalho Chehab 		if (status < 0)
17369a0bf528SMauro Carvalho Chehab 			goto error;
1737cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17389a0bf528SMauro Carvalho Chehab 		break;
1739df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
17409a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1741cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17429a0bf528SMauro Carvalho Chehab 		if (status < 0)
17439a0bf528SMauro Carvalho Chehab 			goto error;
1744cd7a67a4SMauro Carvalho Chehab 		status = power_down_qam(state);
17459a0bf528SMauro Carvalho Chehab 		if (status < 0)
17469a0bf528SMauro Carvalho Chehab 			goto error;
1747cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17489a0bf528SMauro Carvalho Chehab 		break;
17499a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17509a0bf528SMauro Carvalho Chehab 	default:
17519a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17529a0bf528SMauro Carvalho Chehab 		goto error;
17539a0bf528SMauro Carvalho Chehab 	}
17549a0bf528SMauro Carvalho Chehab 
17559a0bf528SMauro Carvalho Chehab 	/*
17569a0bf528SMauro Carvalho Chehab 		Power up new standard
17579a0bf528SMauro Carvalho Chehab 		*/
1758cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
17599a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
17609a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-T\n");
1761cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1762cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt_standard(state, o_mode);
17639a0bf528SMauro Carvalho Chehab 		if (status < 0)
17649a0bf528SMauro Carvalho Chehab 			goto error;
17659a0bf528SMauro Carvalho Chehab 		break;
1766df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
17679a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
17689a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-C Annex %c\n",
1769cd7a67a4SMauro Carvalho Chehab 			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1770cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1771cd7a67a4SMauro Carvalho Chehab 		status = set_qam_standard(state, o_mode);
17729a0bf528SMauro Carvalho Chehab 		if (status < 0)
17739a0bf528SMauro Carvalho Chehab 			goto error;
17749a0bf528SMauro Carvalho Chehab 		break;
17759a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17769a0bf528SMauro Carvalho Chehab 	default:
17779a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17789a0bf528SMauro Carvalho Chehab 	}
17799a0bf528SMauro Carvalho Chehab error:
17809a0bf528SMauro Carvalho Chehab 	if (status < 0)
17813a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
17829a0bf528SMauro Carvalho Chehab 	return status;
17839a0bf528SMauro Carvalho Chehab }
17849a0bf528SMauro Carvalho Chehab 
start(struct drxk_state * state,s32 offset_freq,s32 intermediate_frequency)1785cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq,
1786cd7a67a4SMauro Carvalho Chehab 		 s32 intermediate_frequency)
17879a0bf528SMauro Carvalho Chehab {
17889a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
17899a0bf528SMauro Carvalho Chehab 
1790cd7a67a4SMauro Carvalho Chehab 	u16 i_freqk_hz;
1791cd7a67a4SMauro Carvalho Chehab 	s32 offsetk_hz = offset_freq / 1000;
17929a0bf528SMauro Carvalho Chehab 
17939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
1794cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state != DRXK_STOPPED &&
1795cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state != DRXK_DTV_STARTED)
17969a0bf528SMauro Carvalho Chehab 		goto error;
17979a0bf528SMauro Carvalho Chehab 
1798cd7a67a4SMauro Carvalho Chehab 	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
17999a0bf528SMauro Carvalho Chehab 
1800cd7a67a4SMauro Carvalho Chehab 	if (intermediate_frequency < 0) {
1801cd7a67a4SMauro Carvalho Chehab 		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1802cd7a67a4SMauro Carvalho Chehab 		intermediate_frequency = -intermediate_frequency;
18039a0bf528SMauro Carvalho Chehab 	}
18049a0bf528SMauro Carvalho Chehab 
1805cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18069a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18079a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1808cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1809cd7a67a4SMauro Carvalho Chehab 		status = set_qam(state, i_freqk_hz, offsetk_hz);
18109a0bf528SMauro Carvalho Chehab 		if (status < 0)
18119a0bf528SMauro Carvalho Chehab 			goto error;
1812cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18139a0bf528SMauro Carvalho Chehab 		break;
18149a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1815cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1816cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
18179a0bf528SMauro Carvalho Chehab 		if (status < 0)
18189a0bf528SMauro Carvalho Chehab 			goto error;
1819cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
18209a0bf528SMauro Carvalho Chehab 		if (status < 0)
18219a0bf528SMauro Carvalho Chehab 			goto error;
1822cd7a67a4SMauro Carvalho Chehab 		status = dvbt_start(state);
18239a0bf528SMauro Carvalho Chehab 		if (status < 0)
18249a0bf528SMauro Carvalho Chehab 			goto error;
1825cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18269a0bf528SMauro Carvalho Chehab 		break;
18279a0bf528SMauro Carvalho Chehab 	default:
18289a0bf528SMauro Carvalho Chehab 		break;
18299a0bf528SMauro Carvalho Chehab 	}
18309a0bf528SMauro Carvalho Chehab error:
18319a0bf528SMauro Carvalho Chehab 	if (status < 0)
18323a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18339a0bf528SMauro Carvalho Chehab 	return status;
18349a0bf528SMauro Carvalho Chehab }
18359a0bf528SMauro Carvalho Chehab 
shut_down(struct drxk_state * state)1836cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state)
18379a0bf528SMauro Carvalho Chehab {
18389a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18399a0bf528SMauro Carvalho Chehab 
1840cd7a67a4SMauro Carvalho Chehab 	mpegts_stop(state);
18419a0bf528SMauro Carvalho Chehab 	return 0;
18429a0bf528SMauro Carvalho Chehab }
18439a0bf528SMauro Carvalho Chehab 
get_lock_status(struct drxk_state * state,u32 * p_lock_status)1844cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
18459a0bf528SMauro Carvalho Chehab {
18469a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18479a0bf528SMauro Carvalho Chehab 
18489a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18499a0bf528SMauro Carvalho Chehab 
1850cd7a67a4SMauro Carvalho Chehab 	if (p_lock_status == NULL)
18519a0bf528SMauro Carvalho Chehab 		goto error;
18529a0bf528SMauro Carvalho Chehab 
1853cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
18549a0bf528SMauro Carvalho Chehab 
18559a0bf528SMauro Carvalho Chehab 	/* define the SCU command code */
1856cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18579a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18589a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18599a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1860cd7a67a4SMauro Carvalho Chehab 		status = get_qam_lock_status(state, p_lock_status);
18619a0bf528SMauro Carvalho Chehab 		break;
18629a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1863cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_lock_status(state, p_lock_status);
18649a0bf528SMauro Carvalho Chehab 		break;
18659a0bf528SMauro Carvalho Chehab 	default:
1866b73bb2abSDaniel Scheller 		pr_debug("Unsupported operation mode %d in %s\n",
1867b73bb2abSDaniel Scheller 			state->m_operation_mode, __func__);
1868b73bb2abSDaniel Scheller 		return 0;
18699a0bf528SMauro Carvalho Chehab 	}
18709a0bf528SMauro Carvalho Chehab error:
18719a0bf528SMauro Carvalho Chehab 	if (status < 0)
18723a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18739a0bf528SMauro Carvalho Chehab 	return status;
18749a0bf528SMauro Carvalho Chehab }
18759a0bf528SMauro Carvalho Chehab 
mpegts_start(struct drxk_state * state)1876cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state)
18779a0bf528SMauro Carvalho Chehab {
18789a0bf528SMauro Carvalho Chehab 	int status;
18799a0bf528SMauro Carvalho Chehab 
1880cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
18819a0bf528SMauro Carvalho Chehab 
18829a0bf528SMauro Carvalho Chehab 	/* Allow OC to sync again */
1883cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
18849a0bf528SMauro Carvalho Chehab 	if (status < 0)
18859a0bf528SMauro Carvalho Chehab 		goto error;
1886cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1887cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
18889a0bf528SMauro Carvalho Chehab 	if (status < 0)
18899a0bf528SMauro Carvalho Chehab 		goto error;
18909a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
18919a0bf528SMauro Carvalho Chehab error:
18929a0bf528SMauro Carvalho Chehab 	if (status < 0)
18933a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18949a0bf528SMauro Carvalho Chehab 	return status;
18959a0bf528SMauro Carvalho Chehab }
18969a0bf528SMauro Carvalho Chehab 
mpegts_dto_init(struct drxk_state * state)1897cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state)
18989a0bf528SMauro Carvalho Chehab {
18999a0bf528SMauro Carvalho Chehab 	int status;
19009a0bf528SMauro Carvalho Chehab 
19019a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19029a0bf528SMauro Carvalho Chehab 
19039a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
19049a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
19059a0bf528SMauro Carvalho Chehab 	if (status < 0)
19069a0bf528SMauro Carvalho Chehab 		goto error;
19079a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
19089a0bf528SMauro Carvalho Chehab 	if (status < 0)
19099a0bf528SMauro Carvalho Chehab 		goto error;
19109a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
19119a0bf528SMauro Carvalho Chehab 	if (status < 0)
19129a0bf528SMauro Carvalho Chehab 		goto error;
19139a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
19149a0bf528SMauro Carvalho Chehab 	if (status < 0)
19159a0bf528SMauro Carvalho Chehab 		goto error;
19169a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
19179a0bf528SMauro Carvalho Chehab 	if (status < 0)
19189a0bf528SMauro Carvalho Chehab 		goto error;
19199a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
19209a0bf528SMauro Carvalho Chehab 	if (status < 0)
19219a0bf528SMauro Carvalho Chehab 		goto error;
19229a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
19239a0bf528SMauro Carvalho Chehab 	if (status < 0)
19249a0bf528SMauro Carvalho Chehab 		goto error;
19259a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
19269a0bf528SMauro Carvalho Chehab 	if (status < 0)
19279a0bf528SMauro Carvalho Chehab 		goto error;
19289a0bf528SMauro Carvalho Chehab 
19299a0bf528SMauro Carvalho Chehab 	/* Additional configuration */
19309a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_OCR_INVERT__A, 0);
19319a0bf528SMauro Carvalho Chehab 	if (status < 0)
19329a0bf528SMauro Carvalho Chehab 		goto error;
19339a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_LWM__A, 2);
19349a0bf528SMauro Carvalho Chehab 	if (status < 0)
19359a0bf528SMauro Carvalho Chehab 		goto error;
19369a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
19379a0bf528SMauro Carvalho Chehab error:
19389a0bf528SMauro Carvalho Chehab 	if (status < 0)
19393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19409a0bf528SMauro Carvalho Chehab 
19419a0bf528SMauro Carvalho Chehab 	return status;
19429a0bf528SMauro Carvalho Chehab }
19439a0bf528SMauro Carvalho Chehab 
mpegts_dto_setup(struct drxk_state * state,enum operation_mode o_mode)1944cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state,
1945cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
19469a0bf528SMauro Carvalho Chehab {
19479a0bf528SMauro Carvalho Chehab 	int status;
19489a0bf528SMauro Carvalho Chehab 
1949cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
1950cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
1951cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1952cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1953cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
1954cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
1955cd7a67a4SMauro Carvalho Chehab 	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
1956cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_mode = 0;
1957cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_int_upd_rate = 0;
1958cd7a67a4SMauro Carvalho Chehab 	u32 max_bit_rate = 0;
1959cd7a67a4SMauro Carvalho Chehab 	bool static_clk = false;
19609a0bf528SMauro Carvalho Chehab 
19619a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19629a0bf528SMauro Carvalho Chehab 
19639a0bf528SMauro Carvalho Chehab 	/* Check insertion of the Reed-Solomon parity bytes */
1964cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
19659a0bf528SMauro Carvalho Chehab 	if (status < 0)
19669a0bf528SMauro Carvalho Chehab 		goto error;
1967cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
19689a0bf528SMauro Carvalho Chehab 	if (status < 0)
19699a0bf528SMauro Carvalho Chehab 		goto error;
1970cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
1971cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
19725a7f7b79SMauro Carvalho Chehab 	if (state->m_insert_rs_byte) {
19739a0bf528SMauro Carvalho Chehab 		/* enable parity symbol forward */
1974cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
19759a0bf528SMauro Carvalho Chehab 		/* MVAL disable during parity bytes */
1976cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
19779a0bf528SMauro Carvalho Chehab 		/* TS burst length to 204 */
1978cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_burst_len = 204;
19799a0bf528SMauro Carvalho Chehab 	}
19809a0bf528SMauro Carvalho Chehab 
198139c1cb2bSJonathan McCrohan 	/* Check serial or parallel output */
1982cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
19835a7f7b79SMauro Carvalho Chehab 	if (!state->m_enable_parallel) {
19849a0bf528SMauro Carvalho Chehab 		/* MPEG data output is serial -> set ipr_mode[0] */
1985cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
19869a0bf528SMauro Carvalho Chehab 	}
19879a0bf528SMauro Carvalho Chehab 
1988cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
19899a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1990cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbt_bitrate;
1991cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 3;
1992cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xC00000;
1993cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbt_static_clk;
19949a0bf528SMauro Carvalho Chehab 		break;
1995df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
19969a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1997cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 0x0004;
1998cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
1999cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbc_bitrate;
2000cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbc_static_clk;
20019a0bf528SMauro Carvalho Chehab 		break;
20029a0bf528SMauro Carvalho Chehab 	default:
20039a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
20049a0bf528SMauro Carvalho Chehab 	}		/* switch (standard) */
20059a0bf528SMauro Carvalho Chehab 	if (status < 0)
20069a0bf528SMauro Carvalho Chehab 		goto error;
20079a0bf528SMauro Carvalho Chehab 
20089a0bf528SMauro Carvalho Chehab 	/* Configure DTO's */
2009cd7a67a4SMauro Carvalho Chehab 	if (static_clk) {
2010cd7a67a4SMauro Carvalho Chehab 		u32 bit_rate = 0;
20119a0bf528SMauro Carvalho Chehab 
20129a0bf528SMauro Carvalho Chehab 		/* Rational DTO for MCLK source (static MCLK rate),
20139a0bf528SMauro Carvalho Chehab 			Dynamic DTO for optimal grouping
20149a0bf528SMauro Carvalho Chehab 			(avoid intra-packet gaps),
20159a0bf528SMauro Carvalho Chehab 			DTO offset enable to sync TS burst with MSTRT */
2016cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
20179a0bf528SMauro Carvalho Chehab 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2018cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
20199a0bf528SMauro Carvalho Chehab 				FEC_OC_FCT_MODE_VIRT_ENA__M);
20209a0bf528SMauro Carvalho Chehab 
20219a0bf528SMauro Carvalho Chehab 		/* Check user defined bitrate */
2022cd7a67a4SMauro Carvalho Chehab 		bit_rate = max_bit_rate;
2023cd7a67a4SMauro Carvalho Chehab 		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
2024cd7a67a4SMauro Carvalho Chehab 			bit_rate = 75900000UL;
20259a0bf528SMauro Carvalho Chehab 		}
20269a0bf528SMauro Carvalho Chehab 		/* Rational DTO period:
20279a0bf528SMauro Carvalho Chehab 			dto_period = (Fsys / bitrate) - 2
20289a0bf528SMauro Carvalho Chehab 
2029cd7a67a4SMauro Carvalho Chehab 			result should be floored,
20309a0bf528SMauro Carvalho Chehab 			to make sure >= requested bitrate
20319a0bf528SMauro Carvalho Chehab 			*/
2032cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2033cd7a67a4SMauro Carvalho Chehab 						* 1000) / bit_rate);
2034cd7a67a4SMauro Carvalho Chehab 		if (fec_oc_dto_period <= 2)
2035cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period = 0;
20369a0bf528SMauro Carvalho Chehab 		else
2037cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period -= 2;
2038cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 8;
20399a0bf528SMauro Carvalho Chehab 	} else {
2040cd7a67a4SMauro Carvalho Chehab 		/* (commonAttr->static_clk == false) => dynamic mode */
2041cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2042cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2043cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 5;
20449a0bf528SMauro Carvalho Chehab 	}
20459a0bf528SMauro Carvalho Chehab 
20469a0bf528SMauro Carvalho Chehab 	/* Write appropriate registers with requested configuration */
2047cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
20489a0bf528SMauro Carvalho Chehab 	if (status < 0)
20499a0bf528SMauro Carvalho Chehab 		goto error;
2050cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
20519a0bf528SMauro Carvalho Chehab 	if (status < 0)
20529a0bf528SMauro Carvalho Chehab 		goto error;
2053cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
20549a0bf528SMauro Carvalho Chehab 	if (status < 0)
20559a0bf528SMauro Carvalho Chehab 		goto error;
2056cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
20579a0bf528SMauro Carvalho Chehab 	if (status < 0)
20589a0bf528SMauro Carvalho Chehab 		goto error;
2059cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
20609a0bf528SMauro Carvalho Chehab 	if (status < 0)
20619a0bf528SMauro Carvalho Chehab 		goto error;
2062cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
20639a0bf528SMauro Carvalho Chehab 	if (status < 0)
20649a0bf528SMauro Carvalho Chehab 		goto error;
20659a0bf528SMauro Carvalho Chehab 
20669a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
2067cd7a67a4SMauro Carvalho Chehab 	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
20689a0bf528SMauro Carvalho Chehab 	if (status < 0)
20699a0bf528SMauro Carvalho Chehab 		goto error;
2070ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2071ab5060cdSMauro Carvalho Chehab 			 fec_oc_tmd_int_upd_rate);
20729a0bf528SMauro Carvalho Chehab 	if (status < 0)
20739a0bf528SMauro Carvalho Chehab 		goto error;
2074cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
20759a0bf528SMauro Carvalho Chehab error:
20769a0bf528SMauro Carvalho Chehab 	if (status < 0)
20773a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
20789a0bf528SMauro Carvalho Chehab 	return status;
20799a0bf528SMauro Carvalho Chehab }
20809a0bf528SMauro Carvalho Chehab 
mpegts_configure_polarity(struct drxk_state * state)2081cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state)
20829a0bf528SMauro Carvalho Chehab {
2083cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_invert = 0;
20849a0bf528SMauro Carvalho Chehab 
20859a0bf528SMauro Carvalho Chehab 	/* Data mask for the output data byte */
2086cd7a67a4SMauro Carvalho Chehab 	u16 invert_data_mask =
20879a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
20889a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
20899a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
20909a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
20919a0bf528SMauro Carvalho Chehab 
20929a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
20939a0bf528SMauro Carvalho Chehab 
20949a0bf528SMauro Carvalho Chehab 	/* Control selective inversion of output bits */
2095cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
20965a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_data)
2097cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= invert_data_mask;
2098cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
20995a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_err)
2100cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2101cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
21025a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_str)
2103cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2104cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
21055a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_val)
2106cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2107cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
21085a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_clk)
2109cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
21109a0bf528SMauro Carvalho Chehab 
2111cd7a67a4SMauro Carvalho Chehab 	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
21129a0bf528SMauro Carvalho Chehab }
21139a0bf528SMauro Carvalho Chehab 
21149a0bf528SMauro Carvalho Chehab #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
21159a0bf528SMauro Carvalho Chehab 
set_agc_rf(struct drxk_state * state,struct s_cfg_agc * p_agc_cfg,bool is_dtv)2116cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state,
2117cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
21189a0bf528SMauro Carvalho Chehab {
21199a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
21209a0bf528SMauro Carvalho Chehab 	u16 data = 0;
2121cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_if_agc_settings;
21229a0bf528SMauro Carvalho Chehab 
21239a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21249a0bf528SMauro Carvalho Chehab 
2125cd7a67a4SMauro Carvalho Chehab 	if (p_agc_cfg == NULL)
21269a0bf528SMauro Carvalho Chehab 		goto error;
21279a0bf528SMauro Carvalho Chehab 
2128cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
21299a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
21309a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
21319a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
21329a0bf528SMauro Carvalho Chehab 		if (status < 0)
21339a0bf528SMauro Carvalho Chehab 			goto error;
21349a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
21359a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
21369a0bf528SMauro Carvalho Chehab 		if (status < 0)
21379a0bf528SMauro Carvalho Chehab 			goto error;
21389a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
21399a0bf528SMauro Carvalho Chehab 		if (status < 0)
21409a0bf528SMauro Carvalho Chehab 			goto error;
21419a0bf528SMauro Carvalho Chehab 
21429a0bf528SMauro Carvalho Chehab 		/* Enable SCU RF AGC loop */
21439a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
21449a0bf528SMauro Carvalho Chehab 
21459a0bf528SMauro Carvalho Chehab 		/* Polarity */
2146cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
21479a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21489a0bf528SMauro Carvalho Chehab 		else
21499a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21509a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
21519a0bf528SMauro Carvalho Chehab 		if (status < 0)
21529a0bf528SMauro Carvalho Chehab 			goto error;
21539a0bf528SMauro Carvalho Chehab 
21549a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
21559a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
21569a0bf528SMauro Carvalho Chehab 		if (status < 0)
21579a0bf528SMauro Carvalho Chehab 			goto error;
21589a0bf528SMauro Carvalho Chehab 
21599a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2160cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
21619a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
21629a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
21639a0bf528SMauro Carvalho Chehab 
21649a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
21659a0bf528SMauro Carvalho Chehab 		if (status < 0)
21669a0bf528SMauro Carvalho Chehab 			goto error;
21679a0bf528SMauro Carvalho Chehab 
2168cd7a67a4SMauro Carvalho Chehab 		if (is_dvbt(state))
2169cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2170cd7a67a4SMauro Carvalho Chehab 		else if (is_qam(state))
2171cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_qam_if_agc_cfg;
21729a0bf528SMauro Carvalho Chehab 		else
2173cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_atv_if_agc_cfg;
2174cd7a67a4SMauro Carvalho Chehab 		if (p_if_agc_settings == NULL) {
21759a0bf528SMauro Carvalho Chehab 			status = -EINVAL;
21769a0bf528SMauro Carvalho Chehab 			goto error;
21779a0bf528SMauro Carvalho Chehab 		}
21789a0bf528SMauro Carvalho Chehab 
21799a0bf528SMauro Carvalho Chehab 		/* Set TOP, only if IF-AGC is in AUTO mode */
218089fffac8SMauro Carvalho Chehab 		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
2181ab5060cdSMauro Carvalho Chehab 			status = write16(state,
2182ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2183ab5060cdSMauro Carvalho Chehab 					 p_agc_cfg->top);
21849a0bf528SMauro Carvalho Chehab 			if (status < 0)
21859a0bf528SMauro Carvalho Chehab 				goto error;
218689fffac8SMauro Carvalho Chehab 		}
21879a0bf528SMauro Carvalho Chehab 
21889a0bf528SMauro Carvalho Chehab 		/* Cut-Off current */
2189ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2190ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->cut_off_current);
21919a0bf528SMauro Carvalho Chehab 		if (status < 0)
21929a0bf528SMauro Carvalho Chehab 			goto error;
21939a0bf528SMauro Carvalho Chehab 
21949a0bf528SMauro Carvalho Chehab 		/* Max. output level */
2195ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2196ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->max_output_level);
21979a0bf528SMauro Carvalho Chehab 		if (status < 0)
21989a0bf528SMauro Carvalho Chehab 			goto error;
21999a0bf528SMauro Carvalho Chehab 
22009a0bf528SMauro Carvalho Chehab 		break;
22019a0bf528SMauro Carvalho Chehab 
22029a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
22039a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
22049a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22059a0bf528SMauro Carvalho Chehab 		if (status < 0)
22069a0bf528SMauro Carvalho Chehab 			goto error;
22079a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22089a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22099a0bf528SMauro Carvalho Chehab 		if (status < 0)
22109a0bf528SMauro Carvalho Chehab 			goto error;
22119a0bf528SMauro Carvalho Chehab 
22129a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22139a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22149a0bf528SMauro Carvalho Chehab 		if (status < 0)
22159a0bf528SMauro Carvalho Chehab 			goto error;
22169a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2217cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
22189a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22199a0bf528SMauro Carvalho Chehab 		else
22209a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22219a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22229a0bf528SMauro Carvalho Chehab 		if (status < 0)
22239a0bf528SMauro Carvalho Chehab 			goto error;
22249a0bf528SMauro Carvalho Chehab 
22259a0bf528SMauro Carvalho Chehab 		/* SCU c.o.c. to 0, enabling full control range */
22269a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
22279a0bf528SMauro Carvalho Chehab 		if (status < 0)
22289a0bf528SMauro Carvalho Chehab 			goto error;
22299a0bf528SMauro Carvalho Chehab 
22309a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2231ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2232ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
22339a0bf528SMauro Carvalho Chehab 		if (status < 0)
22349a0bf528SMauro Carvalho Chehab 			goto error;
22359a0bf528SMauro Carvalho Chehab 		break;
22369a0bf528SMauro Carvalho Chehab 
22379a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
22389a0bf528SMauro Carvalho Chehab 		/* Disable RF AGC DAC */
22399a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22409a0bf528SMauro Carvalho Chehab 		if (status < 0)
22419a0bf528SMauro Carvalho Chehab 			goto error;
22429a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22439a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22449a0bf528SMauro Carvalho Chehab 		if (status < 0)
22459a0bf528SMauro Carvalho Chehab 			goto error;
22469a0bf528SMauro Carvalho Chehab 
22479a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22489a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22499a0bf528SMauro Carvalho Chehab 		if (status < 0)
22509a0bf528SMauro Carvalho Chehab 			goto error;
22519a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22529a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22539a0bf528SMauro Carvalho Chehab 		if (status < 0)
22549a0bf528SMauro Carvalho Chehab 			goto error;
22559a0bf528SMauro Carvalho Chehab 		break;
22569a0bf528SMauro Carvalho Chehab 
22579a0bf528SMauro Carvalho Chehab 	default:
22589a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
22599a0bf528SMauro Carvalho Chehab 
22609a0bf528SMauro Carvalho Chehab 	}
22619a0bf528SMauro Carvalho Chehab error:
22629a0bf528SMauro Carvalho Chehab 	if (status < 0)
22633a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
22649a0bf528SMauro Carvalho Chehab 	return status;
22659a0bf528SMauro Carvalho Chehab }
22669a0bf528SMauro Carvalho Chehab 
22679a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
22689a0bf528SMauro Carvalho Chehab 
set_agc_if(struct drxk_state * state,struct s_cfg_agc * p_agc_cfg,bool is_dtv)2269cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state,
2270cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
22719a0bf528SMauro Carvalho Chehab {
22729a0bf528SMauro Carvalho Chehab 	u16 data = 0;
22739a0bf528SMauro Carvalho Chehab 	int status = 0;
2274cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_rf_agc_settings;
22759a0bf528SMauro Carvalho Chehab 
22769a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
22779a0bf528SMauro Carvalho Chehab 
2278cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
22799a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
22809a0bf528SMauro Carvalho Chehab 
22819a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
22829a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22839a0bf528SMauro Carvalho Chehab 		if (status < 0)
22849a0bf528SMauro Carvalho Chehab 			goto error;
22859a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
22869a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22879a0bf528SMauro Carvalho Chehab 		if (status < 0)
22889a0bf528SMauro Carvalho Chehab 			goto error;
22899a0bf528SMauro Carvalho Chehab 
22909a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22919a0bf528SMauro Carvalho Chehab 		if (status < 0)
22929a0bf528SMauro Carvalho Chehab 			goto error;
22939a0bf528SMauro Carvalho Chehab 
22949a0bf528SMauro Carvalho Chehab 		/* Enable SCU IF AGC loop */
22959a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
22969a0bf528SMauro Carvalho Chehab 
22979a0bf528SMauro Carvalho Chehab 		/* Polarity */
2298cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
22999a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23009a0bf528SMauro Carvalho Chehab 		else
23019a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23029a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23039a0bf528SMauro Carvalho Chehab 		if (status < 0)
23049a0bf528SMauro Carvalho Chehab 			goto error;
23059a0bf528SMauro Carvalho Chehab 
23069a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
23079a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
23089a0bf528SMauro Carvalho Chehab 		if (status < 0)
23099a0bf528SMauro Carvalho Chehab 			goto error;
23109a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2311cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
23129a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
23139a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
23149a0bf528SMauro Carvalho Chehab 
23159a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
23169a0bf528SMauro Carvalho Chehab 		if (status < 0)
23179a0bf528SMauro Carvalho Chehab 			goto error;
23189a0bf528SMauro Carvalho Chehab 
2319cd7a67a4SMauro Carvalho Chehab 		if (is_qam(state))
2320cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
23219a0bf528SMauro Carvalho Chehab 		else
2322cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2323cd7a67a4SMauro Carvalho Chehab 		if (p_rf_agc_settings == NULL)
23249a0bf528SMauro Carvalho Chehab 			return -1;
23259a0bf528SMauro Carvalho Chehab 		/* Restore TOP */
2326ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2327ab5060cdSMauro Carvalho Chehab 				 p_rf_agc_settings->top);
23289a0bf528SMauro Carvalho Chehab 		if (status < 0)
23299a0bf528SMauro Carvalho Chehab 			goto error;
23309a0bf528SMauro Carvalho Chehab 		break;
23319a0bf528SMauro Carvalho Chehab 
23329a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
23339a0bf528SMauro Carvalho Chehab 
23349a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23359a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23369a0bf528SMauro Carvalho Chehab 		if (status < 0)
23379a0bf528SMauro Carvalho Chehab 			goto error;
23389a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23399a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23409a0bf528SMauro Carvalho Chehab 		if (status < 0)
23419a0bf528SMauro Carvalho Chehab 			goto error;
23429a0bf528SMauro Carvalho Chehab 
23439a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23449a0bf528SMauro Carvalho Chehab 		if (status < 0)
23459a0bf528SMauro Carvalho Chehab 			goto error;
23469a0bf528SMauro Carvalho Chehab 
23479a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23489a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23499a0bf528SMauro Carvalho Chehab 
23509a0bf528SMauro Carvalho Chehab 		/* Polarity */
2351cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23529a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23539a0bf528SMauro Carvalho Chehab 		else
23549a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23559a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23569a0bf528SMauro Carvalho Chehab 		if (status < 0)
23579a0bf528SMauro Carvalho Chehab 			goto error;
23589a0bf528SMauro Carvalho Chehab 
23599a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2360ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2361ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
23629a0bf528SMauro Carvalho Chehab 		if (status < 0)
23639a0bf528SMauro Carvalho Chehab 			goto error;
23649a0bf528SMauro Carvalho Chehab 		break;
23659a0bf528SMauro Carvalho Chehab 
23669a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
23679a0bf528SMauro Carvalho Chehab 
23689a0bf528SMauro Carvalho Chehab 		/* Disable If AGC DAC */
23699a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23709a0bf528SMauro Carvalho Chehab 		if (status < 0)
23719a0bf528SMauro Carvalho Chehab 			goto error;
23729a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23739a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23749a0bf528SMauro Carvalho Chehab 		if (status < 0)
23759a0bf528SMauro Carvalho Chehab 			goto error;
23769a0bf528SMauro Carvalho Chehab 
23779a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23789a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23799a0bf528SMauro Carvalho Chehab 		if (status < 0)
23809a0bf528SMauro Carvalho Chehab 			goto error;
23819a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23829a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23839a0bf528SMauro Carvalho Chehab 		if (status < 0)
23849a0bf528SMauro Carvalho Chehab 			goto error;
23859a0bf528SMauro Carvalho Chehab 		break;
2386cd7a67a4SMauro Carvalho Chehab 	}		/* switch (agcSettingsIf->ctrl_mode) */
23879a0bf528SMauro Carvalho Chehab 
23889a0bf528SMauro Carvalho Chehab 	/* always set the top to support
23899a0bf528SMauro Carvalho Chehab 		configurations without if-loop */
2390cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
23919a0bf528SMauro Carvalho Chehab error:
23929a0bf528SMauro Carvalho Chehab 	if (status < 0)
23933a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
23949a0bf528SMauro Carvalho Chehab 	return status;
23959a0bf528SMauro Carvalho Chehab }
23969a0bf528SMauro Carvalho Chehab 
get_qam_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2397cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state,
2398cd7a67a4SMauro Carvalho Chehab 			       s32 *p_signal_to_noise)
23999a0bf528SMauro Carvalho Chehab {
24009a0bf528SMauro Carvalho Chehab 	int status = 0;
2401cd7a67a4SMauro Carvalho Chehab 	u16 qam_sl_err_power = 0;	/* accum. error between
24029a0bf528SMauro Carvalho Chehab 					raw and sliced symbols */
2403cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
24049a0bf528SMauro Carvalho Chehab 					QAM modulation */
2405cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_mer = 0;	/* QAM MER */
24069a0bf528SMauro Carvalho Chehab 
24079a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24089a0bf528SMauro Carvalho Chehab 
24099a0bf528SMauro Carvalho Chehab 	/* MER calculation */
24109a0bf528SMauro Carvalho Chehab 
24119a0bf528SMauro Carvalho Chehab 	/* get the register value needed for MER */
2412cd7a67a4SMauro Carvalho Chehab 	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
24139a0bf528SMauro Carvalho Chehab 	if (status < 0) {
24143a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24159a0bf528SMauro Carvalho Chehab 		return -EINVAL;
24169a0bf528SMauro Carvalho Chehab 	}
24179a0bf528SMauro Carvalho Chehab 
24189a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
24199a0bf528SMauro Carvalho Chehab 	case QAM_16:
2420cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
24219a0bf528SMauro Carvalho Chehab 		break;
24229a0bf528SMauro Carvalho Chehab 	case QAM_32:
2423cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
24249a0bf528SMauro Carvalho Chehab 		break;
24259a0bf528SMauro Carvalho Chehab 	case QAM_64:
2426cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
24279a0bf528SMauro Carvalho Chehab 		break;
24289a0bf528SMauro Carvalho Chehab 	case QAM_128:
2429cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
24309a0bf528SMauro Carvalho Chehab 		break;
24319a0bf528SMauro Carvalho Chehab 	default:
24329a0bf528SMauro Carvalho Chehab 	case QAM_256:
2433cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
24349a0bf528SMauro Carvalho Chehab 		break;
24359a0bf528SMauro Carvalho Chehab 	}
24369a0bf528SMauro Carvalho Chehab 
2437cd7a67a4SMauro Carvalho Chehab 	if (qam_sl_err_power > 0) {
2438cd7a67a4SMauro Carvalho Chehab 		qam_sl_mer = log10times100(qam_sl_sig_power) -
2439cd7a67a4SMauro Carvalho Chehab 			log10times100((u32) qam_sl_err_power);
24409a0bf528SMauro Carvalho Chehab 	}
2441cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = qam_sl_mer;
24429a0bf528SMauro Carvalho Chehab 
24439a0bf528SMauro Carvalho Chehab 	return status;
24449a0bf528SMauro Carvalho Chehab }
24459a0bf528SMauro Carvalho Chehab 
get_dvbt_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2446cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state,
2447cd7a67a4SMauro Carvalho Chehab 				s32 *p_signal_to_noise)
24489a0bf528SMauro Carvalho Chehab {
24499a0bf528SMauro Carvalho Chehab 	int status;
2450cd7a67a4SMauro Carvalho Chehab 	u16 reg_data = 0;
2451cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_i = 0;
2452cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_q = 0;
2453cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_sqr_err_exp = 0;
2454cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_tps_pwr_ofs = 0;
2455cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_req_smb_cnt = 0;
2456cd7a67a4SMauro Carvalho Chehab 	u32 tps_cnt = 0;
2457cd7a67a4SMauro Carvalho Chehab 	u32 sqr_err_iq = 0;
24589a0bf528SMauro Carvalho Chehab 	u32 a = 0;
24599a0bf528SMauro Carvalho Chehab 	u32 b = 0;
24609a0bf528SMauro Carvalho Chehab 	u32 c = 0;
2461cd7a67a4SMauro Carvalho Chehab 	u32 i_mer = 0;
2462cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
24639a0bf528SMauro Carvalho Chehab 
24649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24659a0bf528SMauro Carvalho Chehab 
2466ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2467ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_tps_pwr_ofs);
24689a0bf528SMauro Carvalho Chehab 	if (status < 0)
24699a0bf528SMauro Carvalho Chehab 		goto error;
2470ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2471ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_req_smb_cnt);
24729a0bf528SMauro Carvalho Chehab 	if (status < 0)
24739a0bf528SMauro Carvalho Chehab 		goto error;
2474ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2475ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_sqr_err_exp);
24769a0bf528SMauro Carvalho Chehab 	if (status < 0)
24779a0bf528SMauro Carvalho Chehab 		goto error;
2478ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2479ab5060cdSMauro Carvalho Chehab 			&reg_data);
24809a0bf528SMauro Carvalho Chehab 	if (status < 0)
24819a0bf528SMauro Carvalho Chehab 		goto error;
24829a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_I operational range */
2483cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_i = (u32) reg_data;
2484cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2485cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2486cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_i += 0x00010000UL;
24879a0bf528SMauro Carvalho Chehab 	}
2488cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
24899a0bf528SMauro Carvalho Chehab 	if (status < 0)
24909a0bf528SMauro Carvalho Chehab 		goto error;
24919a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_Q operational range */
2492cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_q = (u32) reg_data;
2493cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2494cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
2495cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_q += 0x00010000UL;
24969a0bf528SMauro Carvalho Chehab 
2497ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2498ab5060cdSMauro Carvalho Chehab 			&transmission_params);
24999a0bf528SMauro Carvalho Chehab 	if (status < 0)
25009a0bf528SMauro Carvalho Chehab 		goto error;
25019a0bf528SMauro Carvalho Chehab 
25029a0bf528SMauro Carvalho Chehab 	/* Check input data for MER */
25039a0bf528SMauro Carvalho Chehab 
25049a0bf528SMauro Carvalho Chehab 	/* MER calculation (in 0.1 dB) without math.h */
2505cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2506cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
2507cd7a67a4SMauro Carvalho Chehab 	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
25089a0bf528SMauro Carvalho Chehab 		/* No error at all, this must be the HW reset value
25099a0bf528SMauro Carvalho Chehab 			* Apparently no first measurement yet
25109a0bf528SMauro Carvalho Chehab 			* Set MER to 0.0 */
2511cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
25129a0bf528SMauro Carvalho Chehab 	} else {
2513cd7a67a4SMauro Carvalho Chehab 		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2514cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_sqr_err_exp;
2515cd7a67a4SMauro Carvalho Chehab 		if ((transmission_params &
25169a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
25179a0bf528SMauro Carvalho Chehab 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2518cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 17;
25199a0bf528SMauro Carvalho Chehab 		else
2520cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 68;
25219a0bf528SMauro Carvalho Chehab 
25229a0bf528SMauro Carvalho Chehab 		/* IMER = 100 * log10 (x)
2523cd7a67a4SMauro Carvalho Chehab 			where x = (eq_reg_td_tps_pwr_ofs^2 *
2524cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
25259a0bf528SMauro Carvalho Chehab 
25269a0bf528SMauro Carvalho Chehab 			=> IMER = a + b -c
2527cd7a67a4SMauro Carvalho Chehab 			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2528cd7a67a4SMauro Carvalho Chehab 			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2529cd7a67a4SMauro Carvalho Chehab 			c = 100 * log10 (sqr_err_iq)
25309a0bf528SMauro Carvalho Chehab 			*/
25319a0bf528SMauro Carvalho Chehab 
25329a0bf528SMauro Carvalho Chehab 		/* log(x) x = 9bits * 9bits->18 bits  */
2533cd7a67a4SMauro Carvalho Chehab 		a = log10times100(eq_reg_td_tps_pwr_ofs *
2534cd7a67a4SMauro Carvalho Chehab 					eq_reg_td_tps_pwr_ofs);
25359a0bf528SMauro Carvalho Chehab 		/* log(x) x = 16bits * 7bits->23 bits  */
2536cd7a67a4SMauro Carvalho Chehab 		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
25379a0bf528SMauro Carvalho Chehab 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
2538cd7a67a4SMauro Carvalho Chehab 		c = log10times100(sqr_err_iq);
25399a0bf528SMauro Carvalho Chehab 
2540cd7a67a4SMauro Carvalho Chehab 		i_mer = a + b - c;
25419a0bf528SMauro Carvalho Chehab 	}
2542cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = i_mer;
25439a0bf528SMauro Carvalho Chehab 
25449a0bf528SMauro Carvalho Chehab error:
25459a0bf528SMauro Carvalho Chehab 	if (status < 0)
25463a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
25479a0bf528SMauro Carvalho Chehab 	return status;
25489a0bf528SMauro Carvalho Chehab }
25499a0bf528SMauro Carvalho Chehab 
get_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2550cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
25519a0bf528SMauro Carvalho Chehab {
25529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25539a0bf528SMauro Carvalho Chehab 
2554cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = 0;
2555cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
25569a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2557cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
25589a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
25599a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2560cd7a67a4SMauro Carvalho Chehab 		return get_qam_signal_to_noise(state, p_signal_to_noise);
25619a0bf528SMauro Carvalho Chehab 	default:
25629a0bf528SMauro Carvalho Chehab 		break;
25639a0bf528SMauro Carvalho Chehab 	}
25649a0bf528SMauro Carvalho Chehab 	return 0;
25659a0bf528SMauro Carvalho Chehab }
25669a0bf528SMauro Carvalho Chehab 
25679a0bf528SMauro Carvalho Chehab #if 0
2568cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
25699a0bf528SMauro Carvalho Chehab {
25709a0bf528SMauro Carvalho Chehab 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
25719a0bf528SMauro Carvalho Chehab 	int status = 0;
25729a0bf528SMauro Carvalho Chehab 
25739a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25749a0bf528SMauro Carvalho Chehab 
25759a0bf528SMauro Carvalho Chehab 	static s32 QE_SN[] = {
25769a0bf528SMauro Carvalho Chehab 		51,		/* QPSK 1/2 */
25779a0bf528SMauro Carvalho Chehab 		69,		/* QPSK 2/3 */
25789a0bf528SMauro Carvalho Chehab 		79,		/* QPSK 3/4 */
25799a0bf528SMauro Carvalho Chehab 		89,		/* QPSK 5/6 */
25809a0bf528SMauro Carvalho Chehab 		97,		/* QPSK 7/8 */
25819a0bf528SMauro Carvalho Chehab 		108,		/* 16-QAM 1/2 */
25829a0bf528SMauro Carvalho Chehab 		131,		/* 16-QAM 2/3 */
25839a0bf528SMauro Carvalho Chehab 		146,		/* 16-QAM 3/4 */
25849a0bf528SMauro Carvalho Chehab 		156,		/* 16-QAM 5/6 */
25859a0bf528SMauro Carvalho Chehab 		160,		/* 16-QAM 7/8 */
25869a0bf528SMauro Carvalho Chehab 		165,		/* 64-QAM 1/2 */
25879a0bf528SMauro Carvalho Chehab 		187,		/* 64-QAM 2/3 */
25889a0bf528SMauro Carvalho Chehab 		202,		/* 64-QAM 3/4 */
25899a0bf528SMauro Carvalho Chehab 		216,		/* 64-QAM 5/6 */
25909a0bf528SMauro Carvalho Chehab 		225,		/* 64-QAM 7/8 */
25919a0bf528SMauro Carvalho Chehab 	};
25929a0bf528SMauro Carvalho Chehab 
2593cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
25949a0bf528SMauro Carvalho Chehab 
25959a0bf528SMauro Carvalho Chehab 	do {
2596cd7a67a4SMauro Carvalho Chehab 		s32 signal_to_noise = 0;
2597cd7a67a4SMauro Carvalho Chehab 		u16 constellation = 0;
2598cd7a67a4SMauro Carvalho Chehab 		u16 code_rate = 0;
2599cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel;
2600cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality;
26019a0bf528SMauro Carvalho Chehab 
2602cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
26039a0bf528SMauro Carvalho Chehab 		if (status < 0)
26049a0bf528SMauro Carvalho Chehab 			break;
2605ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2606ab5060cdSMauro Carvalho Chehab 				&constellation);
26079a0bf528SMauro Carvalho Chehab 		if (status < 0)
26089a0bf528SMauro Carvalho Chehab 			break;
2609cd7a67a4SMauro Carvalho Chehab 		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
26109a0bf528SMauro Carvalho Chehab 
2611ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2612ab5060cdSMauro Carvalho Chehab 				&code_rate);
26139a0bf528SMauro Carvalho Chehab 		if (status < 0)
26149a0bf528SMauro Carvalho Chehab 			break;
2615cd7a67a4SMauro Carvalho Chehab 		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
26169a0bf528SMauro Carvalho Chehab 
2617cd7a67a4SMauro Carvalho Chehab 		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2618cd7a67a4SMauro Carvalho Chehab 		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
26199a0bf528SMauro Carvalho Chehab 			break;
2620cd7a67a4SMauro Carvalho Chehab 		signal_to_noise_rel = signal_to_noise -
2621cd7a67a4SMauro Carvalho Chehab 		    QE_SN[constellation * 5 + code_rate];
2622cd7a67a4SMauro Carvalho Chehab 		ber_quality = 100;
26239a0bf528SMauro Carvalho Chehab 
2624cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2625cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2626cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2627cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2628cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26299a0bf528SMauro Carvalho Chehab 		else
2630cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26319a0bf528SMauro Carvalho Chehab 	} while (0);
26329a0bf528SMauro Carvalho Chehab 	return 0;
26339a0bf528SMauro Carvalho Chehab };
26349a0bf528SMauro Carvalho Chehab 
2635cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
26369a0bf528SMauro Carvalho Chehab {
26379a0bf528SMauro Carvalho Chehab 	int status = 0;
2638cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26399a0bf528SMauro Carvalho Chehab 
26409a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26419a0bf528SMauro Carvalho Chehab 
26429a0bf528SMauro Carvalho Chehab 	do {
2643cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise = 0;
2644cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality = 100;
2645cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel = 0;
26469a0bf528SMauro Carvalho Chehab 
2647cd7a67a4SMauro Carvalho Chehab 		status = get_qam_signal_to_noise(state, &signal_to_noise);
26489a0bf528SMauro Carvalho Chehab 		if (status < 0)
26499a0bf528SMauro Carvalho Chehab 			break;
26509a0bf528SMauro Carvalho Chehab 
26519a0bf528SMauro Carvalho Chehab 		switch (state->props.modulation) {
26529a0bf528SMauro Carvalho Chehab 		case QAM_16:
2653cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 200;
26549a0bf528SMauro Carvalho Chehab 			break;
26559a0bf528SMauro Carvalho Chehab 		case QAM_32:
2656cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 230;
26579a0bf528SMauro Carvalho Chehab 			break;	/* Not in NorDig */
26589a0bf528SMauro Carvalho Chehab 		case QAM_64:
2659cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 260;
26609a0bf528SMauro Carvalho Chehab 			break;
26619a0bf528SMauro Carvalho Chehab 		case QAM_128:
2662cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 290;
26639a0bf528SMauro Carvalho Chehab 			break;
26649a0bf528SMauro Carvalho Chehab 		default:
26659a0bf528SMauro Carvalho Chehab 		case QAM_256:
2666cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 320;
26679a0bf528SMauro Carvalho Chehab 			break;
26689a0bf528SMauro Carvalho Chehab 		}
26699a0bf528SMauro Carvalho Chehab 
2670cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2671cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2672cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2673cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2674cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26759a0bf528SMauro Carvalho Chehab 		else
2676cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26779a0bf528SMauro Carvalho Chehab 	} while (0);
26789a0bf528SMauro Carvalho Chehab 
26799a0bf528SMauro Carvalho Chehab 	return status;
26809a0bf528SMauro Carvalho Chehab }
26819a0bf528SMauro Carvalho Chehab 
2682cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality)
26839a0bf528SMauro Carvalho Chehab {
26849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26859a0bf528SMauro Carvalho Chehab 
2686cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
26879a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2688cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_quality(state, p_quality);
26899a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
2690cd7a67a4SMauro Carvalho Chehab 		return get_dvbc_quality(state, p_quality);
26919a0bf528SMauro Carvalho Chehab 	default:
26929a0bf528SMauro Carvalho Chehab 		break;
26939a0bf528SMauro Carvalho Chehab 	}
26949a0bf528SMauro Carvalho Chehab 
26959a0bf528SMauro Carvalho Chehab 	return 0;
26969a0bf528SMauro Carvalho Chehab }
26979a0bf528SMauro Carvalho Chehab #endif
26989a0bf528SMauro Carvalho Chehab 
26999a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
27009a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
27019a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A   0x420060
27029a0bf528SMauro Carvalho Chehab 
27039a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
27049a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
27059a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
27069a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
27079a0bf528SMauro Carvalho Chehab 
27089a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
27099a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
27109a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
27119a0bf528SMauro Carvalho Chehab 
ConfigureI2CBridge(struct drxk_state * state,bool b_enable_bridge)2712cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
27139a0bf528SMauro Carvalho Chehab {
27149a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27159a0bf528SMauro Carvalho Chehab 
27169a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27179a0bf528SMauro Carvalho Chehab 
2718cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
27199a0bf528SMauro Carvalho Chehab 		return 0;
2720cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_POWERED_DOWN)
27219a0bf528SMauro Carvalho Chehab 		goto error;
27229a0bf528SMauro Carvalho Chehab 
27239a0bf528SMauro Carvalho Chehab 	if (state->no_i2c_bridge)
27249a0bf528SMauro Carvalho Chehab 		return 0;
27259a0bf528SMauro Carvalho Chehab 
2726ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2727ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
27289a0bf528SMauro Carvalho Chehab 	if (status < 0)
27299a0bf528SMauro Carvalho Chehab 		goto error;
2730cd7a67a4SMauro Carvalho Chehab 	if (b_enable_bridge) {
2731ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2732ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
27339a0bf528SMauro Carvalho Chehab 		if (status < 0)
27349a0bf528SMauro Carvalho Chehab 			goto error;
27359a0bf528SMauro Carvalho Chehab 	} else {
2736ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2737ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
27389a0bf528SMauro Carvalho Chehab 		if (status < 0)
27399a0bf528SMauro Carvalho Chehab 			goto error;
27409a0bf528SMauro Carvalho Chehab 	}
27419a0bf528SMauro Carvalho Chehab 
2742b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
27439a0bf528SMauro Carvalho Chehab 
27449a0bf528SMauro Carvalho Chehab error:
27459a0bf528SMauro Carvalho Chehab 	if (status < 0)
27463a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27479a0bf528SMauro Carvalho Chehab 	return status;
27489a0bf528SMauro Carvalho Chehab }
27499a0bf528SMauro Carvalho Chehab 
set_pre_saw(struct drxk_state * state,struct s_cfg_pre_saw * p_pre_saw_cfg)2750cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state,
2751cd7a67a4SMauro Carvalho Chehab 		     struct s_cfg_pre_saw *p_pre_saw_cfg)
27529a0bf528SMauro Carvalho Chehab {
27539a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27549a0bf528SMauro Carvalho Chehab 
27559a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27569a0bf528SMauro Carvalho Chehab 
2757cd7a67a4SMauro Carvalho Chehab 	if ((p_pre_saw_cfg == NULL)
2758cd7a67a4SMauro Carvalho Chehab 	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
27599a0bf528SMauro Carvalho Chehab 		goto error;
27609a0bf528SMauro Carvalho Chehab 
2761cd7a67a4SMauro Carvalho Chehab 	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
27629a0bf528SMauro Carvalho Chehab error:
27639a0bf528SMauro Carvalho Chehab 	if (status < 0)
27643a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27659a0bf528SMauro Carvalho Chehab 	return status;
27669a0bf528SMauro Carvalho Chehab }
27679a0bf528SMauro Carvalho Chehab 
bl_direct_cmd(struct drxk_state * state,u32 target_addr,u16 rom_offset,u16 nr_of_elements,u32 time_out)2768cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2769cd7a67a4SMauro Carvalho Chehab 		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
27709a0bf528SMauro Carvalho Chehab {
2771cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
2772cd7a67a4SMauro Carvalho Chehab 	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2773cd7a67a4SMauro Carvalho Chehab 	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
27749a0bf528SMauro Carvalho Chehab 	int status;
27759a0bf528SMauro Carvalho Chehab 	unsigned long end;
27769a0bf528SMauro Carvalho Chehab 
27779a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27789a0bf528SMauro Carvalho Chehab 
27799a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
27809a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
27819a0bf528SMauro Carvalho Chehab 	if (status < 0)
27829a0bf528SMauro Carvalho Chehab 		goto error;
27839a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
27849a0bf528SMauro Carvalho Chehab 	if (status < 0)
27859a0bf528SMauro Carvalho Chehab 		goto error;
27869a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
27879a0bf528SMauro Carvalho Chehab 	if (status < 0)
27889a0bf528SMauro Carvalho Chehab 		goto error;
2789cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
27909a0bf528SMauro Carvalho Chehab 	if (status < 0)
27919a0bf528SMauro Carvalho Chehab 		goto error;
2792cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
27939a0bf528SMauro Carvalho Chehab 	if (status < 0)
27949a0bf528SMauro Carvalho Chehab 		goto error;
27959a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
27969a0bf528SMauro Carvalho Chehab 	if (status < 0)
27979a0bf528SMauro Carvalho Chehab 		goto error;
27989a0bf528SMauro Carvalho Chehab 
2799cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
28009a0bf528SMauro Carvalho Chehab 	do {
2801cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
28029a0bf528SMauro Carvalho Chehab 		if (status < 0)
28039a0bf528SMauro Carvalho Chehab 			goto error;
2804cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
2805cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
28063a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
28079a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
28089a0bf528SMauro Carvalho Chehab 		goto error2;
28099a0bf528SMauro Carvalho Chehab 	}
28109a0bf528SMauro Carvalho Chehab error:
28119a0bf528SMauro Carvalho Chehab 	if (status < 0)
28123a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28139a0bf528SMauro Carvalho Chehab error2:
28149a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
28159a0bf528SMauro Carvalho Chehab 	return status;
28169a0bf528SMauro Carvalho Chehab 
28179a0bf528SMauro Carvalho Chehab }
28189a0bf528SMauro Carvalho Chehab 
adc_sync_measurement(struct drxk_state * state,u16 * count)2819cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count)
28209a0bf528SMauro Carvalho Chehab {
28219a0bf528SMauro Carvalho Chehab 	u16 data = 0;
28229a0bf528SMauro Carvalho Chehab 	int status;
28239a0bf528SMauro Carvalho Chehab 
28249a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28259a0bf528SMauro Carvalho Chehab 
2826cd7a67a4SMauro Carvalho Chehab 	/* start measurement */
28279a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
28289a0bf528SMauro Carvalho Chehab 	if (status < 0)
28299a0bf528SMauro Carvalho Chehab 		goto error;
28309a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 1);
28319a0bf528SMauro Carvalho Chehab 	if (status < 0)
28329a0bf528SMauro Carvalho Chehab 		goto error;
28339a0bf528SMauro Carvalho Chehab 
28349a0bf528SMauro Carvalho Chehab 	*count = 0;
28359a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE0__A, &data);
28369a0bf528SMauro Carvalho Chehab 	if (status < 0)
28379a0bf528SMauro Carvalho Chehab 		goto error;
28389a0bf528SMauro Carvalho Chehab 	if (data == 127)
28399a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28409a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE1__A, &data);
28419a0bf528SMauro Carvalho Chehab 	if (status < 0)
28429a0bf528SMauro Carvalho Chehab 		goto error;
28439a0bf528SMauro Carvalho Chehab 	if (data == 127)
28449a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28459a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE2__A, &data);
28469a0bf528SMauro Carvalho Chehab 	if (status < 0)
28479a0bf528SMauro Carvalho Chehab 		goto error;
28489a0bf528SMauro Carvalho Chehab 	if (data == 127)
28499a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28509a0bf528SMauro Carvalho Chehab 
28519a0bf528SMauro Carvalho Chehab error:
28529a0bf528SMauro Carvalho Chehab 	if (status < 0)
28533a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28549a0bf528SMauro Carvalho Chehab 	return status;
28559a0bf528SMauro Carvalho Chehab }
28569a0bf528SMauro Carvalho Chehab 
adc_synchronization(struct drxk_state * state)2857cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state)
28589a0bf528SMauro Carvalho Chehab {
28599a0bf528SMauro Carvalho Chehab 	u16 count = 0;
28609a0bf528SMauro Carvalho Chehab 	int status;
28619a0bf528SMauro Carvalho Chehab 
28629a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28639a0bf528SMauro Carvalho Chehab 
2864cd7a67a4SMauro Carvalho Chehab 	status = adc_sync_measurement(state, &count);
28659a0bf528SMauro Carvalho Chehab 	if (status < 0)
28669a0bf528SMauro Carvalho Chehab 		goto error;
28679a0bf528SMauro Carvalho Chehab 
28689a0bf528SMauro Carvalho Chehab 	if (count == 1) {
286939c1cb2bSJonathan McCrohan 		/* Try sampling on a different edge */
2870cd7a67a4SMauro Carvalho Chehab 		u16 clk_neg = 0;
28719a0bf528SMauro Carvalho Chehab 
2872cd7a67a4SMauro Carvalho Chehab 		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
28739a0bf528SMauro Carvalho Chehab 		if (status < 0)
28749a0bf528SMauro Carvalho Chehab 			goto error;
2875cd7a67a4SMauro Carvalho Chehab 		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
28769a0bf528SMauro Carvalho Chehab 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2877cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2878cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
28799a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
28809a0bf528SMauro Carvalho Chehab 		} else {
2881cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2882cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
28839a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
28849a0bf528SMauro Carvalho Chehab 		}
2885cd7a67a4SMauro Carvalho Chehab 		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
28869a0bf528SMauro Carvalho Chehab 		if (status < 0)
28879a0bf528SMauro Carvalho Chehab 			goto error;
2888cd7a67a4SMauro Carvalho Chehab 		status = adc_sync_measurement(state, &count);
28899a0bf528SMauro Carvalho Chehab 		if (status < 0)
28909a0bf528SMauro Carvalho Chehab 			goto error;
28919a0bf528SMauro Carvalho Chehab 	}
28929a0bf528SMauro Carvalho Chehab 
28939a0bf528SMauro Carvalho Chehab 	if (count < 2)
28949a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
28959a0bf528SMauro Carvalho Chehab error:
28969a0bf528SMauro Carvalho Chehab 	if (status < 0)
28973a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28989a0bf528SMauro Carvalho Chehab 	return status;
28999a0bf528SMauro Carvalho Chehab }
29009a0bf528SMauro Carvalho Chehab 
set_frequency_shifter(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset,bool is_dtv)2901cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state,
2902cd7a67a4SMauro Carvalho Chehab 			       u16 intermediate_freqk_hz,
2903cd7a67a4SMauro Carvalho Chehab 			       s32 tuner_freq_offset, bool is_dtv)
29049a0bf528SMauro Carvalho Chehab {
2905cd7a67a4SMauro Carvalho Chehab 	bool select_pos_image = false;
2906cd7a67a4SMauro Carvalho Chehab 	u32 rf_freq_residual = tuner_freq_offset;
2907cd7a67a4SMauro Carvalho Chehab 	u32 fm_frequency_shift = 0;
2908cd7a67a4SMauro Carvalho Chehab 	bool tuner_mirror = !state->m_b_mirror_freq_spect;
2909cd7a67a4SMauro Carvalho Chehab 	u32 adc_freq;
2910cd7a67a4SMauro Carvalho Chehab 	bool adc_flip;
29119a0bf528SMauro Carvalho Chehab 	int status;
2912cd7a67a4SMauro Carvalho Chehab 	u32 if_freq_actual;
2913cd7a67a4SMauro Carvalho Chehab 	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2914cd7a67a4SMauro Carvalho Chehab 	u32 frequency_shift;
2915cd7a67a4SMauro Carvalho Chehab 	bool image_to_select;
29169a0bf528SMauro Carvalho Chehab 
29179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29189a0bf528SMauro Carvalho Chehab 
29199a0bf528SMauro Carvalho Chehab 	/*
29209a0bf528SMauro Carvalho Chehab 	   Program frequency shifter
29219a0bf528SMauro Carvalho Chehab 	   No need to account for mirroring on RF
29229a0bf528SMauro Carvalho Chehab 	 */
2923cd7a67a4SMauro Carvalho Chehab 	if (is_dtv) {
2924cd7a67a4SMauro Carvalho Chehab 		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2925cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_QAM_ITU_C) ||
2926cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_DVBT))
2927cd7a67a4SMauro Carvalho Chehab 			select_pos_image = true;
29289a0bf528SMauro Carvalho Chehab 		else
2929cd7a67a4SMauro Carvalho Chehab 			select_pos_image = false;
29309a0bf528SMauro Carvalho Chehab 	}
2931cd7a67a4SMauro Carvalho Chehab 	if (tuner_mirror)
29329a0bf528SMauro Carvalho Chehab 		/* tuner doesn't mirror */
2933cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz +
2934cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual + fm_frequency_shift;
29359a0bf528SMauro Carvalho Chehab 	else
29369a0bf528SMauro Carvalho Chehab 		/* tuner mirrors */
2937cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz -
2938cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual - fm_frequency_shift;
2939cd7a67a4SMauro Carvalho Chehab 	if (if_freq_actual > sampling_frequency / 2) {
29409a0bf528SMauro Carvalho Chehab 		/* adc mirrors */
2941cd7a67a4SMauro Carvalho Chehab 		adc_freq = sampling_frequency - if_freq_actual;
2942cd7a67a4SMauro Carvalho Chehab 		adc_flip = true;
29439a0bf528SMauro Carvalho Chehab 	} else {
29449a0bf528SMauro Carvalho Chehab 		/* adc doesn't mirror */
2945cd7a67a4SMauro Carvalho Chehab 		adc_freq = if_freq_actual;
2946cd7a67a4SMauro Carvalho Chehab 		adc_flip = false;
29479a0bf528SMauro Carvalho Chehab 	}
29489a0bf528SMauro Carvalho Chehab 
2949cd7a67a4SMauro Carvalho Chehab 	frequency_shift = adc_freq;
2950cd7a67a4SMauro Carvalho Chehab 	image_to_select = state->m_rfmirror ^ tuner_mirror ^
2951cd7a67a4SMauro Carvalho Chehab 	    adc_flip ^ select_pos_image;
2952cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_fs_rate_ofs =
2953cd7a67a4SMauro Carvalho Chehab 	    Frac28a((frequency_shift), sampling_frequency);
29549a0bf528SMauro Carvalho Chehab 
2955cd7a67a4SMauro Carvalho Chehab 	if (image_to_select)
2956cd7a67a4SMauro Carvalho Chehab 		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
29579a0bf528SMauro Carvalho Chehab 
29589a0bf528SMauro Carvalho Chehab 	/* Program frequency shifter with tuner offset compensation */
2959cd7a67a4SMauro Carvalho Chehab 	/* frequency_shift += tuner_freq_offset; TODO */
29609a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
2961cd7a67a4SMauro Carvalho Chehab 			 state->m_iqm_fs_rate_ofs);
29629a0bf528SMauro Carvalho Chehab 	if (status < 0)
29633a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
29649a0bf528SMauro Carvalho Chehab 	return status;
29659a0bf528SMauro Carvalho Chehab }
29669a0bf528SMauro Carvalho Chehab 
init_agc(struct drxk_state * state,bool is_dtv)2967cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv)
29689a0bf528SMauro Carvalho Chehab {
2969cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt = 0;
2970cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_min = 0;
2971cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_max = 0;
2972cd7a67a4SMauro Carvalho Chehab 	u16 clp_cyclen = 0;
2973cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_min = 0;
2974cd7a67a4SMauro Carvalho Chehab 	u16 clp_dir_to = 0;
2975cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_min = 0;
2976cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_max = 0;
2977cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_max = 0;
2978cd7a67a4SMauro Carvalho Chehab 	u16 sns_dir_to = 0;
2979cd7a67a4SMauro Carvalho Chehab 	u16 ki_innergain_min = 0;
2980cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt = 0;
2981cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_min = 0;
2982cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_max = 0;
29839a0bf528SMauro Carvalho Chehab 	u16 data = 0;
2984cd7a67a4SMauro Carvalho Chehab 	u16 fast_clp_ctrl_delay = 0;
2985cd7a67a4SMauro Carvalho Chehab 	u16 clp_ctrl_mode = 0;
29869a0bf528SMauro Carvalho Chehab 	int status = 0;
29879a0bf528SMauro Carvalho Chehab 
29889a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29899a0bf528SMauro Carvalho Chehab 
29909a0bf528SMauro Carvalho Chehab 	/* Common settings */
2991cd7a67a4SMauro Carvalho Chehab 	sns_sum_max = 1023;
2992cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_min = 2047;
2993cd7a67a4SMauro Carvalho Chehab 	clp_cyclen = 500;
2994cd7a67a4SMauro Carvalho Chehab 	clp_sum_max = 1023;
29959a0bf528SMauro Carvalho Chehab 
29969a0bf528SMauro Carvalho Chehab 	/* AGCInit() not available for DVBT; init done in microcode */
2997cd7a67a4SMauro Carvalho Chehab 	if (!is_qam(state)) {
29983a4398f5SMauro Carvalho Chehab 		pr_err("%s: mode %d is not DVB-C\n",
29993a4398f5SMauro Carvalho Chehab 		       __func__, state->m_operation_mode);
30009a0bf528SMauro Carvalho Chehab 		return -EINVAL;
30019a0bf528SMauro Carvalho Chehab 	}
30029a0bf528SMauro Carvalho Chehab 
30039a0bf528SMauro Carvalho Chehab 	/* FIXME: Analog TV AGC require different settings */
30049a0bf528SMauro Carvalho Chehab 
30059a0bf528SMauro Carvalho Chehab 	/* Standard specific settings */
3006cd7a67a4SMauro Carvalho Chehab 	clp_sum_min = 8;
3007cd7a67a4SMauro Carvalho Chehab 	clp_dir_to = (u16) -9;
3008cd7a67a4SMauro Carvalho Chehab 	clp_ctrl_mode = 0;
3009cd7a67a4SMauro Carvalho Chehab 	sns_sum_min = 8;
3010cd7a67a4SMauro Carvalho Chehab 	sns_dir_to = (u16) -9;
3011cd7a67a4SMauro Carvalho Chehab 	ki_innergain_min = (u16) -1030;
3012cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_max = 0x2380;
3013cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt = 0x2380;
3014cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_min = 0x0511;
3015cd7a67a4SMauro Carvalho Chehab 	ingain_tgt = 0x0511;
3016cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_max = 5119;
3017cd7a67a4SMauro Carvalho Chehab 	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
30189a0bf528SMauro Carvalho Chehab 
3019ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3020ab5060cdSMauro Carvalho Chehab 			 fast_clp_ctrl_delay);
30219a0bf528SMauro Carvalho Chehab 	if (status < 0)
30229a0bf528SMauro Carvalho Chehab 		goto error;
30239a0bf528SMauro Carvalho Chehab 
3024cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
30259a0bf528SMauro Carvalho Chehab 	if (status < 0)
30269a0bf528SMauro Carvalho Chehab 		goto error;
3027cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
30289a0bf528SMauro Carvalho Chehab 	if (status < 0)
30299a0bf528SMauro Carvalho Chehab 		goto error;
3030cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
30319a0bf528SMauro Carvalho Chehab 	if (status < 0)
30329a0bf528SMauro Carvalho Chehab 		goto error;
3033cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
30349a0bf528SMauro Carvalho Chehab 	if (status < 0)
30359a0bf528SMauro Carvalho Chehab 		goto error;
3036ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3037ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_min);
30389a0bf528SMauro Carvalho Chehab 	if (status < 0)
30399a0bf528SMauro Carvalho Chehab 		goto error;
3040ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3041ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_max);
30429a0bf528SMauro Carvalho Chehab 	if (status < 0)
30439a0bf528SMauro Carvalho Chehab 		goto error;
30449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
30459a0bf528SMauro Carvalho Chehab 	if (status < 0)
30469a0bf528SMauro Carvalho Chehab 		goto error;
30479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
30489a0bf528SMauro Carvalho Chehab 	if (status < 0)
30499a0bf528SMauro Carvalho Chehab 		goto error;
30509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
30519a0bf528SMauro Carvalho Chehab 	if (status < 0)
30529a0bf528SMauro Carvalho Chehab 		goto error;
30539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
30549a0bf528SMauro Carvalho Chehab 	if (status < 0)
30559a0bf528SMauro Carvalho Chehab 		goto error;
3056cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
30579a0bf528SMauro Carvalho Chehab 	if (status < 0)
30589a0bf528SMauro Carvalho Chehab 		goto error;
3059cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
30609a0bf528SMauro Carvalho Chehab 	if (status < 0)
30619a0bf528SMauro Carvalho Chehab 		goto error;
30629a0bf528SMauro Carvalho Chehab 
3063ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3064ab5060cdSMauro Carvalho Chehab 			 ki_innergain_min);
30659a0bf528SMauro Carvalho Chehab 	if (status < 0)
30669a0bf528SMauro Carvalho Chehab 		goto error;
3067ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3068ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt);
30699a0bf528SMauro Carvalho Chehab 	if (status < 0)
30709a0bf528SMauro Carvalho Chehab 		goto error;
3071cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
30729a0bf528SMauro Carvalho Chehab 	if (status < 0)
30739a0bf528SMauro Carvalho Chehab 		goto error;
30749a0bf528SMauro Carvalho Chehab 
30759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
30769a0bf528SMauro Carvalho Chehab 	if (status < 0)
30779a0bf528SMauro Carvalho Chehab 		goto error;
30789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
30799a0bf528SMauro Carvalho Chehab 	if (status < 0)
30809a0bf528SMauro Carvalho Chehab 		goto error;
30819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
30829a0bf528SMauro Carvalho Chehab 	if (status < 0)
30839a0bf528SMauro Carvalho Chehab 		goto error;
30849a0bf528SMauro Carvalho Chehab 
30859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
30869a0bf528SMauro Carvalho Chehab 	if (status < 0)
30879a0bf528SMauro Carvalho Chehab 		goto error;
3088cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
30899a0bf528SMauro Carvalho Chehab 	if (status < 0)
30909a0bf528SMauro Carvalho Chehab 		goto error;
3091cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
30929a0bf528SMauro Carvalho Chehab 	if (status < 0)
30939a0bf528SMauro Carvalho Chehab 		goto error;
3094cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
30959a0bf528SMauro Carvalho Chehab 	if (status < 0)
30969a0bf528SMauro Carvalho Chehab 		goto error;
3097cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
30989a0bf528SMauro Carvalho Chehab 	if (status < 0)
30999a0bf528SMauro Carvalho Chehab 		goto error;
31009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
31019a0bf528SMauro Carvalho Chehab 	if (status < 0)
31029a0bf528SMauro Carvalho Chehab 		goto error;
31039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
31049a0bf528SMauro Carvalho Chehab 	if (status < 0)
31059a0bf528SMauro Carvalho Chehab 		goto error;
31069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
31079a0bf528SMauro Carvalho Chehab 	if (status < 0)
31089a0bf528SMauro Carvalho Chehab 		goto error;
31099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
31109a0bf528SMauro Carvalho Chehab 	if (status < 0)
31119a0bf528SMauro Carvalho Chehab 		goto error;
31129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
31139a0bf528SMauro Carvalho Chehab 	if (status < 0)
31149a0bf528SMauro Carvalho Chehab 		goto error;
31159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
31169a0bf528SMauro Carvalho Chehab 	if (status < 0)
31179a0bf528SMauro Carvalho Chehab 		goto error;
31189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
31199a0bf528SMauro Carvalho Chehab 	if (status < 0)
31209a0bf528SMauro Carvalho Chehab 		goto error;
31219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
31229a0bf528SMauro Carvalho Chehab 	if (status < 0)
31239a0bf528SMauro Carvalho Chehab 		goto error;
31249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
31259a0bf528SMauro Carvalho Chehab 	if (status < 0)
31269a0bf528SMauro Carvalho Chehab 		goto error;
31279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
31289a0bf528SMauro Carvalho Chehab 	if (status < 0)
31299a0bf528SMauro Carvalho Chehab 		goto error;
31309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
31319a0bf528SMauro Carvalho Chehab 	if (status < 0)
31329a0bf528SMauro Carvalho Chehab 		goto error;
31339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
31349a0bf528SMauro Carvalho Chehab 	if (status < 0)
31359a0bf528SMauro Carvalho Chehab 		goto error;
31369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
31379a0bf528SMauro Carvalho Chehab 	if (status < 0)
31389a0bf528SMauro Carvalho Chehab 		goto error;
31399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
31409a0bf528SMauro Carvalho Chehab 	if (status < 0)
31419a0bf528SMauro Carvalho Chehab 		goto error;
31429a0bf528SMauro Carvalho Chehab 
31439a0bf528SMauro Carvalho Chehab 	/* Initialize inner-loop KI gain factors */
31449a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_AGC_KI__A, &data);
31459a0bf528SMauro Carvalho Chehab 	if (status < 0)
31469a0bf528SMauro Carvalho Chehab 		goto error;
31479a0bf528SMauro Carvalho Chehab 
31489a0bf528SMauro Carvalho Chehab 	data = 0x0657;
31499a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_RF__M;
31509a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
31519a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_IF__M;
31529a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
31539a0bf528SMauro Carvalho Chehab 
31549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI__A, data);
31559a0bf528SMauro Carvalho Chehab error:
31569a0bf528SMauro Carvalho Chehab 	if (status < 0)
31573a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
31589a0bf528SMauro Carvalho Chehab 	return status;
31599a0bf528SMauro Carvalho Chehab }
31609a0bf528SMauro Carvalho Chehab 
dvbtqam_get_acc_pkt_err(struct drxk_state * state,u16 * packet_err)3161cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
31629a0bf528SMauro Carvalho Chehab {
31639a0bf528SMauro Carvalho Chehab 	int status;
31649a0bf528SMauro Carvalho Chehab 
31659a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3166cd7a67a4SMauro Carvalho Chehab 	if (packet_err == NULL)
31679a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
31689a0bf528SMauro Carvalho Chehab 	else
3169ab5060cdSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3170ab5060cdSMauro Carvalho Chehab 				packet_err);
31719a0bf528SMauro Carvalho Chehab 	if (status < 0)
31723a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
31739a0bf528SMauro Carvalho Chehab 	return status;
31749a0bf528SMauro Carvalho Chehab }
31759a0bf528SMauro Carvalho Chehab 
dvbt_sc_command(struct drxk_state * state,u16 cmd,u16 subcmd,u16 param0,u16 param1,u16 param2,u16 param3,u16 param4)3176cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state,
31779a0bf528SMauro Carvalho Chehab 			 u16 cmd, u16 subcmd,
31789a0bf528SMauro Carvalho Chehab 			 u16 param0, u16 param1, u16 param2,
31799a0bf528SMauro Carvalho Chehab 			 u16 param3, u16 param4)
31809a0bf528SMauro Carvalho Chehab {
3181cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
3182cd7a67a4SMauro Carvalho Chehab 	u16 err_code = 0;
3183cd7a67a4SMauro Carvalho Chehab 	u16 retry_cnt = 0;
3184cd7a67a4SMauro Carvalho Chehab 	u16 sc_exec = 0;
31859a0bf528SMauro Carvalho Chehab 	int status;
31869a0bf528SMauro Carvalho Chehab 
31879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3188cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3189cd7a67a4SMauro Carvalho Chehab 	if (sc_exec != 1) {
31909a0bf528SMauro Carvalho Chehab 		/* SC is not running */
31919a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
31929a0bf528SMauro Carvalho Chehab 	}
31939a0bf528SMauro Carvalho Chehab 	if (status < 0)
31949a0bf528SMauro Carvalho Chehab 		goto error;
31959a0bf528SMauro Carvalho Chehab 
31969a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready to receive command */
3197cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
31989a0bf528SMauro Carvalho Chehab 	do {
3199b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3200cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3201cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3202cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3203cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32049a0bf528SMauro Carvalho Chehab 		goto error;
32059a0bf528SMauro Carvalho Chehab 
32069a0bf528SMauro Carvalho Chehab 	/* Write sub-command */
32079a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32089a0bf528SMauro Carvalho Chehab 		/* All commands using sub-cmd */
32099a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32109a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32119a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32129a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
32139a0bf528SMauro Carvalho Chehab 		if (status < 0)
32149a0bf528SMauro Carvalho Chehab 			goto error;
32159a0bf528SMauro Carvalho Chehab 		break;
32169a0bf528SMauro Carvalho Chehab 	default:
32179a0bf528SMauro Carvalho Chehab 		/* Do nothing */
32189a0bf528SMauro Carvalho Chehab 		break;
32199a0bf528SMauro Carvalho Chehab 	}
32209a0bf528SMauro Carvalho Chehab 
32219a0bf528SMauro Carvalho Chehab 	/* Write needed parameters and the command */
32222f60f13cSMauro Carvalho Chehab 	status = 0;
32239a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32249a0bf528SMauro Carvalho Chehab 		/* All commands using 5 parameters */
32259a0bf528SMauro Carvalho Chehab 		/* All commands using 4 parameters */
32269a0bf528SMauro Carvalho Chehab 		/* All commands using 3 parameters */
32279a0bf528SMauro Carvalho Chehab 		/* All commands using 2 parameters */
32289a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32299a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32309a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32312f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
3232df561f66SGustavo A. R. Silva 		fallthrough;	/* All commands using 1 parameters */
32339a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32349a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32352f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
3236df561f66SGustavo A. R. Silva 		fallthrough;	/* All commands using 0 parameters */
32379a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32389a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
32399a0bf528SMauro Carvalho Chehab 		/* Write command */
32402f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
32419a0bf528SMauro Carvalho Chehab 		break;
32429a0bf528SMauro Carvalho Chehab 	default:
32439a0bf528SMauro Carvalho Chehab 		/* Unknown command */
32449a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32459a0bf528SMauro Carvalho Chehab 	}
32469a0bf528SMauro Carvalho Chehab 	if (status < 0)
32479a0bf528SMauro Carvalho Chehab 		goto error;
32489a0bf528SMauro Carvalho Chehab 
32499a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready processing command */
3250cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32519a0bf528SMauro Carvalho Chehab 	do {
3252b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3253cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3254cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3255cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3256cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32579a0bf528SMauro Carvalho Chehab 		goto error;
32589a0bf528SMauro Carvalho Chehab 
32599a0bf528SMauro Carvalho Chehab 	/* Check for illegal cmd */
3260cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3261cd7a67a4SMauro Carvalho Chehab 	if (err_code == 0xFFFF) {
32629a0bf528SMauro Carvalho Chehab 		/* illegal command */
32639a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32649a0bf528SMauro Carvalho Chehab 	}
32659a0bf528SMauro Carvalho Chehab 	if (status < 0)
32669a0bf528SMauro Carvalho Chehab 		goto error;
32679a0bf528SMauro Carvalho Chehab 
326839c1cb2bSJonathan McCrohan 	/* Retrieve results parameters from SC */
32699a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32709a0bf528SMauro Carvalho Chehab 		/* All commands yielding 5 results */
32719a0bf528SMauro Carvalho Chehab 		/* All commands yielding 4 results */
32729a0bf528SMauro Carvalho Chehab 		/* All commands yielding 3 results */
32739a0bf528SMauro Carvalho Chehab 		/* All commands yielding 2 results */
32749a0bf528SMauro Carvalho Chehab 		/* All commands yielding 1 result */
32759a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32769a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32779a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
3278af7ab662SGustavo A. R. Silva 		break;
32799a0bf528SMauro Carvalho Chehab 		/* All commands yielding 0 results */
32809a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32819a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_TIMER:
32829a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32839a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32849a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32859a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
32869a0bf528SMauro Carvalho Chehab 		break;
32879a0bf528SMauro Carvalho Chehab 	default:
32889a0bf528SMauro Carvalho Chehab 		/* Unknown command */
32899a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32909a0bf528SMauro Carvalho Chehab 		break;
32919a0bf528SMauro Carvalho Chehab 	}			/* switch (cmd->cmd) */
32929a0bf528SMauro Carvalho Chehab error:
32939a0bf528SMauro Carvalho Chehab 	if (status < 0)
32943a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
32959a0bf528SMauro Carvalho Chehab 	return status;
32969a0bf528SMauro Carvalho Chehab }
32979a0bf528SMauro Carvalho Chehab 
power_up_dvbt(struct drxk_state * state)3298cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state)
32999a0bf528SMauro Carvalho Chehab {
3300cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRX_POWER_UP;
33019a0bf528SMauro Carvalho Chehab 	int status;
33029a0bf528SMauro Carvalho Chehab 
33039a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3304cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
33059a0bf528SMauro Carvalho Chehab 	if (status < 0)
33063a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33079a0bf528SMauro Carvalho Chehab 	return status;
33089a0bf528SMauro Carvalho Chehab }
33099a0bf528SMauro Carvalho Chehab 
dvbt_ctrl_set_inc_enable(struct drxk_state * state,bool * enabled)3310cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
33119a0bf528SMauro Carvalho Chehab {
33129a0bf528SMauro Carvalho Chehab 	int status;
33139a0bf528SMauro Carvalho Chehab 
33149a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33155a7f7b79SMauro Carvalho Chehab 	if (*enabled)
33169a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
33179a0bf528SMauro Carvalho Chehab 	else
33189a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
33199a0bf528SMauro Carvalho Chehab 	if (status < 0)
33203a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33219a0bf528SMauro Carvalho Chehab 	return status;
33229a0bf528SMauro Carvalho Chehab }
33239a0bf528SMauro Carvalho Chehab 
33249a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K     4000
dvbt_ctrl_set_fr_enable(struct drxk_state * state,bool * enabled)3325cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
33269a0bf528SMauro Carvalho Chehab {
33279a0bf528SMauro Carvalho Chehab 
33289a0bf528SMauro Carvalho Chehab 	int status;
33299a0bf528SMauro Carvalho Chehab 
33309a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33315a7f7b79SMauro Carvalho Chehab 	if (*enabled) {
33329a0bf528SMauro Carvalho Chehab 		/* write mask to 1 */
33339a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
33349a0bf528SMauro Carvalho Chehab 				   DEFAULT_FR_THRES_8K);
33359a0bf528SMauro Carvalho Chehab 	} else {
33369a0bf528SMauro Carvalho Chehab 		/* write mask to 0 */
33379a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
33389a0bf528SMauro Carvalho Chehab 	}
33399a0bf528SMauro Carvalho Chehab 	if (status < 0)
33403a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33419a0bf528SMauro Carvalho Chehab 
33429a0bf528SMauro Carvalho Chehab 	return status;
33439a0bf528SMauro Carvalho Chehab }
33449a0bf528SMauro Carvalho Chehab 
dvbt_ctrl_set_echo_threshold(struct drxk_state * state,struct drxk_cfg_dvbt_echo_thres_t * echo_thres)3345cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3346cd7a67a4SMauro Carvalho Chehab 				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
33479a0bf528SMauro Carvalho Chehab {
33489a0bf528SMauro Carvalho Chehab 	u16 data = 0;
33499a0bf528SMauro Carvalho Chehab 	int status;
33509a0bf528SMauro Carvalho Chehab 
33519a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33529a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
33539a0bf528SMauro Carvalho Chehab 	if (status < 0)
33549a0bf528SMauro Carvalho Chehab 		goto error;
33559a0bf528SMauro Carvalho Chehab 
3356cd7a67a4SMauro Carvalho Chehab 	switch (echo_thres->fft_mode) {
33579a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_2K:
33589a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3359cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
33609a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
33619a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
33629a0bf528SMauro Carvalho Chehab 		break;
33639a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_8K:
33649a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3365cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
33669a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
33679a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
33689a0bf528SMauro Carvalho Chehab 		break;
33699a0bf528SMauro Carvalho Chehab 	default:
33709a0bf528SMauro Carvalho Chehab 		return -EINVAL;
33719a0bf528SMauro Carvalho Chehab 	}
33729a0bf528SMauro Carvalho Chehab 
33739a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
33749a0bf528SMauro Carvalho Chehab error:
33759a0bf528SMauro Carvalho Chehab 	if (status < 0)
33763a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33779a0bf528SMauro Carvalho Chehab 	return status;
33789a0bf528SMauro Carvalho Chehab }
33799a0bf528SMauro Carvalho Chehab 
dvbt_ctrl_set_sqi_speed(struct drxk_state * state,enum drxk_cfg_dvbt_sqi_speed * speed)3380cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3381cd7a67a4SMauro Carvalho Chehab 			       enum drxk_cfg_dvbt_sqi_speed *speed)
33829a0bf528SMauro Carvalho Chehab {
33839a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
33849a0bf528SMauro Carvalho Chehab 
33859a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33869a0bf528SMauro Carvalho Chehab 
33879a0bf528SMauro Carvalho Chehab 	switch (*speed) {
33889a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_FAST:
33899a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_MEDIUM:
33909a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_SLOW:
33919a0bf528SMauro Carvalho Chehab 		break;
33929a0bf528SMauro Carvalho Chehab 	default:
33939a0bf528SMauro Carvalho Chehab 		goto error;
33949a0bf528SMauro Carvalho Chehab 	}
33959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
33969a0bf528SMauro Carvalho Chehab 			   (u16) *speed);
33979a0bf528SMauro Carvalho Chehab error:
33989a0bf528SMauro Carvalho Chehab 	if (status < 0)
33993a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34009a0bf528SMauro Carvalho Chehab 	return status;
34019a0bf528SMauro Carvalho Chehab }
34029a0bf528SMauro Carvalho Chehab 
34039a0bf528SMauro Carvalho Chehab /*============================================================================*/
34049a0bf528SMauro Carvalho Chehab 
340534eb9751SMauro Carvalho Chehab /*
34069a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
34079a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34089a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34099a0bf528SMauro Carvalho Chehab *
34109a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
34119a0bf528SMauro Carvalho Chehab *
34129a0bf528SMauro Carvalho Chehab */
dvbt_activate_presets(struct drxk_state * state)3413cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state)
34149a0bf528SMauro Carvalho Chehab {
34159a0bf528SMauro Carvalho Chehab 	int status;
34169a0bf528SMauro Carvalho Chehab 	bool setincenable = false;
34179a0bf528SMauro Carvalho Chehab 	bool setfrenable = true;
34189a0bf528SMauro Carvalho Chehab 
3419cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3420cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
34219a0bf528SMauro Carvalho Chehab 
34229a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3423cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
34249a0bf528SMauro Carvalho Chehab 	if (status < 0)
34259a0bf528SMauro Carvalho Chehab 		goto error;
3426cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
34279a0bf528SMauro Carvalho Chehab 	if (status < 0)
34289a0bf528SMauro Carvalho Chehab 		goto error;
3429cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
34309a0bf528SMauro Carvalho Chehab 	if (status < 0)
34319a0bf528SMauro Carvalho Chehab 		goto error;
3432cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
34339a0bf528SMauro Carvalho Chehab 	if (status < 0)
34349a0bf528SMauro Carvalho Chehab 		goto error;
3435ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3436ab5060cdSMauro Carvalho Chehab 			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
34379a0bf528SMauro Carvalho Chehab error:
34389a0bf528SMauro Carvalho Chehab 	if (status < 0)
34393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34409a0bf528SMauro Carvalho Chehab 	return status;
34419a0bf528SMauro Carvalho Chehab }
34429a0bf528SMauro Carvalho Chehab 
34439a0bf528SMauro Carvalho Chehab /*============================================================================*/
34449a0bf528SMauro Carvalho Chehab 
344534eb9751SMauro Carvalho Chehab /*
34469a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
34479a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34489a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34499a0bf528SMauro Carvalho Chehab *
34509a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
34519a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
34529a0bf528SMauro Carvalho Chehab */
set_dvbt_standard(struct drxk_state * state,enum operation_mode o_mode)3453cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
3454cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode)
34559a0bf528SMauro Carvalho Chehab {
3456cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
34579a0bf528SMauro Carvalho Chehab 	u16 data = 0;
34589a0bf528SMauro Carvalho Chehab 	int status;
34599a0bf528SMauro Carvalho Chehab 
34609a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34619a0bf528SMauro Carvalho Chehab 
3462cd7a67a4SMauro Carvalho Chehab 	power_up_dvbt(state);
34639a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
3464cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_dvbt(state);
34659a0bf528SMauro Carvalho Chehab 	/* send OFDM reset command */
3466ab5060cdSMauro Carvalho Chehab 	status = scu_command(state,
3467ab5060cdSMauro Carvalho Chehab 			     SCU_RAM_COMMAND_STANDARD_OFDM
3468ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3469ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
34709a0bf528SMauro Carvalho Chehab 	if (status < 0)
34719a0bf528SMauro Carvalho Chehab 		goto error;
34729a0bf528SMauro Carvalho Chehab 
34739a0bf528SMauro Carvalho Chehab 	/* send OFDM setenv command */
3474ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3475ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3476ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
34779a0bf528SMauro Carvalho Chehab 	if (status < 0)
34789a0bf528SMauro Carvalho Chehab 		goto error;
34799a0bf528SMauro Carvalho Chehab 
34809a0bf528SMauro Carvalho Chehab 	/* reset datapath for OFDM, processors first */
34819a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
34829a0bf528SMauro Carvalho Chehab 	if (status < 0)
34839a0bf528SMauro Carvalho Chehab 		goto error;
34849a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
34859a0bf528SMauro Carvalho Chehab 	if (status < 0)
34869a0bf528SMauro Carvalho Chehab 		goto error;
34879a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
34889a0bf528SMauro Carvalho Chehab 	if (status < 0)
34899a0bf528SMauro Carvalho Chehab 		goto error;
34909a0bf528SMauro Carvalho Chehab 
34919a0bf528SMauro Carvalho Chehab 	/* IQM setup */
34929a0bf528SMauro Carvalho Chehab 	/* synchronize on ofdstate->m_festart */
34939a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 1);
34949a0bf528SMauro Carvalho Chehab 	if (status < 0)
34959a0bf528SMauro Carvalho Chehab 		goto error;
34969a0bf528SMauro Carvalho Chehab 	/* window size for clipping ADC detection */
34979a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
34989a0bf528SMauro Carvalho Chehab 	if (status < 0)
34999a0bf528SMauro Carvalho Chehab 		goto error;
350073854b86SJason Wang 	/* window size for sense pre-SAW detection */
35019a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
35029a0bf528SMauro Carvalho Chehab 	if (status < 0)
35039a0bf528SMauro Carvalho Chehab 		goto error;
35049a0bf528SMauro Carvalho Chehab 	/* sense threshold for sense pre-SAW detection */
35059a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
35069a0bf528SMauro Carvalho Chehab 	if (status < 0)
35079a0bf528SMauro Carvalho Chehab 		goto error;
3508cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
35099a0bf528SMauro Carvalho Chehab 	if (status < 0)
35109a0bf528SMauro Carvalho Chehab 		goto error;
35119a0bf528SMauro Carvalho Chehab 
35129a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AGC_RF__A, 0);
35139a0bf528SMauro Carvalho Chehab 	if (status < 0)
35149a0bf528SMauro Carvalho Chehab 		goto error;
35159a0bf528SMauro Carvalho Chehab 
35169a0bf528SMauro Carvalho Chehab 	/* Impulse noise cruncher setup */
35179a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_LCT__A, 0);	/* crunch in IQM_CF */
35189a0bf528SMauro Carvalho Chehab 	if (status < 0)
35199a0bf528SMauro Carvalho Chehab 		goto error;
35209a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);	/* detect in IQM_CF */
35219a0bf528SMauro Carvalho Chehab 	if (status < 0)
35229a0bf528SMauro Carvalho Chehab 		goto error;
35239a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 3);	/* peak detector window length */
35249a0bf528SMauro Carvalho Chehab 	if (status < 0)
35259a0bf528SMauro Carvalho Chehab 		goto error;
35269a0bf528SMauro Carvalho Chehab 
35279a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 16);
35289a0bf528SMauro Carvalho Chehab 	if (status < 0)
35299a0bf528SMauro Carvalho Chehab 		goto error;
35309a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
35319a0bf528SMauro Carvalho Chehab 	if (status < 0)
35329a0bf528SMauro Carvalho Chehab 		goto error;
35339a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
35349a0bf528SMauro Carvalho Chehab 	if (status < 0)
35359a0bf528SMauro Carvalho Chehab 		goto error;
35369a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE__A, 1600);
35379a0bf528SMauro Carvalho Chehab 	if (status < 0)
35389a0bf528SMauro Carvalho Chehab 		goto error;
35399a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, 0);
35409a0bf528SMauro Carvalho Chehab 	if (status < 0)
35419a0bf528SMauro Carvalho Chehab 		goto error;
35429a0bf528SMauro Carvalho Chehab 
35439a0bf528SMauro Carvalho Chehab 	/* virtual clipping threshold for clipping ADC detection */
35449a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
35459a0bf528SMauro Carvalho Chehab 	if (status < 0)
35469a0bf528SMauro Carvalho Chehab 		goto error;
35479a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 495);	/* crunching threshold */
35489a0bf528SMauro Carvalho Chehab 	if (status < 0)
35499a0bf528SMauro Carvalho Chehab 		goto error;
35509a0bf528SMauro Carvalho Chehab 
3551ab5060cdSMauro Carvalho Chehab 	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3552ab5060cdSMauro Carvalho Chehab 			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
35539a0bf528SMauro Carvalho Chehab 	if (status < 0)
35549a0bf528SMauro Carvalho Chehab 		goto error;
35559a0bf528SMauro Carvalho Chehab 
35569a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 2);	/* peak detector threshold */
35579a0bf528SMauro Carvalho Chehab 	if (status < 0)
35589a0bf528SMauro Carvalho Chehab 		goto error;
35599a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
35609a0bf528SMauro Carvalho Chehab 	if (status < 0)
35619a0bf528SMauro Carvalho Chehab 		goto error;
35629a0bf528SMauro Carvalho Chehab 	/* enable power measurement interrupt */
35639a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
35649a0bf528SMauro Carvalho Chehab 	if (status < 0)
35659a0bf528SMauro Carvalho Chehab 		goto error;
35669a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
35679a0bf528SMauro Carvalho Chehab 	if (status < 0)
35689a0bf528SMauro Carvalho Chehab 		goto error;
35699a0bf528SMauro Carvalho Chehab 
35709a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
3571cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
35729a0bf528SMauro Carvalho Chehab 	if (status < 0)
35739a0bf528SMauro Carvalho Chehab 		goto error;
3574cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
35759a0bf528SMauro Carvalho Chehab 	if (status < 0)
35769a0bf528SMauro Carvalho Chehab 		goto error;
35779a0bf528SMauro Carvalho Chehab 
35789a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
35799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
35809a0bf528SMauro Carvalho Chehab 	if (status < 0)
35819a0bf528SMauro Carvalho Chehab 		goto error;
35829a0bf528SMauro Carvalho Chehab 
3583cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
35849a0bf528SMauro Carvalho Chehab 	if (status < 0)
35859a0bf528SMauro Carvalho Chehab 		goto error;
3586cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
35879a0bf528SMauro Carvalho Chehab 	if (status < 0)
35889a0bf528SMauro Carvalho Chehab 		goto error;
35899a0bf528SMauro Carvalho Chehab 
35909a0bf528SMauro Carvalho Chehab 	/* Set Noise Estimation notch width and enable DC fix */
35919a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
35929a0bf528SMauro Carvalho Chehab 	if (status < 0)
35939a0bf528SMauro Carvalho Chehab 		goto error;
35949a0bf528SMauro Carvalho Chehab 	data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
35959a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
35969a0bf528SMauro Carvalho Chehab 	if (status < 0)
35979a0bf528SMauro Carvalho Chehab 		goto error;
35989a0bf528SMauro Carvalho Chehab 
35999a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
36009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
36019a0bf528SMauro Carvalho Chehab 	if (status < 0)
36029a0bf528SMauro Carvalho Chehab 		goto error;
36039a0bf528SMauro Carvalho Chehab 
3604cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code) {
3605cd7a67a4SMauro Carvalho Chehab 		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
3606ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3607ab5060cdSMauro Carvalho Chehab 				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
36089a0bf528SMauro Carvalho Chehab 		if (status < 0)
36099a0bf528SMauro Carvalho Chehab 			goto error;
36109a0bf528SMauro Carvalho Chehab 	}
36119a0bf528SMauro Carvalho Chehab 
36129a0bf528SMauro Carvalho Chehab 	/* OFDM_SC setup */
36139a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36149a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
36159a0bf528SMauro Carvalho Chehab 	if (status < 0)
36169a0bf528SMauro Carvalho Chehab 		goto error;
36179a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
36189a0bf528SMauro Carvalho Chehab 	if (status < 0)
36199a0bf528SMauro Carvalho Chehab 		goto error;
36209a0bf528SMauro Carvalho Chehab #endif
36219a0bf528SMauro Carvalho Chehab 
36229a0bf528SMauro Carvalho Chehab 	/* FEC setup */
36239a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_INPUT_CTL__A, 1);	/* OFDM input */
36249a0bf528SMauro Carvalho Chehab 	if (status < 0)
36259a0bf528SMauro Carvalho Chehab 		goto error;
36269a0bf528SMauro Carvalho Chehab 
36279a0bf528SMauro Carvalho Chehab 
36289a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36299a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
36309a0bf528SMauro Carvalho Chehab 	if (status < 0)
36319a0bf528SMauro Carvalho Chehab 		goto error;
36329a0bf528SMauro Carvalho Chehab #else
36339a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
36349a0bf528SMauro Carvalho Chehab 	if (status < 0)
36359a0bf528SMauro Carvalho Chehab 		goto error;
36369a0bf528SMauro Carvalho Chehab #endif
36379a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
36389a0bf528SMauro Carvalho Chehab 	if (status < 0)
36399a0bf528SMauro Carvalho Chehab 		goto error;
36409a0bf528SMauro Carvalho Chehab 
36419a0bf528SMauro Carvalho Chehab 	/* Setup MPEG bus */
3642cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, OM_DVBT);
36439a0bf528SMauro Carvalho Chehab 	if (status < 0)
36449a0bf528SMauro Carvalho Chehab 		goto error;
36459a0bf528SMauro Carvalho Chehab 	/* Set DVBT Presets */
3646cd7a67a4SMauro Carvalho Chehab 	status = dvbt_activate_presets(state);
36479a0bf528SMauro Carvalho Chehab 	if (status < 0)
36489a0bf528SMauro Carvalho Chehab 		goto error;
36499a0bf528SMauro Carvalho Chehab 
36509a0bf528SMauro Carvalho Chehab error:
36519a0bf528SMauro Carvalho Chehab 	if (status < 0)
36523a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
36539a0bf528SMauro Carvalho Chehab 	return status;
36549a0bf528SMauro Carvalho Chehab }
36559a0bf528SMauro Carvalho Chehab 
36569a0bf528SMauro Carvalho Chehab /*============================================================================*/
365734eb9751SMauro Carvalho Chehab /*
3658cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel.
36599a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
36609a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
36619a0bf528SMauro Carvalho Chehab */
dvbt_start(struct drxk_state * state)3662cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state)
36639a0bf528SMauro Carvalho Chehab {
36649a0bf528SMauro Carvalho Chehab 	u16 param1;
36659a0bf528SMauro Carvalho Chehab 	int status;
3666cd7a67a4SMauro Carvalho Chehab 	/* drxk_ofdm_sc_cmd_t scCmd; */
36679a0bf528SMauro Carvalho Chehab 
36689a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3669cd7a67a4SMauro Carvalho Chehab 	/* start correct processes to get in lock */
36709a0bf528SMauro Carvalho Chehab 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
36719a0bf528SMauro Carvalho Chehab 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3672ab5060cdSMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3673ab5060cdSMauro Carvalho Chehab 				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3674ab5060cdSMauro Carvalho Chehab 				 0, 0, 0);
36759a0bf528SMauro Carvalho Chehab 	if (status < 0)
36769a0bf528SMauro Carvalho Chehab 		goto error;
3677cd7a67a4SMauro Carvalho Chehab 	/* start FEC OC */
3678cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
36799a0bf528SMauro Carvalho Chehab 	if (status < 0)
36809a0bf528SMauro Carvalho Chehab 		goto error;
36819a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
36829a0bf528SMauro Carvalho Chehab 	if (status < 0)
36839a0bf528SMauro Carvalho Chehab 		goto error;
36849a0bf528SMauro Carvalho Chehab error:
36859a0bf528SMauro Carvalho Chehab 	if (status < 0)
36863a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
36879a0bf528SMauro Carvalho Chehab 	return status;
36889a0bf528SMauro Carvalho Chehab }
36899a0bf528SMauro Carvalho Chehab 
36909a0bf528SMauro Carvalho Chehab 
36919a0bf528SMauro Carvalho Chehab /*============================================================================*/
36929a0bf528SMauro Carvalho Chehab 
369334eb9751SMauro Carvalho Chehab /*
36949a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
36959a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
36969a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
36979a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
36989a0bf528SMauro Carvalho Chehab */
set_dvbt(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset)3699cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3700cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset)
37019a0bf528SMauro Carvalho Chehab {
3702cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
3703cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
3704cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate_ofs = 0;
37059a0bf528SMauro Carvalho Chehab 	u32 bandwidth = 0;
37069a0bf528SMauro Carvalho Chehab 	u16 param1;
37079a0bf528SMauro Carvalho Chehab 	int status;
37089a0bf528SMauro Carvalho Chehab 
3709ab5060cdSMauro Carvalho Chehab 	dprintk(1, "IF =%d, TFO = %d\n",
3710ab5060cdSMauro Carvalho Chehab 		intermediate_freqk_hz, tuner_freq_offset);
37119a0bf528SMauro Carvalho Chehab 
3712ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3713ab5060cdSMauro Carvalho Chehab 			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3714ab5060cdSMauro Carvalho Chehab 			    0, NULL, 1, &cmd_result);
37159a0bf528SMauro Carvalho Chehab 	if (status < 0)
37169a0bf528SMauro Carvalho Chehab 		goto error;
37179a0bf528SMauro Carvalho Chehab 
37189a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
37199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
37209a0bf528SMauro Carvalho Chehab 	if (status < 0)
37219a0bf528SMauro Carvalho Chehab 		goto error;
37229a0bf528SMauro Carvalho Chehab 
37239a0bf528SMauro Carvalho Chehab 	/* Stop processors */
37249a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
37259a0bf528SMauro Carvalho Chehab 	if (status < 0)
37269a0bf528SMauro Carvalho Chehab 		goto error;
37279a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
37289a0bf528SMauro Carvalho Chehab 	if (status < 0)
37299a0bf528SMauro Carvalho Chehab 		goto error;
37309a0bf528SMauro Carvalho Chehab 
37319a0bf528SMauro Carvalho Chehab 	/* Mandatory fix, always stop CP, required to set spl offset back to
37329a0bf528SMauro Carvalho Chehab 		hardware default (is set to 0 by ucode during pilot detection */
37339a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
37349a0bf528SMauro Carvalho Chehab 	if (status < 0)
37359a0bf528SMauro Carvalho Chehab 		goto error;
37369a0bf528SMauro Carvalho Chehab 
3737ab5060cdSMauro Carvalho Chehab 	/*== Write channel settings to device ================================*/
37389a0bf528SMauro Carvalho Chehab 
37399a0bf528SMauro Carvalho Chehab 	/* mode */
37409a0bf528SMauro Carvalho Chehab 	switch (state->props.transmission_mode) {
37419a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_AUTO:
37429a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_8K:
37431cef3942SMauro Carvalho Chehab 	default:
3744cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
37459a0bf528SMauro Carvalho Chehab 		break;
37469a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_2K:
3747cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
37489a0bf528SMauro Carvalho Chehab 		break;
37499a0bf528SMauro Carvalho Chehab 	}
37509a0bf528SMauro Carvalho Chehab 
37519a0bf528SMauro Carvalho Chehab 	/* guard */
37529a0bf528SMauro Carvalho Chehab 	switch (state->props.guard_interval) {
37539a0bf528SMauro Carvalho Chehab 	default:
37541cef3942SMauro Carvalho Chehab 	case GUARD_INTERVAL_AUTO: /* try first guess DRX_GUARD_1DIV4 */
37559a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_4:
3756cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
37579a0bf528SMauro Carvalho Chehab 		break;
37589a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_32:
3759cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
37609a0bf528SMauro Carvalho Chehab 		break;
37619a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_16:
3762cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
37639a0bf528SMauro Carvalho Chehab 		break;
37649a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_8:
3765cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
37669a0bf528SMauro Carvalho Chehab 		break;
37679a0bf528SMauro Carvalho Chehab 	}
37689a0bf528SMauro Carvalho Chehab 
37699a0bf528SMauro Carvalho Chehab 	/* hierarchy */
37709a0bf528SMauro Carvalho Chehab 	switch (state->props.hierarchy) {
37719a0bf528SMauro Carvalho Chehab 	case HIERARCHY_AUTO:
37729a0bf528SMauro Carvalho Chehab 	case HIERARCHY_NONE:
37731cef3942SMauro Carvalho Chehab 	default:	/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
37749a0bf528SMauro Carvalho Chehab 	case HIERARCHY_1:
3775cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
37769a0bf528SMauro Carvalho Chehab 		break;
37779a0bf528SMauro Carvalho Chehab 	case HIERARCHY_2:
3778cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
37799a0bf528SMauro Carvalho Chehab 		break;
37809a0bf528SMauro Carvalho Chehab 	case HIERARCHY_4:
3781cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
37829a0bf528SMauro Carvalho Chehab 		break;
37839a0bf528SMauro Carvalho Chehab 	}
37849a0bf528SMauro Carvalho Chehab 
37859a0bf528SMauro Carvalho Chehab 
37869a0bf528SMauro Carvalho Chehab 	/* modulation */
37879a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
37889a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
37891cef3942SMauro Carvalho Chehab 	default:	/* try first guess DRX_CONSTELLATION_QAM64 */
37909a0bf528SMauro Carvalho Chehab 	case QAM_64:
3791cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
37929a0bf528SMauro Carvalho Chehab 		break;
37939a0bf528SMauro Carvalho Chehab 	case QPSK:
3794cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
37959a0bf528SMauro Carvalho Chehab 		break;
37969a0bf528SMauro Carvalho Chehab 	case QAM_16:
3797cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
37989a0bf528SMauro Carvalho Chehab 		break;
37999a0bf528SMauro Carvalho Chehab 	}
38009a0bf528SMauro Carvalho Chehab #if 0
380139c1cb2bSJonathan McCrohan 	/* No hierarchical channels support in BDA */
38029a0bf528SMauro Carvalho Chehab 	/* Priority (only for hierarchical channels) */
38039a0bf528SMauro Carvalho Chehab 	switch (channel->priority) {
38049a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_LOW:
3805cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3806cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38079a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_LO);
38089a0bf528SMauro Carvalho Chehab 		break;
38099a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_HIGH:
3810cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3811cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38129a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_HI));
38139a0bf528SMauro Carvalho Chehab 		break;
3814df561f66SGustavo A. R. Silva 	case DRX_PRIORITY_UNKNOWN:
38159a0bf528SMauro Carvalho Chehab 	default:
38169a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
38179a0bf528SMauro Carvalho Chehab 		goto error;
38189a0bf528SMauro Carvalho Chehab 	}
38199a0bf528SMauro Carvalho Chehab #else
3820868c9a17SMauro Carvalho Chehab 	/* Set Priority high */
3821cd7a67a4SMauro Carvalho Chehab 	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
38229a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
38239a0bf528SMauro Carvalho Chehab 	if (status < 0)
38249a0bf528SMauro Carvalho Chehab 		goto error;
38259a0bf528SMauro Carvalho Chehab #endif
38269a0bf528SMauro Carvalho Chehab 
38279a0bf528SMauro Carvalho Chehab 	/* coderate */
38289a0bf528SMauro Carvalho Chehab 	switch (state->props.code_rate_HP) {
38299a0bf528SMauro Carvalho Chehab 	case FEC_AUTO:
38301cef3942SMauro Carvalho Chehab 	default:	/* try first guess DRX_CODERATE_2DIV3 */
38319a0bf528SMauro Carvalho Chehab 	case FEC_2_3:
3832cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
38339a0bf528SMauro Carvalho Chehab 		break;
38349a0bf528SMauro Carvalho Chehab 	case FEC_1_2:
3835cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
38369a0bf528SMauro Carvalho Chehab 		break;
38379a0bf528SMauro Carvalho Chehab 	case FEC_3_4:
3838cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
38399a0bf528SMauro Carvalho Chehab 		break;
38409a0bf528SMauro Carvalho Chehab 	case FEC_5_6:
3841cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
38429a0bf528SMauro Carvalho Chehab 		break;
38439a0bf528SMauro Carvalho Chehab 	case FEC_7_8:
3844cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
38459a0bf528SMauro Carvalho Chehab 		break;
38469a0bf528SMauro Carvalho Chehab 	}
38479a0bf528SMauro Carvalho Chehab 
3848ab5060cdSMauro Carvalho Chehab 	/*
3849868c9a17SMauro Carvalho Chehab 	 * SAW filter selection: normally not necessary, but if wanted
3850ab5060cdSMauro Carvalho Chehab 	 * the application can select a SAW filter via the driver by
3851ab5060cdSMauro Carvalho Chehab 	 * using UIOs
3852ab5060cdSMauro Carvalho Chehab 	 */
3853ab5060cdSMauro Carvalho Chehab 
38549a0bf528SMauro Carvalho Chehab 	/* First determine real bandwidth (Hz) */
38559a0bf528SMauro Carvalho Chehab 	/* Also set delay for impulse noise cruncher */
3856ab5060cdSMauro Carvalho Chehab 	/*
3857ab5060cdSMauro Carvalho Chehab 	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3858ab5060cdSMauro Carvalho Chehab 	 * changed by SC for fix for some 8K,1/8 guard but is restored by
3859ab5060cdSMauro Carvalho Chehab 	 * InitEC and ResetEC functions
3860ab5060cdSMauro Carvalho Chehab 	 */
38619a0bf528SMauro Carvalho Chehab 	switch (state->props.bandwidth_hz) {
38629a0bf528SMauro Carvalho Chehab 	case 0:
38639a0bf528SMauro Carvalho Chehab 		state->props.bandwidth_hz = 8000000;
3864df561f66SGustavo A. R. Silva 		fallthrough;
38659a0bf528SMauro Carvalho Chehab 	case 8000000:
38669a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3867ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3868ab5060cdSMauro Carvalho Chehab 				 3052);
38699a0bf528SMauro Carvalho Chehab 		if (status < 0)
38709a0bf528SMauro Carvalho Chehab 			goto error;
38719a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 8 MHz */
3872ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3873ab5060cdSMauro Carvalho Chehab 				 7);
38749a0bf528SMauro Carvalho Chehab 		if (status < 0)
38759a0bf528SMauro Carvalho Chehab 			goto error;
3876ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3877ab5060cdSMauro Carvalho Chehab 				 7);
38789a0bf528SMauro Carvalho Chehab 		if (status < 0)
38799a0bf528SMauro Carvalho Chehab 			goto error;
3880ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3881ab5060cdSMauro Carvalho Chehab 				 7);
38829a0bf528SMauro Carvalho Chehab 		if (status < 0)
38839a0bf528SMauro Carvalho Chehab 			goto error;
3884ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3885ab5060cdSMauro Carvalho Chehab 				 1);
38869a0bf528SMauro Carvalho Chehab 		if (status < 0)
38879a0bf528SMauro Carvalho Chehab 			goto error;
38889a0bf528SMauro Carvalho Chehab 		break;
38899a0bf528SMauro Carvalho Chehab 	case 7000000:
38909a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3891ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3892ab5060cdSMauro Carvalho Chehab 				 3491);
38939a0bf528SMauro Carvalho Chehab 		if (status < 0)
38949a0bf528SMauro Carvalho Chehab 			goto error;
38959a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 7 MHz */
3896ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3897ab5060cdSMauro Carvalho Chehab 				 8);
38989a0bf528SMauro Carvalho Chehab 		if (status < 0)
38999a0bf528SMauro Carvalho Chehab 			goto error;
3900ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3901ab5060cdSMauro Carvalho Chehab 				 8);
39029a0bf528SMauro Carvalho Chehab 		if (status < 0)
39039a0bf528SMauro Carvalho Chehab 			goto error;
3904ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3905ab5060cdSMauro Carvalho Chehab 				 4);
39069a0bf528SMauro Carvalho Chehab 		if (status < 0)
39079a0bf528SMauro Carvalho Chehab 			goto error;
3908ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3909ab5060cdSMauro Carvalho Chehab 				 1);
39109a0bf528SMauro Carvalho Chehab 		if (status < 0)
39119a0bf528SMauro Carvalho Chehab 			goto error;
39129a0bf528SMauro Carvalho Chehab 		break;
39139a0bf528SMauro Carvalho Chehab 	case 6000000:
39149a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3915ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3916ab5060cdSMauro Carvalho Chehab 				 4073);
39179a0bf528SMauro Carvalho Chehab 		if (status < 0)
39189a0bf528SMauro Carvalho Chehab 			goto error;
39199a0bf528SMauro Carvalho Chehab 		/* cochannel protection for NTSC 6 MHz */
3920ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3921ab5060cdSMauro Carvalho Chehab 				 19);
39229a0bf528SMauro Carvalho Chehab 		if (status < 0)
39239a0bf528SMauro Carvalho Chehab 			goto error;
3924ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3925ab5060cdSMauro Carvalho Chehab 				 19);
39269a0bf528SMauro Carvalho Chehab 		if (status < 0)
39279a0bf528SMauro Carvalho Chehab 			goto error;
3928ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3929ab5060cdSMauro Carvalho Chehab 				 14);
39309a0bf528SMauro Carvalho Chehab 		if (status < 0)
39319a0bf528SMauro Carvalho Chehab 			goto error;
3932ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3933ab5060cdSMauro Carvalho Chehab 				 1);
39349a0bf528SMauro Carvalho Chehab 		if (status < 0)
39359a0bf528SMauro Carvalho Chehab 			goto error;
39369a0bf528SMauro Carvalho Chehab 		break;
39379a0bf528SMauro Carvalho Chehab 	default:
39389a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
39399a0bf528SMauro Carvalho Chehab 		goto error;
39409a0bf528SMauro Carvalho Chehab 	}
39419a0bf528SMauro Carvalho Chehab 
3942cd7a67a4SMauro Carvalho Chehab 	if (iqm_rc_rate_ofs == 0) {
39439a0bf528SMauro Carvalho Chehab 		/* Now compute IQM_RC_RATE_OFS
39449a0bf528SMauro Carvalho Chehab 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
39459a0bf528SMauro Carvalho Chehab 			=>
39469a0bf528SMauro Carvalho Chehab 			((SysFreq / BandWidth) * (2^21)) - (2^23)
39479a0bf528SMauro Carvalho Chehab 			*/
39489a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^28)  */
3949ab5060cdSMauro Carvalho Chehab 		/*
3950ab5060cdSMauro Carvalho Chehab 		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
3951ab5060cdSMauro Carvalho Chehab 		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
3952ab5060cdSMauro Carvalho Chehab 		 *	=> assert(109714272 > 48000000) = true
3953ab5060cdSMauro Carvalho Chehab 		 * so Frac 28 can be used
3954ab5060cdSMauro Carvalho Chehab 		 */
3955cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = Frac28a((u32)
3956cd7a67a4SMauro Carvalho Chehab 					((state->m_sys_clock_freq *
39579a0bf528SMauro Carvalho Chehab 						1000) / 3), bandwidth);
39589a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3959cd7a67a4SMauro Carvalho Chehab 		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
3960cd7a67a4SMauro Carvalho Chehab 			iqm_rc_rate_ofs += 0x80L;
3961cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
39629a0bf528SMauro Carvalho Chehab 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
3963cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
39649a0bf528SMauro Carvalho Chehab 	}
39659a0bf528SMauro Carvalho Chehab 
3966cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate_ofs &=
39679a0bf528SMauro Carvalho Chehab 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
39689a0bf528SMauro Carvalho Chehab 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
3969cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
39709a0bf528SMauro Carvalho Chehab 	if (status < 0)
39719a0bf528SMauro Carvalho Chehab 		goto error;
39729a0bf528SMauro Carvalho Chehab 
39739a0bf528SMauro Carvalho Chehab 	/* Bandwidth setting done */
39749a0bf528SMauro Carvalho Chehab 
39759a0bf528SMauro Carvalho Chehab #if 0
3976cd7a67a4SMauro Carvalho Chehab 	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
39779a0bf528SMauro Carvalho Chehab 	if (status < 0)
39789a0bf528SMauro Carvalho Chehab 		goto error;
39799a0bf528SMauro Carvalho Chehab #endif
3980ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
3981ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
39829a0bf528SMauro Carvalho Chehab 	if (status < 0)
39839a0bf528SMauro Carvalho Chehab 		goto error;
39849a0bf528SMauro Carvalho Chehab 
3985ab5060cdSMauro Carvalho Chehab 	/*== start SC, write channel settings to SC ==========================*/
39869a0bf528SMauro Carvalho Chehab 
39879a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
39889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
39899a0bf528SMauro Carvalho Chehab 	if (status < 0)
39909a0bf528SMauro Carvalho Chehab 		goto error;
39919a0bf528SMauro Carvalho Chehab 
39929a0bf528SMauro Carvalho Chehab 	/* Enable SC after setting all other parameters */
39939a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_STATE__A, 0);
39949a0bf528SMauro Carvalho Chehab 	if (status < 0)
39959a0bf528SMauro Carvalho Chehab 		goto error;
39969a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
39979a0bf528SMauro Carvalho Chehab 	if (status < 0)
39989a0bf528SMauro Carvalho Chehab 		goto error;
39999a0bf528SMauro Carvalho Chehab 
40009a0bf528SMauro Carvalho Chehab 
4001ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4002ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
4003ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
40049a0bf528SMauro Carvalho Chehab 	if (status < 0)
40059a0bf528SMauro Carvalho Chehab 		goto error;
40069a0bf528SMauro Carvalho Chehab 
40079a0bf528SMauro Carvalho Chehab 	/* Write SC parameter registers, set all AUTO flags in operation mode */
40089a0bf528SMauro Carvalho Chehab 	param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
40099a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
40109a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
40119a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
40129a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4013cd7a67a4SMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4014cd7a67a4SMauro Carvalho Chehab 				0, transmission_params, param1, 0, 0, 0);
40159a0bf528SMauro Carvalho Chehab 	if (status < 0)
40169a0bf528SMauro Carvalho Chehab 		goto error;
40179a0bf528SMauro Carvalho Chehab 
4018cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code)
4019cd7a67a4SMauro Carvalho Chehab 		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
40209a0bf528SMauro Carvalho Chehab error:
40219a0bf528SMauro Carvalho Chehab 	if (status < 0)
40223a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40239a0bf528SMauro Carvalho Chehab 
40249a0bf528SMauro Carvalho Chehab 	return status;
40259a0bf528SMauro Carvalho Chehab }
40269a0bf528SMauro Carvalho Chehab 
40279a0bf528SMauro Carvalho Chehab 
40289a0bf528SMauro Carvalho Chehab /*============================================================================*/
40299a0bf528SMauro Carvalho Chehab 
403034eb9751SMauro Carvalho Chehab /*
403139c1cb2bSJonathan McCrohan * \brief Retrieve lock status .
40329a0bf528SMauro Carvalho Chehab * \param demod    Pointer to demodulator instance.
40339a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
40349a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
40359a0bf528SMauro Carvalho Chehab *
40369a0bf528SMauro Carvalho Chehab */
get_dvbt_lock_status(struct drxk_state * state,u32 * p_lock_status)4037cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
40389a0bf528SMauro Carvalho Chehab {
40399a0bf528SMauro Carvalho Chehab 	int status;
40409a0bf528SMauro Carvalho Chehab 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
40419a0bf528SMauro Carvalho Chehab 				    OFDM_SC_RA_RAM_LOCK_FEC__M);
40429a0bf528SMauro Carvalho Chehab 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
40439a0bf528SMauro Carvalho Chehab 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
40449a0bf528SMauro Carvalho Chehab 
4045cd7a67a4SMauro Carvalho Chehab 	u16 sc_ra_ram_lock = 0;
4046cd7a67a4SMauro Carvalho Chehab 	u16 sc_comm_exec = 0;
40479a0bf528SMauro Carvalho Chehab 
40489a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
40499a0bf528SMauro Carvalho Chehab 
4050cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
40519a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
40529a0bf528SMauro Carvalho Chehab 	/* Check if SC is running */
4053cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
40549a0bf528SMauro Carvalho Chehab 	if (status < 0)
40559a0bf528SMauro Carvalho Chehab 		goto end;
4056cd7a67a4SMauro Carvalho Chehab 	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
40579a0bf528SMauro Carvalho Chehab 		goto end;
40589a0bf528SMauro Carvalho Chehab 
4059cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
40609a0bf528SMauro Carvalho Chehab 	if (status < 0)
40619a0bf528SMauro Carvalho Chehab 		goto end;
40629a0bf528SMauro Carvalho Chehab 
4063cd7a67a4SMauro Carvalho Chehab 	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4064cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
4065cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4066cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = FEC_LOCK;
4067cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4068cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
4069cd7a67a4SMauro Carvalho Chehab 	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4070cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
40719a0bf528SMauro Carvalho Chehab end:
40729a0bf528SMauro Carvalho Chehab 	if (status < 0)
40733a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40749a0bf528SMauro Carvalho Chehab 
40759a0bf528SMauro Carvalho Chehab 	return status;
40769a0bf528SMauro Carvalho Chehab }
40779a0bf528SMauro Carvalho Chehab 
power_up_qam(struct drxk_state * state)4078cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state)
40799a0bf528SMauro Carvalho Chehab {
4080cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
40819a0bf528SMauro Carvalho Chehab 	int status;
40829a0bf528SMauro Carvalho Chehab 
40839a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4084cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
40859a0bf528SMauro Carvalho Chehab 	if (status < 0)
40863a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40879a0bf528SMauro Carvalho Chehab 
40889a0bf528SMauro Carvalho Chehab 	return status;
40899a0bf528SMauro Carvalho Chehab }
40909a0bf528SMauro Carvalho Chehab 
40919a0bf528SMauro Carvalho Chehab 
409234eb9751SMauro Carvalho Chehab /* Power Down QAM */
power_down_qam(struct drxk_state * state)4093cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state)
40949a0bf528SMauro Carvalho Chehab {
40959a0bf528SMauro Carvalho Chehab 	u16 data = 0;
4096cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
40979a0bf528SMauro Carvalho Chehab 	int status = 0;
40989a0bf528SMauro Carvalho Chehab 
40999a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41009a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
41019a0bf528SMauro Carvalho Chehab 	if (status < 0)
41029a0bf528SMauro Carvalho Chehab 		goto error;
41039a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
41049a0bf528SMauro Carvalho Chehab 		/*
41059a0bf528SMauro Carvalho Chehab 			STOP demodulator
41069a0bf528SMauro Carvalho Chehab 			QAM and HW blocks
41079a0bf528SMauro Carvalho Chehab 			*/
41089a0bf528SMauro Carvalho Chehab 		/* stop all comstate->m_exec */
41099a0bf528SMauro Carvalho Chehab 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
41109a0bf528SMauro Carvalho Chehab 		if (status < 0)
41119a0bf528SMauro Carvalho Chehab 			goto error;
4112ab5060cdSMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4113ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4114ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
41159a0bf528SMauro Carvalho Chehab 		if (status < 0)
41169a0bf528SMauro Carvalho Chehab 			goto error;
41179a0bf528SMauro Carvalho Chehab 	}
41189a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
4119cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
41209a0bf528SMauro Carvalho Chehab 
41219a0bf528SMauro Carvalho Chehab error:
41229a0bf528SMauro Carvalho Chehab 	if (status < 0)
41233a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41249a0bf528SMauro Carvalho Chehab 
41259a0bf528SMauro Carvalho Chehab 	return status;
41269a0bf528SMauro Carvalho Chehab }
41279a0bf528SMauro Carvalho Chehab 
41289a0bf528SMauro Carvalho Chehab /*============================================================================*/
41299a0bf528SMauro Carvalho Chehab 
413034eb9751SMauro Carvalho Chehab /*
41319a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
41329a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
41339a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
41349a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41359a0bf528SMauro Carvalho Chehab *
41369a0bf528SMauro Carvalho Chehab *  NOTE:
41379a0bf528SMauro Carvalho Chehab *  Take into account that for certain settings the errorcounters can overflow.
41389a0bf528SMauro Carvalho Chehab *  The implementation does not check this.
41399a0bf528SMauro Carvalho Chehab *
41409a0bf528SMauro Carvalho Chehab */
set_qam_measurement(struct drxk_state * state,enum e_drxk_constellation modulation,u32 symbol_rate)4141cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state,
4142cd7a67a4SMauro Carvalho Chehab 			     enum e_drxk_constellation modulation,
4143cd7a67a4SMauro Carvalho Chehab 			     u32 symbol_rate)
41449a0bf528SMauro Carvalho Chehab {
4145cd7a67a4SMauro Carvalho Chehab 	u32 fec_bits_desired = 0;	/* BER accounting period */
4146cd7a67a4SMauro Carvalho Chehab 	u32 fec_rs_period_total = 0;	/* Total period */
4147cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
4148cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
41499a0bf528SMauro Carvalho Chehab 	int status = 0;
41509a0bf528SMauro Carvalho Chehab 
41519a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41529a0bf528SMauro Carvalho Chehab 
4153cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1;
4154cd7a67a4SMauro Carvalho Chehab 	/* fec_bits_desired = symbol_rate [kHz] *
41559a0bf528SMauro Carvalho Chehab 		FrameLenght [ms] *
41569a0bf528SMauro Carvalho Chehab 		(modulation + 1) *
41579a0bf528SMauro Carvalho Chehab 		SyncLoss (== 1) *
41589a0bf528SMauro Carvalho Chehab 		ViterbiLoss (==1)
41599a0bf528SMauro Carvalho Chehab 		*/
41609a0bf528SMauro Carvalho Chehab 	switch (modulation) {
41619a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM16:
4162cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 4 * symbol_rate;
41639a0bf528SMauro Carvalho Chehab 		break;
41649a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM32:
4165cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 5 * symbol_rate;
41669a0bf528SMauro Carvalho Chehab 		break;
41679a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM64:
4168cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 6 * symbol_rate;
41699a0bf528SMauro Carvalho Chehab 		break;
41709a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM128:
4171cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 7 * symbol_rate;
41729a0bf528SMauro Carvalho Chehab 		break;
41739a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM256:
4174cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 8 * symbol_rate;
41759a0bf528SMauro Carvalho Chehab 		break;
41769a0bf528SMauro Carvalho Chehab 	default:
41779a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
41789a0bf528SMauro Carvalho Chehab 	}
41799a0bf528SMauro Carvalho Chehab 	if (status < 0)
41809a0bf528SMauro Carvalho Chehab 		goto error;
41819a0bf528SMauro Carvalho Chehab 
4182cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
4183cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired *= 500;	/* meas. period [ms] */
41849a0bf528SMauro Carvalho Chehab 
41859a0bf528SMauro Carvalho Chehab 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4186cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total = fec_bits_desired / 1632 */
4187cd7a67a4SMauro Carvalho Chehab 	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
41889a0bf528SMauro Carvalho Chehab 
4189cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
4190cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4191cd7a67a4SMauro Carvalho Chehab 	if (fec_rs_prescale == 0) {
41929a0bf528SMauro Carvalho Chehab 		/* Divide by zero (though impossible) */
41939a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
41949a0bf528SMauro Carvalho Chehab 		if (status < 0)
41959a0bf528SMauro Carvalho Chehab 			goto error;
41969a0bf528SMauro Carvalho Chehab 	}
4197cd7a67a4SMauro Carvalho Chehab 	fec_rs_period =
4198cd7a67a4SMauro Carvalho Chehab 		((u16) fec_rs_period_total +
4199cd7a67a4SMauro Carvalho Chehab 		(fec_rs_prescale >> 1)) / fec_rs_prescale;
42009a0bf528SMauro Carvalho Chehab 
42019a0bf528SMauro Carvalho Chehab 	/* write corresponding registers */
4202cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
42039a0bf528SMauro Carvalho Chehab 	if (status < 0)
42049a0bf528SMauro Carvalho Chehab 		goto error;
4205ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4206ab5060cdSMauro Carvalho Chehab 			 fec_rs_prescale);
42079a0bf528SMauro Carvalho Chehab 	if (status < 0)
42089a0bf528SMauro Carvalho Chehab 		goto error;
4209cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
42109a0bf528SMauro Carvalho Chehab error:
42119a0bf528SMauro Carvalho Chehab 	if (status < 0)
42123a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
42139a0bf528SMauro Carvalho Chehab 	return status;
42149a0bf528SMauro Carvalho Chehab }
42159a0bf528SMauro Carvalho Chehab 
set_qam16(struct drxk_state * state)4216cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state)
42179a0bf528SMauro Carvalho Chehab {
42189a0bf528SMauro Carvalho Chehab 	int status = 0;
42199a0bf528SMauro Carvalho Chehab 
42209a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42219a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
42229a0bf528SMauro Carvalho Chehab 	/* Equalizer */
42239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
42249a0bf528SMauro Carvalho Chehab 	if (status < 0)
42259a0bf528SMauro Carvalho Chehab 		goto error;
42269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
42279a0bf528SMauro Carvalho Chehab 	if (status < 0)
42289a0bf528SMauro Carvalho Chehab 		goto error;
42299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
42309a0bf528SMauro Carvalho Chehab 	if (status < 0)
42319a0bf528SMauro Carvalho Chehab 		goto error;
42329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
42339a0bf528SMauro Carvalho Chehab 	if (status < 0)
42349a0bf528SMauro Carvalho Chehab 		goto error;
42359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
42369a0bf528SMauro Carvalho Chehab 	if (status < 0)
42379a0bf528SMauro Carvalho Chehab 		goto error;
42389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
42399a0bf528SMauro Carvalho Chehab 	if (status < 0)
42409a0bf528SMauro Carvalho Chehab 		goto error;
42419a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
42429a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
42439a0bf528SMauro Carvalho Chehab 	if (status < 0)
42449a0bf528SMauro Carvalho Chehab 		goto error;
42459a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
42469a0bf528SMauro Carvalho Chehab 	if (status < 0)
42479a0bf528SMauro Carvalho Chehab 		goto error;
42489a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
42499a0bf528SMauro Carvalho Chehab 	if (status < 0)
42509a0bf528SMauro Carvalho Chehab 		goto error;
42519a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
42529a0bf528SMauro Carvalho Chehab 	if (status < 0)
42539a0bf528SMauro Carvalho Chehab 		goto error;
42549a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
42559a0bf528SMauro Carvalho Chehab 	if (status < 0)
42569a0bf528SMauro Carvalho Chehab 		goto error;
42579a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
42589a0bf528SMauro Carvalho Chehab 	if (status < 0)
42599a0bf528SMauro Carvalho Chehab 		goto error;
42609a0bf528SMauro Carvalho Chehab 
42619a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
42629a0bf528SMauro Carvalho Chehab 	if (status < 0)
42639a0bf528SMauro Carvalho Chehab 		goto error;
42649a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
42659a0bf528SMauro Carvalho Chehab 	if (status < 0)
42669a0bf528SMauro Carvalho Chehab 		goto error;
42679a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
42689a0bf528SMauro Carvalho Chehab 	if (status < 0)
42699a0bf528SMauro Carvalho Chehab 		goto error;
42709a0bf528SMauro Carvalho Chehab 
42719a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4272ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4273ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM16);
42749a0bf528SMauro Carvalho Chehab 	if (status < 0)
42759a0bf528SMauro Carvalho Chehab 		goto error;
42769a0bf528SMauro Carvalho Chehab 
42779a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
42789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
42799a0bf528SMauro Carvalho Chehab 	if (status < 0)
42809a0bf528SMauro Carvalho Chehab 		goto error;
42819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
42829a0bf528SMauro Carvalho Chehab 	if (status < 0)
42839a0bf528SMauro Carvalho Chehab 		goto error;
42849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
42859a0bf528SMauro Carvalho Chehab 	if (status < 0)
42869a0bf528SMauro Carvalho Chehab 		goto error;
42879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
42889a0bf528SMauro Carvalho Chehab 	if (status < 0)
42899a0bf528SMauro Carvalho Chehab 		goto error;
42909a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
42919a0bf528SMauro Carvalho Chehab 	if (status < 0)
42929a0bf528SMauro Carvalho Chehab 		goto error;
42939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
42949a0bf528SMauro Carvalho Chehab 	if (status < 0)
42959a0bf528SMauro Carvalho Chehab 		goto error;
42969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
42979a0bf528SMauro Carvalho Chehab 	if (status < 0)
42989a0bf528SMauro Carvalho Chehab 		goto error;
42999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43009a0bf528SMauro Carvalho Chehab 	if (status < 0)
43019a0bf528SMauro Carvalho Chehab 		goto error;
43029a0bf528SMauro Carvalho Chehab 
43039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43049a0bf528SMauro Carvalho Chehab 	if (status < 0)
43059a0bf528SMauro Carvalho Chehab 		goto error;
43069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43079a0bf528SMauro Carvalho Chehab 	if (status < 0)
43089a0bf528SMauro Carvalho Chehab 		goto error;
43099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
43109a0bf528SMauro Carvalho Chehab 	if (status < 0)
43119a0bf528SMauro Carvalho Chehab 		goto error;
43129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
43139a0bf528SMauro Carvalho Chehab 	if (status < 0)
43149a0bf528SMauro Carvalho Chehab 		goto error;
43159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
43169a0bf528SMauro Carvalho Chehab 	if (status < 0)
43179a0bf528SMauro Carvalho Chehab 		goto error;
43189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
43199a0bf528SMauro Carvalho Chehab 	if (status < 0)
43209a0bf528SMauro Carvalho Chehab 		goto error;
43219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
43229a0bf528SMauro Carvalho Chehab 	if (status < 0)
43239a0bf528SMauro Carvalho Chehab 		goto error;
43249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
43259a0bf528SMauro Carvalho Chehab 	if (status < 0)
43269a0bf528SMauro Carvalho Chehab 		goto error;
43279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
43289a0bf528SMauro Carvalho Chehab 	if (status < 0)
43299a0bf528SMauro Carvalho Chehab 		goto error;
43309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
43319a0bf528SMauro Carvalho Chehab 	if (status < 0)
43329a0bf528SMauro Carvalho Chehab 		goto error;
43339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
43349a0bf528SMauro Carvalho Chehab 	if (status < 0)
43359a0bf528SMauro Carvalho Chehab 		goto error;
43369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
43379a0bf528SMauro Carvalho Chehab 	if (status < 0)
43389a0bf528SMauro Carvalho Chehab 		goto error;
43399a0bf528SMauro Carvalho Chehab 
43409a0bf528SMauro Carvalho Chehab 
43419a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
43429a0bf528SMauro Carvalho Chehab 
43439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
43449a0bf528SMauro Carvalho Chehab 	if (status < 0)
43459a0bf528SMauro Carvalho Chehab 		goto error;
43469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
43479a0bf528SMauro Carvalho Chehab 	if (status < 0)
43489a0bf528SMauro Carvalho Chehab 		goto error;
43499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
43509a0bf528SMauro Carvalho Chehab 	if (status < 0)
43519a0bf528SMauro Carvalho Chehab 		goto error;
43529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
43539a0bf528SMauro Carvalho Chehab 	if (status < 0)
43549a0bf528SMauro Carvalho Chehab 		goto error;
43559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
43569a0bf528SMauro Carvalho Chehab 	if (status < 0)
43579a0bf528SMauro Carvalho Chehab 		goto error;
43589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
43599a0bf528SMauro Carvalho Chehab 	if (status < 0)
43609a0bf528SMauro Carvalho Chehab 		goto error;
43619a0bf528SMauro Carvalho Chehab 
43629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
43639a0bf528SMauro Carvalho Chehab 	if (status < 0)
43649a0bf528SMauro Carvalho Chehab 		goto error;
43659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
43669a0bf528SMauro Carvalho Chehab 	if (status < 0)
43679a0bf528SMauro Carvalho Chehab 		goto error;
43689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
43699a0bf528SMauro Carvalho Chehab 	if (status < 0)
43709a0bf528SMauro Carvalho Chehab 		goto error;
43719a0bf528SMauro Carvalho Chehab 
43729a0bf528SMauro Carvalho Chehab 
43739a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
43749a0bf528SMauro Carvalho Chehab 
43759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
43769a0bf528SMauro Carvalho Chehab 	if (status < 0)
43779a0bf528SMauro Carvalho Chehab 		goto error;
43789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
43799a0bf528SMauro Carvalho Chehab 	if (status < 0)
43809a0bf528SMauro Carvalho Chehab 		goto error;
43819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
43829a0bf528SMauro Carvalho Chehab 	if (status < 0)
43839a0bf528SMauro Carvalho Chehab 		goto error;
43849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
43859a0bf528SMauro Carvalho Chehab 	if (status < 0)
43869a0bf528SMauro Carvalho Chehab 		goto error;
43879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
43889a0bf528SMauro Carvalho Chehab 	if (status < 0)
43899a0bf528SMauro Carvalho Chehab 		goto error;
43909a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
43919a0bf528SMauro Carvalho Chehab 	if (status < 0)
43929a0bf528SMauro Carvalho Chehab 		goto error;
43939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
43949a0bf528SMauro Carvalho Chehab 	if (status < 0)
43959a0bf528SMauro Carvalho Chehab 		goto error;
43969a0bf528SMauro Carvalho Chehab 
43979a0bf528SMauro Carvalho Chehab error:
43989a0bf528SMauro Carvalho Chehab 	if (status < 0)
43993a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
44009a0bf528SMauro Carvalho Chehab 	return status;
44019a0bf528SMauro Carvalho Chehab }
44029a0bf528SMauro Carvalho Chehab 
44039a0bf528SMauro Carvalho Chehab /*============================================================================*/
44049a0bf528SMauro Carvalho Chehab 
440534eb9751SMauro Carvalho Chehab /*
44069a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44079a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
44089a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
44099a0bf528SMauro Carvalho Chehab */
set_qam32(struct drxk_state * state)4410cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state)
44119a0bf528SMauro Carvalho Chehab {
44129a0bf528SMauro Carvalho Chehab 	int status = 0;
44139a0bf528SMauro Carvalho Chehab 
44149a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
44159a0bf528SMauro Carvalho Chehab 
44169a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
44179a0bf528SMauro Carvalho Chehab 	/* Equalizer */
44189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
44199a0bf528SMauro Carvalho Chehab 	if (status < 0)
44209a0bf528SMauro Carvalho Chehab 		goto error;
44219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
44229a0bf528SMauro Carvalho Chehab 	if (status < 0)
44239a0bf528SMauro Carvalho Chehab 		goto error;
44249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
44259a0bf528SMauro Carvalho Chehab 	if (status < 0)
44269a0bf528SMauro Carvalho Chehab 		goto error;
44279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
44289a0bf528SMauro Carvalho Chehab 	if (status < 0)
44299a0bf528SMauro Carvalho Chehab 		goto error;
44309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
44319a0bf528SMauro Carvalho Chehab 	if (status < 0)
44329a0bf528SMauro Carvalho Chehab 		goto error;
44339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
44349a0bf528SMauro Carvalho Chehab 	if (status < 0)
44359a0bf528SMauro Carvalho Chehab 		goto error;
44369a0bf528SMauro Carvalho Chehab 
44379a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
44389a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
44399a0bf528SMauro Carvalho Chehab 	if (status < 0)
44409a0bf528SMauro Carvalho Chehab 		goto error;
44419a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
44429a0bf528SMauro Carvalho Chehab 	if (status < 0)
44439a0bf528SMauro Carvalho Chehab 		goto error;
44449a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
44459a0bf528SMauro Carvalho Chehab 	if (status < 0)
44469a0bf528SMauro Carvalho Chehab 		goto error;
44479a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
44489a0bf528SMauro Carvalho Chehab 	if (status < 0)
44499a0bf528SMauro Carvalho Chehab 		goto error;
44509a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
44519a0bf528SMauro Carvalho Chehab 	if (status < 0)
44529a0bf528SMauro Carvalho Chehab 		goto error;
44539a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
44549a0bf528SMauro Carvalho Chehab 	if (status < 0)
44559a0bf528SMauro Carvalho Chehab 		goto error;
44569a0bf528SMauro Carvalho Chehab 
44579a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
44589a0bf528SMauro Carvalho Chehab 	if (status < 0)
44599a0bf528SMauro Carvalho Chehab 		goto error;
44609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
44619a0bf528SMauro Carvalho Chehab 	if (status < 0)
44629a0bf528SMauro Carvalho Chehab 		goto error;
44639a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
44649a0bf528SMauro Carvalho Chehab 	if (status < 0)
44659a0bf528SMauro Carvalho Chehab 		goto error;
44669a0bf528SMauro Carvalho Chehab 
44679a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
44689a0bf528SMauro Carvalho Chehab 
4469ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4470ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM32);
44719a0bf528SMauro Carvalho Chehab 	if (status < 0)
44729a0bf528SMauro Carvalho Chehab 		goto error;
44739a0bf528SMauro Carvalho Chehab 
44749a0bf528SMauro Carvalho Chehab 
44759a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
44769a0bf528SMauro Carvalho Chehab 
44779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
44789a0bf528SMauro Carvalho Chehab 	if (status < 0)
44799a0bf528SMauro Carvalho Chehab 		goto error;
44809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
44819a0bf528SMauro Carvalho Chehab 	if (status < 0)
44829a0bf528SMauro Carvalho Chehab 		goto error;
44839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
44849a0bf528SMauro Carvalho Chehab 	if (status < 0)
44859a0bf528SMauro Carvalho Chehab 		goto error;
44869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
44879a0bf528SMauro Carvalho Chehab 	if (status < 0)
44889a0bf528SMauro Carvalho Chehab 		goto error;
44899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
44909a0bf528SMauro Carvalho Chehab 	if (status < 0)
44919a0bf528SMauro Carvalho Chehab 		goto error;
44929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
44939a0bf528SMauro Carvalho Chehab 	if (status < 0)
44949a0bf528SMauro Carvalho Chehab 		goto error;
44959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
44969a0bf528SMauro Carvalho Chehab 	if (status < 0)
44979a0bf528SMauro Carvalho Chehab 		goto error;
44989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
44999a0bf528SMauro Carvalho Chehab 	if (status < 0)
45009a0bf528SMauro Carvalho Chehab 		goto error;
45019a0bf528SMauro Carvalho Chehab 
45029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45039a0bf528SMauro Carvalho Chehab 	if (status < 0)
45049a0bf528SMauro Carvalho Chehab 		goto error;
45059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45069a0bf528SMauro Carvalho Chehab 	if (status < 0)
45079a0bf528SMauro Carvalho Chehab 		goto error;
45089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
45099a0bf528SMauro Carvalho Chehab 	if (status < 0)
45109a0bf528SMauro Carvalho Chehab 		goto error;
45119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
45129a0bf528SMauro Carvalho Chehab 	if (status < 0)
45139a0bf528SMauro Carvalho Chehab 		goto error;
45149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
45159a0bf528SMauro Carvalho Chehab 	if (status < 0)
45169a0bf528SMauro Carvalho Chehab 		goto error;
45179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
45189a0bf528SMauro Carvalho Chehab 	if (status < 0)
45199a0bf528SMauro Carvalho Chehab 		goto error;
45209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
45219a0bf528SMauro Carvalho Chehab 	if (status < 0)
45229a0bf528SMauro Carvalho Chehab 		goto error;
45239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
45249a0bf528SMauro Carvalho Chehab 	if (status < 0)
45259a0bf528SMauro Carvalho Chehab 		goto error;
45269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
45279a0bf528SMauro Carvalho Chehab 	if (status < 0)
45289a0bf528SMauro Carvalho Chehab 		goto error;
45299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
45309a0bf528SMauro Carvalho Chehab 	if (status < 0)
45319a0bf528SMauro Carvalho Chehab 		goto error;
45329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
45339a0bf528SMauro Carvalho Chehab 	if (status < 0)
45349a0bf528SMauro Carvalho Chehab 		goto error;
45359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
45369a0bf528SMauro Carvalho Chehab 	if (status < 0)
45379a0bf528SMauro Carvalho Chehab 		goto error;
45389a0bf528SMauro Carvalho Chehab 
45399a0bf528SMauro Carvalho Chehab 
45409a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
45419a0bf528SMauro Carvalho Chehab 
45429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
45439a0bf528SMauro Carvalho Chehab 	if (status < 0)
45449a0bf528SMauro Carvalho Chehab 		goto error;
45459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
45469a0bf528SMauro Carvalho Chehab 	if (status < 0)
45479a0bf528SMauro Carvalho Chehab 		goto error;
45489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
45499a0bf528SMauro Carvalho Chehab 	if (status < 0)
45509a0bf528SMauro Carvalho Chehab 		goto error;
45519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
45529a0bf528SMauro Carvalho Chehab 	if (status < 0)
45539a0bf528SMauro Carvalho Chehab 		goto error;
45549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
45559a0bf528SMauro Carvalho Chehab 	if (status < 0)
45569a0bf528SMauro Carvalho Chehab 		goto error;
45579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
45589a0bf528SMauro Carvalho Chehab 	if (status < 0)
45599a0bf528SMauro Carvalho Chehab 		goto error;
45609a0bf528SMauro Carvalho Chehab 
45619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
45629a0bf528SMauro Carvalho Chehab 	if (status < 0)
45639a0bf528SMauro Carvalho Chehab 		goto error;
45649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
45659a0bf528SMauro Carvalho Chehab 	if (status < 0)
45669a0bf528SMauro Carvalho Chehab 		goto error;
45679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
45689a0bf528SMauro Carvalho Chehab 	if (status < 0)
45699a0bf528SMauro Carvalho Chehab 		goto error;
45709a0bf528SMauro Carvalho Chehab 
45719a0bf528SMauro Carvalho Chehab 
45729a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
45739a0bf528SMauro Carvalho Chehab 
45749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
45759a0bf528SMauro Carvalho Chehab 	if (status < 0)
45769a0bf528SMauro Carvalho Chehab 		goto error;
45779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
45789a0bf528SMauro Carvalho Chehab 	if (status < 0)
45799a0bf528SMauro Carvalho Chehab 		goto error;
45809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
45819a0bf528SMauro Carvalho Chehab 	if (status < 0)
45829a0bf528SMauro Carvalho Chehab 		goto error;
45839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
45849a0bf528SMauro Carvalho Chehab 	if (status < 0)
45859a0bf528SMauro Carvalho Chehab 		goto error;
45869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
45879a0bf528SMauro Carvalho Chehab 	if (status < 0)
45889a0bf528SMauro Carvalho Chehab 		goto error;
45899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
45909a0bf528SMauro Carvalho Chehab 	if (status < 0)
45919a0bf528SMauro Carvalho Chehab 		goto error;
45929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
45939a0bf528SMauro Carvalho Chehab error:
45949a0bf528SMauro Carvalho Chehab 	if (status < 0)
45953a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
45969a0bf528SMauro Carvalho Chehab 	return status;
45979a0bf528SMauro Carvalho Chehab }
45989a0bf528SMauro Carvalho Chehab 
45999a0bf528SMauro Carvalho Chehab /*============================================================================*/
46009a0bf528SMauro Carvalho Chehab 
460134eb9751SMauro Carvalho Chehab /*
46029a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46039a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46049a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46059a0bf528SMauro Carvalho Chehab */
set_qam64(struct drxk_state * state)4606cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state)
46079a0bf528SMauro Carvalho Chehab {
46089a0bf528SMauro Carvalho Chehab 	int status = 0;
46099a0bf528SMauro Carvalho Chehab 
46109a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
46119a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
46129a0bf528SMauro Carvalho Chehab 	/* Equalizer */
46139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
46149a0bf528SMauro Carvalho Chehab 	if (status < 0)
46159a0bf528SMauro Carvalho Chehab 		goto error;
46169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
46179a0bf528SMauro Carvalho Chehab 	if (status < 0)
46189a0bf528SMauro Carvalho Chehab 		goto error;
46199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
46209a0bf528SMauro Carvalho Chehab 	if (status < 0)
46219a0bf528SMauro Carvalho Chehab 		goto error;
46229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
46239a0bf528SMauro Carvalho Chehab 	if (status < 0)
46249a0bf528SMauro Carvalho Chehab 		goto error;
46259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
46269a0bf528SMauro Carvalho Chehab 	if (status < 0)
46279a0bf528SMauro Carvalho Chehab 		goto error;
46289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
46299a0bf528SMauro Carvalho Chehab 	if (status < 0)
46309a0bf528SMauro Carvalho Chehab 		goto error;
46319a0bf528SMauro Carvalho Chehab 
46329a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
46339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
46349a0bf528SMauro Carvalho Chehab 	if (status < 0)
46359a0bf528SMauro Carvalho Chehab 		goto error;
46369a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
46379a0bf528SMauro Carvalho Chehab 	if (status < 0)
46389a0bf528SMauro Carvalho Chehab 		goto error;
46399a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
46409a0bf528SMauro Carvalho Chehab 	if (status < 0)
46419a0bf528SMauro Carvalho Chehab 		goto error;
46429a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
46439a0bf528SMauro Carvalho Chehab 	if (status < 0)
46449a0bf528SMauro Carvalho Chehab 		goto error;
46459a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
46469a0bf528SMauro Carvalho Chehab 	if (status < 0)
46479a0bf528SMauro Carvalho Chehab 		goto error;
46489a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
46499a0bf528SMauro Carvalho Chehab 	if (status < 0)
46509a0bf528SMauro Carvalho Chehab 		goto error;
46519a0bf528SMauro Carvalho Chehab 
46529a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
46539a0bf528SMauro Carvalho Chehab 	if (status < 0)
46549a0bf528SMauro Carvalho Chehab 		goto error;
46559a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
46569a0bf528SMauro Carvalho Chehab 	if (status < 0)
46579a0bf528SMauro Carvalho Chehab 		goto error;
46589a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
46599a0bf528SMauro Carvalho Chehab 	if (status < 0)
46609a0bf528SMauro Carvalho Chehab 		goto error;
46619a0bf528SMauro Carvalho Chehab 
46629a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4663ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4664ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM64);
46659a0bf528SMauro Carvalho Chehab 	if (status < 0)
46669a0bf528SMauro Carvalho Chehab 		goto error;
46679a0bf528SMauro Carvalho Chehab 
46689a0bf528SMauro Carvalho Chehab 
46699a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
46709a0bf528SMauro Carvalho Chehab 
46719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
46729a0bf528SMauro Carvalho Chehab 	if (status < 0)
46739a0bf528SMauro Carvalho Chehab 		goto error;
46749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
46759a0bf528SMauro Carvalho Chehab 	if (status < 0)
46769a0bf528SMauro Carvalho Chehab 		goto error;
46779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
46789a0bf528SMauro Carvalho Chehab 	if (status < 0)
46799a0bf528SMauro Carvalho Chehab 		goto error;
46809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
46819a0bf528SMauro Carvalho Chehab 	if (status < 0)
46829a0bf528SMauro Carvalho Chehab 		goto error;
46839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
46849a0bf528SMauro Carvalho Chehab 	if (status < 0)
46859a0bf528SMauro Carvalho Chehab 		goto error;
46869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
46879a0bf528SMauro Carvalho Chehab 	if (status < 0)
46889a0bf528SMauro Carvalho Chehab 		goto error;
46899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
46909a0bf528SMauro Carvalho Chehab 	if (status < 0)
46919a0bf528SMauro Carvalho Chehab 		goto error;
46929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
46939a0bf528SMauro Carvalho Chehab 	if (status < 0)
46949a0bf528SMauro Carvalho Chehab 		goto error;
46959a0bf528SMauro Carvalho Chehab 
46969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
46979a0bf528SMauro Carvalho Chehab 	if (status < 0)
46989a0bf528SMauro Carvalho Chehab 		goto error;
46999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47009a0bf528SMauro Carvalho Chehab 	if (status < 0)
47019a0bf528SMauro Carvalho Chehab 		goto error;
47029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47039a0bf528SMauro Carvalho Chehab 	if (status < 0)
47049a0bf528SMauro Carvalho Chehab 		goto error;
47059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47069a0bf528SMauro Carvalho Chehab 	if (status < 0)
47079a0bf528SMauro Carvalho Chehab 		goto error;
47089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47099a0bf528SMauro Carvalho Chehab 	if (status < 0)
47109a0bf528SMauro Carvalho Chehab 		goto error;
47119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
47129a0bf528SMauro Carvalho Chehab 	if (status < 0)
47139a0bf528SMauro Carvalho Chehab 		goto error;
47149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
47159a0bf528SMauro Carvalho Chehab 	if (status < 0)
47169a0bf528SMauro Carvalho Chehab 		goto error;
47179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
47189a0bf528SMauro Carvalho Chehab 	if (status < 0)
47199a0bf528SMauro Carvalho Chehab 		goto error;
47209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
47219a0bf528SMauro Carvalho Chehab 	if (status < 0)
47229a0bf528SMauro Carvalho Chehab 		goto error;
47239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
47249a0bf528SMauro Carvalho Chehab 	if (status < 0)
47259a0bf528SMauro Carvalho Chehab 		goto error;
47269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
47279a0bf528SMauro Carvalho Chehab 	if (status < 0)
47289a0bf528SMauro Carvalho Chehab 		goto error;
47299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
47309a0bf528SMauro Carvalho Chehab 	if (status < 0)
47319a0bf528SMauro Carvalho Chehab 		goto error;
47329a0bf528SMauro Carvalho Chehab 
47339a0bf528SMauro Carvalho Chehab 
47349a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
47359a0bf528SMauro Carvalho Chehab 
47369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
47379a0bf528SMauro Carvalho Chehab 	if (status < 0)
47389a0bf528SMauro Carvalho Chehab 		goto error;
47399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
47409a0bf528SMauro Carvalho Chehab 	if (status < 0)
47419a0bf528SMauro Carvalho Chehab 		goto error;
47429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
47439a0bf528SMauro Carvalho Chehab 	if (status < 0)
47449a0bf528SMauro Carvalho Chehab 		goto error;
47459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
47469a0bf528SMauro Carvalho Chehab 	if (status < 0)
47479a0bf528SMauro Carvalho Chehab 		goto error;
47489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
47499a0bf528SMauro Carvalho Chehab 	if (status < 0)
47509a0bf528SMauro Carvalho Chehab 		goto error;
47519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
47529a0bf528SMauro Carvalho Chehab 	if (status < 0)
47539a0bf528SMauro Carvalho Chehab 		goto error;
47549a0bf528SMauro Carvalho Chehab 
47559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
47569a0bf528SMauro Carvalho Chehab 	if (status < 0)
47579a0bf528SMauro Carvalho Chehab 		goto error;
47589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
47599a0bf528SMauro Carvalho Chehab 	if (status < 0)
47609a0bf528SMauro Carvalho Chehab 		goto error;
47619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
47629a0bf528SMauro Carvalho Chehab 	if (status < 0)
47639a0bf528SMauro Carvalho Chehab 		goto error;
47649a0bf528SMauro Carvalho Chehab 
47659a0bf528SMauro Carvalho Chehab 
47669a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
47679a0bf528SMauro Carvalho Chehab 
47689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
47699a0bf528SMauro Carvalho Chehab 	if (status < 0)
47709a0bf528SMauro Carvalho Chehab 		goto error;
47719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
47729a0bf528SMauro Carvalho Chehab 	if (status < 0)
47739a0bf528SMauro Carvalho Chehab 		goto error;
47749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
47759a0bf528SMauro Carvalho Chehab 	if (status < 0)
47769a0bf528SMauro Carvalho Chehab 		goto error;
47779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
47789a0bf528SMauro Carvalho Chehab 	if (status < 0)
47799a0bf528SMauro Carvalho Chehab 		goto error;
47809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
47819a0bf528SMauro Carvalho Chehab 	if (status < 0)
47829a0bf528SMauro Carvalho Chehab 		goto error;
47839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
47849a0bf528SMauro Carvalho Chehab 	if (status < 0)
47859a0bf528SMauro Carvalho Chehab 		goto error;
47869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
47879a0bf528SMauro Carvalho Chehab error:
47889a0bf528SMauro Carvalho Chehab 	if (status < 0)
47893a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
47909a0bf528SMauro Carvalho Chehab 
47919a0bf528SMauro Carvalho Chehab 	return status;
47929a0bf528SMauro Carvalho Chehab }
47939a0bf528SMauro Carvalho Chehab 
47949a0bf528SMauro Carvalho Chehab /*============================================================================*/
47959a0bf528SMauro Carvalho Chehab 
479634eb9751SMauro Carvalho Chehab /*
47979a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
47989a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
47999a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48009a0bf528SMauro Carvalho Chehab */
set_qam128(struct drxk_state * state)4801cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state)
48029a0bf528SMauro Carvalho Chehab {
48039a0bf528SMauro Carvalho Chehab 	int status = 0;
48049a0bf528SMauro Carvalho Chehab 
48059a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
48069a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
48079a0bf528SMauro Carvalho Chehab 	/* Equalizer */
48089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48099a0bf528SMauro Carvalho Chehab 	if (status < 0)
48109a0bf528SMauro Carvalho Chehab 		goto error;
48119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
48129a0bf528SMauro Carvalho Chehab 	if (status < 0)
48139a0bf528SMauro Carvalho Chehab 		goto error;
48149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
48159a0bf528SMauro Carvalho Chehab 	if (status < 0)
48169a0bf528SMauro Carvalho Chehab 		goto error;
48179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
48189a0bf528SMauro Carvalho Chehab 	if (status < 0)
48199a0bf528SMauro Carvalho Chehab 		goto error;
48209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
48219a0bf528SMauro Carvalho Chehab 	if (status < 0)
48229a0bf528SMauro Carvalho Chehab 		goto error;
48239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
48249a0bf528SMauro Carvalho Chehab 	if (status < 0)
48259a0bf528SMauro Carvalho Chehab 		goto error;
48269a0bf528SMauro Carvalho Chehab 
48279a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
48289a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
48299a0bf528SMauro Carvalho Chehab 	if (status < 0)
48309a0bf528SMauro Carvalho Chehab 		goto error;
48319a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
48329a0bf528SMauro Carvalho Chehab 	if (status < 0)
48339a0bf528SMauro Carvalho Chehab 		goto error;
48349a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
48359a0bf528SMauro Carvalho Chehab 	if (status < 0)
48369a0bf528SMauro Carvalho Chehab 		goto error;
48379a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
48389a0bf528SMauro Carvalho Chehab 	if (status < 0)
48399a0bf528SMauro Carvalho Chehab 		goto error;
48409a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
48419a0bf528SMauro Carvalho Chehab 	if (status < 0)
48429a0bf528SMauro Carvalho Chehab 		goto error;
48439a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
48449a0bf528SMauro Carvalho Chehab 	if (status < 0)
48459a0bf528SMauro Carvalho Chehab 		goto error;
48469a0bf528SMauro Carvalho Chehab 
48479a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
48489a0bf528SMauro Carvalho Chehab 	if (status < 0)
48499a0bf528SMauro Carvalho Chehab 		goto error;
48509a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
48519a0bf528SMauro Carvalho Chehab 	if (status < 0)
48529a0bf528SMauro Carvalho Chehab 		goto error;
48539a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
48549a0bf528SMauro Carvalho Chehab 	if (status < 0)
48559a0bf528SMauro Carvalho Chehab 		goto error;
48569a0bf528SMauro Carvalho Chehab 
48579a0bf528SMauro Carvalho Chehab 
48589a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
48599a0bf528SMauro Carvalho Chehab 
4860ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4861ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM128);
48629a0bf528SMauro Carvalho Chehab 	if (status < 0)
48639a0bf528SMauro Carvalho Chehab 		goto error;
48649a0bf528SMauro Carvalho Chehab 
48659a0bf528SMauro Carvalho Chehab 
48669a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
48679a0bf528SMauro Carvalho Chehab 
48689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
48699a0bf528SMauro Carvalho Chehab 	if (status < 0)
48709a0bf528SMauro Carvalho Chehab 		goto error;
48719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
48729a0bf528SMauro Carvalho Chehab 	if (status < 0)
48739a0bf528SMauro Carvalho Chehab 		goto error;
48749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
48759a0bf528SMauro Carvalho Chehab 	if (status < 0)
48769a0bf528SMauro Carvalho Chehab 		goto error;
48779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
48789a0bf528SMauro Carvalho Chehab 	if (status < 0)
48799a0bf528SMauro Carvalho Chehab 		goto error;
48809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
48819a0bf528SMauro Carvalho Chehab 	if (status < 0)
48829a0bf528SMauro Carvalho Chehab 		goto error;
48839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
48849a0bf528SMauro Carvalho Chehab 	if (status < 0)
48859a0bf528SMauro Carvalho Chehab 		goto error;
48869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
48879a0bf528SMauro Carvalho Chehab 	if (status < 0)
48889a0bf528SMauro Carvalho Chehab 		goto error;
48899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
48909a0bf528SMauro Carvalho Chehab 	if (status < 0)
48919a0bf528SMauro Carvalho Chehab 		goto error;
48929a0bf528SMauro Carvalho Chehab 
48939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
48949a0bf528SMauro Carvalho Chehab 	if (status < 0)
48959a0bf528SMauro Carvalho Chehab 		goto error;
48969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
48979a0bf528SMauro Carvalho Chehab 	if (status < 0)
48989a0bf528SMauro Carvalho Chehab 		goto error;
48999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49009a0bf528SMauro Carvalho Chehab 	if (status < 0)
49019a0bf528SMauro Carvalho Chehab 		goto error;
49029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49039a0bf528SMauro Carvalho Chehab 	if (status < 0)
49049a0bf528SMauro Carvalho Chehab 		goto error;
49059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49069a0bf528SMauro Carvalho Chehab 	if (status < 0)
49079a0bf528SMauro Carvalho Chehab 		goto error;
49089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49099a0bf528SMauro Carvalho Chehab 	if (status < 0)
49109a0bf528SMauro Carvalho Chehab 		goto error;
49119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
49129a0bf528SMauro Carvalho Chehab 	if (status < 0)
49139a0bf528SMauro Carvalho Chehab 		goto error;
49149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
49159a0bf528SMauro Carvalho Chehab 	if (status < 0)
49169a0bf528SMauro Carvalho Chehab 		goto error;
49179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
49189a0bf528SMauro Carvalho Chehab 	if (status < 0)
49199a0bf528SMauro Carvalho Chehab 		goto error;
49209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
49219a0bf528SMauro Carvalho Chehab 	if (status < 0)
49229a0bf528SMauro Carvalho Chehab 		goto error;
49239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
49249a0bf528SMauro Carvalho Chehab 	if (status < 0)
49259a0bf528SMauro Carvalho Chehab 		goto error;
49269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
49279a0bf528SMauro Carvalho Chehab 	if (status < 0)
49289a0bf528SMauro Carvalho Chehab 		goto error;
49299a0bf528SMauro Carvalho Chehab 
49309a0bf528SMauro Carvalho Chehab 
49319a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
49329a0bf528SMauro Carvalho Chehab 
49339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
49349a0bf528SMauro Carvalho Chehab 	if (status < 0)
49359a0bf528SMauro Carvalho Chehab 		goto error;
49369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
49379a0bf528SMauro Carvalho Chehab 	if (status < 0)
49389a0bf528SMauro Carvalho Chehab 		goto error;
49399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
49409a0bf528SMauro Carvalho Chehab 	if (status < 0)
49419a0bf528SMauro Carvalho Chehab 		goto error;
49429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
49439a0bf528SMauro Carvalho Chehab 	if (status < 0)
49449a0bf528SMauro Carvalho Chehab 		goto error;
49459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
49469a0bf528SMauro Carvalho Chehab 	if (status < 0)
49479a0bf528SMauro Carvalho Chehab 		goto error;
49489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
49499a0bf528SMauro Carvalho Chehab 	if (status < 0)
49509a0bf528SMauro Carvalho Chehab 		goto error;
49519a0bf528SMauro Carvalho Chehab 
49529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
49539a0bf528SMauro Carvalho Chehab 	if (status < 0)
49549a0bf528SMauro Carvalho Chehab 		goto error;
49559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
49569a0bf528SMauro Carvalho Chehab 	if (status < 0)
49579a0bf528SMauro Carvalho Chehab 		goto error;
49589a0bf528SMauro Carvalho Chehab 
49599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
49609a0bf528SMauro Carvalho Chehab 	if (status < 0)
49619a0bf528SMauro Carvalho Chehab 		goto error;
49629a0bf528SMauro Carvalho Chehab 
49639a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
49649a0bf528SMauro Carvalho Chehab 
49659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
49669a0bf528SMauro Carvalho Chehab 	if (status < 0)
49679a0bf528SMauro Carvalho Chehab 		goto error;
49689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
49699a0bf528SMauro Carvalho Chehab 	if (status < 0)
49709a0bf528SMauro Carvalho Chehab 		goto error;
49719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
49729a0bf528SMauro Carvalho Chehab 	if (status < 0)
49739a0bf528SMauro Carvalho Chehab 		goto error;
49749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
49759a0bf528SMauro Carvalho Chehab 	if (status < 0)
49769a0bf528SMauro Carvalho Chehab 		goto error;
49779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
49789a0bf528SMauro Carvalho Chehab 	if (status < 0)
49799a0bf528SMauro Carvalho Chehab 		goto error;
49809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
49819a0bf528SMauro Carvalho Chehab 	if (status < 0)
49829a0bf528SMauro Carvalho Chehab 		goto error;
49839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
49849a0bf528SMauro Carvalho Chehab error:
49859a0bf528SMauro Carvalho Chehab 	if (status < 0)
49863a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
49879a0bf528SMauro Carvalho Chehab 
49889a0bf528SMauro Carvalho Chehab 	return status;
49899a0bf528SMauro Carvalho Chehab }
49909a0bf528SMauro Carvalho Chehab 
49919a0bf528SMauro Carvalho Chehab /*============================================================================*/
49929a0bf528SMauro Carvalho Chehab 
499334eb9751SMauro Carvalho Chehab /*
49949a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
49959a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
49969a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
49979a0bf528SMauro Carvalho Chehab */
set_qam256(struct drxk_state * state)4998cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state)
49999a0bf528SMauro Carvalho Chehab {
50009a0bf528SMauro Carvalho Chehab 	int status = 0;
50019a0bf528SMauro Carvalho Chehab 
50029a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
50039a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
50049a0bf528SMauro Carvalho Chehab 	/* Equalizer */
50059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50069a0bf528SMauro Carvalho Chehab 	if (status < 0)
50079a0bf528SMauro Carvalho Chehab 		goto error;
50089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50099a0bf528SMauro Carvalho Chehab 	if (status < 0)
50109a0bf528SMauro Carvalho Chehab 		goto error;
50119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
50129a0bf528SMauro Carvalho Chehab 	if (status < 0)
50139a0bf528SMauro Carvalho Chehab 		goto error;
50149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
50159a0bf528SMauro Carvalho Chehab 	if (status < 0)
50169a0bf528SMauro Carvalho Chehab 		goto error;
50179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
50189a0bf528SMauro Carvalho Chehab 	if (status < 0)
50199a0bf528SMauro Carvalho Chehab 		goto error;
50209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
50219a0bf528SMauro Carvalho Chehab 	if (status < 0)
50229a0bf528SMauro Carvalho Chehab 		goto error;
50239a0bf528SMauro Carvalho Chehab 
50249a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
50259a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
50269a0bf528SMauro Carvalho Chehab 	if (status < 0)
50279a0bf528SMauro Carvalho Chehab 		goto error;
50289a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
50299a0bf528SMauro Carvalho Chehab 	if (status < 0)
50309a0bf528SMauro Carvalho Chehab 		goto error;
50319a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
50329a0bf528SMauro Carvalho Chehab 	if (status < 0)
50339a0bf528SMauro Carvalho Chehab 		goto error;
50349a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
50359a0bf528SMauro Carvalho Chehab 	if (status < 0)
50369a0bf528SMauro Carvalho Chehab 		goto error;
50379a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
50389a0bf528SMauro Carvalho Chehab 	if (status < 0)
50399a0bf528SMauro Carvalho Chehab 		goto error;
50409a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
50419a0bf528SMauro Carvalho Chehab 	if (status < 0)
50429a0bf528SMauro Carvalho Chehab 		goto error;
50439a0bf528SMauro Carvalho Chehab 
50449a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
50459a0bf528SMauro Carvalho Chehab 	if (status < 0)
50469a0bf528SMauro Carvalho Chehab 		goto error;
50479a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
50489a0bf528SMauro Carvalho Chehab 	if (status < 0)
50499a0bf528SMauro Carvalho Chehab 		goto error;
50509a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
50519a0bf528SMauro Carvalho Chehab 	if (status < 0)
50529a0bf528SMauro Carvalho Chehab 		goto error;
50539a0bf528SMauro Carvalho Chehab 
50549a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
50559a0bf528SMauro Carvalho Chehab 
5056ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5057ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM256);
50589a0bf528SMauro Carvalho Chehab 	if (status < 0)
50599a0bf528SMauro Carvalho Chehab 		goto error;
50609a0bf528SMauro Carvalho Chehab 
50619a0bf528SMauro Carvalho Chehab 
50629a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
50639a0bf528SMauro Carvalho Chehab 
50649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
50659a0bf528SMauro Carvalho Chehab 	if (status < 0)
50669a0bf528SMauro Carvalho Chehab 		goto error;
50679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
50689a0bf528SMauro Carvalho Chehab 	if (status < 0)
50699a0bf528SMauro Carvalho Chehab 		goto error;
50709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
50719a0bf528SMauro Carvalho Chehab 	if (status < 0)
50729a0bf528SMauro Carvalho Chehab 		goto error;
50739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
50749a0bf528SMauro Carvalho Chehab 	if (status < 0)
50759a0bf528SMauro Carvalho Chehab 		goto error;
50769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
50779a0bf528SMauro Carvalho Chehab 	if (status < 0)
50789a0bf528SMauro Carvalho Chehab 		goto error;
50799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
50809a0bf528SMauro Carvalho Chehab 	if (status < 0)
50819a0bf528SMauro Carvalho Chehab 		goto error;
50829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
50839a0bf528SMauro Carvalho Chehab 	if (status < 0)
50849a0bf528SMauro Carvalho Chehab 		goto error;
50859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
50869a0bf528SMauro Carvalho Chehab 	if (status < 0)
50879a0bf528SMauro Carvalho Chehab 		goto error;
50889a0bf528SMauro Carvalho Chehab 
50899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
50909a0bf528SMauro Carvalho Chehab 	if (status < 0)
50919a0bf528SMauro Carvalho Chehab 		goto error;
50929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
50939a0bf528SMauro Carvalho Chehab 	if (status < 0)
50949a0bf528SMauro Carvalho Chehab 		goto error;
50959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
50969a0bf528SMauro Carvalho Chehab 	if (status < 0)
50979a0bf528SMauro Carvalho Chehab 		goto error;
50989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
50999a0bf528SMauro Carvalho Chehab 	if (status < 0)
51009a0bf528SMauro Carvalho Chehab 		goto error;
51019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51029a0bf528SMauro Carvalho Chehab 	if (status < 0)
51039a0bf528SMauro Carvalho Chehab 		goto error;
51049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51059a0bf528SMauro Carvalho Chehab 	if (status < 0)
51069a0bf528SMauro Carvalho Chehab 		goto error;
51079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51089a0bf528SMauro Carvalho Chehab 	if (status < 0)
51099a0bf528SMauro Carvalho Chehab 		goto error;
51109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51119a0bf528SMauro Carvalho Chehab 	if (status < 0)
51129a0bf528SMauro Carvalho Chehab 		goto error;
51139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
51149a0bf528SMauro Carvalho Chehab 	if (status < 0)
51159a0bf528SMauro Carvalho Chehab 		goto error;
51169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
51179a0bf528SMauro Carvalho Chehab 	if (status < 0)
51189a0bf528SMauro Carvalho Chehab 		goto error;
51199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
51209a0bf528SMauro Carvalho Chehab 	if (status < 0)
51219a0bf528SMauro Carvalho Chehab 		goto error;
51229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
51239a0bf528SMauro Carvalho Chehab 	if (status < 0)
51249a0bf528SMauro Carvalho Chehab 		goto error;
51259a0bf528SMauro Carvalho Chehab 
51269a0bf528SMauro Carvalho Chehab 
51279a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
51289a0bf528SMauro Carvalho Chehab 
51299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
51309a0bf528SMauro Carvalho Chehab 	if (status < 0)
51319a0bf528SMauro Carvalho Chehab 		goto error;
51329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
51339a0bf528SMauro Carvalho Chehab 	if (status < 0)
51349a0bf528SMauro Carvalho Chehab 		goto error;
51359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
51369a0bf528SMauro Carvalho Chehab 	if (status < 0)
51379a0bf528SMauro Carvalho Chehab 		goto error;
51389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
51399a0bf528SMauro Carvalho Chehab 	if (status < 0)
51409a0bf528SMauro Carvalho Chehab 		goto error;
51419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
51429a0bf528SMauro Carvalho Chehab 	if (status < 0)
51439a0bf528SMauro Carvalho Chehab 		goto error;
51449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
51459a0bf528SMauro Carvalho Chehab 	if (status < 0)
51469a0bf528SMauro Carvalho Chehab 		goto error;
51479a0bf528SMauro Carvalho Chehab 
51489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
51499a0bf528SMauro Carvalho Chehab 	if (status < 0)
51509a0bf528SMauro Carvalho Chehab 		goto error;
51519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
51529a0bf528SMauro Carvalho Chehab 	if (status < 0)
51539a0bf528SMauro Carvalho Chehab 		goto error;
51549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
51559a0bf528SMauro Carvalho Chehab 	if (status < 0)
51569a0bf528SMauro Carvalho Chehab 		goto error;
51579a0bf528SMauro Carvalho Chehab 
51589a0bf528SMauro Carvalho Chehab 
51599a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
51609a0bf528SMauro Carvalho Chehab 
51619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
51629a0bf528SMauro Carvalho Chehab 	if (status < 0)
51639a0bf528SMauro Carvalho Chehab 		goto error;
51649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
51659a0bf528SMauro Carvalho Chehab 	if (status < 0)
51669a0bf528SMauro Carvalho Chehab 		goto error;
51679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
51689a0bf528SMauro Carvalho Chehab 	if (status < 0)
51699a0bf528SMauro Carvalho Chehab 		goto error;
51709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
51719a0bf528SMauro Carvalho Chehab 	if (status < 0)
51729a0bf528SMauro Carvalho Chehab 		goto error;
51739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
51749a0bf528SMauro Carvalho Chehab 	if (status < 0)
51759a0bf528SMauro Carvalho Chehab 		goto error;
51769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
51779a0bf528SMauro Carvalho Chehab 	if (status < 0)
51789a0bf528SMauro Carvalho Chehab 		goto error;
51799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
51809a0bf528SMauro Carvalho Chehab error:
51819a0bf528SMauro Carvalho Chehab 	if (status < 0)
51823a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
51839a0bf528SMauro Carvalho Chehab 	return status;
51849a0bf528SMauro Carvalho Chehab }
51859a0bf528SMauro Carvalho Chehab 
51869a0bf528SMauro Carvalho Chehab 
51879a0bf528SMauro Carvalho Chehab /*============================================================================*/
518834eb9751SMauro Carvalho Chehab /*
51899a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
51909a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
51919a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
51929a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
51939a0bf528SMauro Carvalho Chehab */
qam_reset_qam(struct drxk_state * state)5194cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state)
51959a0bf528SMauro Carvalho Chehab {
51969a0bf528SMauro Carvalho Chehab 	int status;
5197cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
51989a0bf528SMauro Carvalho Chehab 
51999a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52009a0bf528SMauro Carvalho Chehab 	/* Stop QAM comstate->m_exec */
52019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52029a0bf528SMauro Carvalho Chehab 	if (status < 0)
52039a0bf528SMauro Carvalho Chehab 		goto error;
52049a0bf528SMauro Carvalho Chehab 
5205ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5206ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5207ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
52089a0bf528SMauro Carvalho Chehab error:
52099a0bf528SMauro Carvalho Chehab 	if (status < 0)
52103a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52119a0bf528SMauro Carvalho Chehab 	return status;
52129a0bf528SMauro Carvalho Chehab }
52139a0bf528SMauro Carvalho Chehab 
52149a0bf528SMauro Carvalho Chehab /*============================================================================*/
52159a0bf528SMauro Carvalho Chehab 
521634eb9751SMauro Carvalho Chehab /*
52179a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
52189a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52199a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52209a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52219a0bf528SMauro Carvalho Chehab */
qam_set_symbolrate(struct drxk_state * state)5222cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state)
52239a0bf528SMauro Carvalho Chehab {
5224cd7a67a4SMauro Carvalho Chehab 	u32 adc_frequency = 0;
5225cd7a67a4SMauro Carvalho Chehab 	u32 symb_freq = 0;
5226cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate = 0;
52279a0bf528SMauro Carvalho Chehab 	u16 ratesel = 0;
5228cd7a67a4SMauro Carvalho Chehab 	u32 lc_symb_rate = 0;
52299a0bf528SMauro Carvalho Chehab 	int status;
52309a0bf528SMauro Carvalho Chehab 
52319a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52329a0bf528SMauro Carvalho Chehab 	/* Select & calculate correct IQM rate */
5233cd7a67a4SMauro Carvalho Chehab 	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
52349a0bf528SMauro Carvalho Chehab 	ratesel = 0;
52359a0bf528SMauro Carvalho Chehab 	if (state->props.symbol_rate <= 1188750)
52369a0bf528SMauro Carvalho Chehab 		ratesel = 3;
52379a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 2377500)
52389a0bf528SMauro Carvalho Chehab 		ratesel = 2;
52399a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 4755000)
52409a0bf528SMauro Carvalho Chehab 		ratesel = 1;
52419a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FD_RATESEL__A, ratesel);
52429a0bf528SMauro Carvalho Chehab 	if (status < 0)
52439a0bf528SMauro Carvalho Chehab 		goto error;
52449a0bf528SMauro Carvalho Chehab 
52459a0bf528SMauro Carvalho Chehab 	/*
52469a0bf528SMauro Carvalho Chehab 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
52479a0bf528SMauro Carvalho Chehab 		*/
5248cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate * (1 << ratesel);
5249cd7a67a4SMauro Carvalho Chehab 	if (symb_freq == 0) {
52509a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
52519a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
52529a0bf528SMauro Carvalho Chehab 		goto error;
52539a0bf528SMauro Carvalho Chehab 	}
5254cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5255cd7a67a4SMauro Carvalho Chehab 		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
52569a0bf528SMauro Carvalho Chehab 		(1 << 23);
5257cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
52589a0bf528SMauro Carvalho Chehab 	if (status < 0)
52599a0bf528SMauro Carvalho Chehab 		goto error;
5260cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_rc_rate = iqm_rc_rate;
52619a0bf528SMauro Carvalho Chehab 	/*
5262cd7a67a4SMauro Carvalho Chehab 		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
52639a0bf528SMauro Carvalho Chehab 		*/
5264cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate;
5265cd7a67a4SMauro Carvalho Chehab 	if (adc_frequency == 0) {
52669a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
52679a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
52689a0bf528SMauro Carvalho Chehab 		goto error;
52699a0bf528SMauro Carvalho Chehab 	}
5270cd7a67a4SMauro Carvalho Chehab 	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5271cd7a67a4SMauro Carvalho Chehab 		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
52729a0bf528SMauro Carvalho Chehab 		16);
5273cd7a67a4SMauro Carvalho Chehab 	if (lc_symb_rate > 511)
5274cd7a67a4SMauro Carvalho Chehab 		lc_symb_rate = 511;
5275cd7a67a4SMauro Carvalho Chehab 	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
52769a0bf528SMauro Carvalho Chehab 
52779a0bf528SMauro Carvalho Chehab error:
52789a0bf528SMauro Carvalho Chehab 	if (status < 0)
52793a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52809a0bf528SMauro Carvalho Chehab 	return status;
52819a0bf528SMauro Carvalho Chehab }
52829a0bf528SMauro Carvalho Chehab 
52839a0bf528SMauro Carvalho Chehab /*============================================================================*/
52849a0bf528SMauro Carvalho Chehab 
528534eb9751SMauro Carvalho Chehab /*
52869a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
52879a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52889a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52899a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52909a0bf528SMauro Carvalho Chehab */
52919a0bf528SMauro Carvalho Chehab 
get_qam_lock_status(struct drxk_state * state,u32 * p_lock_status)5292cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
52939a0bf528SMauro Carvalho Chehab {
52949a0bf528SMauro Carvalho Chehab 	int status;
5295cd7a67a4SMauro Carvalho Chehab 	u16 result[2] = { 0, 0 };
52969a0bf528SMauro Carvalho Chehab 
52979a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5298cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
52999a0bf528SMauro Carvalho Chehab 	status = scu_command(state,
53009a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_STANDARD_QAM |
53019a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5302cd7a67a4SMauro Carvalho Chehab 			result);
53039a0bf528SMauro Carvalho Chehab 	if (status < 0)
53043a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53059a0bf528SMauro Carvalho Chehab 
5306cd7a67a4SMauro Carvalho Chehab 	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53079a0bf528SMauro Carvalho Chehab 		/* 0x0000 NOT LOCKED */
5308cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53099a0bf528SMauro Carvalho Chehab 		/* 0x4000 DEMOD LOCKED */
5310cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
5311cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53129a0bf528SMauro Carvalho Chehab 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
5313cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
53149a0bf528SMauro Carvalho Chehab 	} else {
53159a0bf528SMauro Carvalho Chehab 		/* 0xC000 NEVER LOCKED */
53169a0bf528SMauro Carvalho Chehab 		/* (system will never be able to lock to the signal) */
5317ab5060cdSMauro Carvalho Chehab 		/*
5318ab5060cdSMauro Carvalho Chehab 		 * TODO: check this, intermediate & standard specific lock
5319ab5060cdSMauro Carvalho Chehab 		 * states are not taken into account here
5320ab5060cdSMauro Carvalho Chehab 		 */
5321cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
53229a0bf528SMauro Carvalho Chehab 	}
53239a0bf528SMauro Carvalho Chehab 	return status;
53249a0bf528SMauro Carvalho Chehab }
53259a0bf528SMauro Carvalho Chehab 
53269a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M         0x03
53279a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL     0x00
53289a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED          0x01
53299a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON    0x02
53309a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M      0x10
53319a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL  0x10
53329a0bf528SMauro Carvalho Chehab 
qam_demodulator_command(struct drxk_state * state,int number_of_parameters)5333cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state,
5334cd7a67a4SMauro Carvalho Chehab 				 int number_of_parameters)
53359a0bf528SMauro Carvalho Chehab {
53369a0bf528SMauro Carvalho Chehab 	int status;
5337cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5338cd7a67a4SMauro Carvalho Chehab 	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
53399a0bf528SMauro Carvalho Chehab 
5340cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[0] = state->m_constellation;	/* modulation     */
5341cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
53429a0bf528SMauro Carvalho Chehab 
5343cd7a67a4SMauro Carvalho Chehab 	if (number_of_parameters == 2) {
5344cd7a67a4SMauro Carvalho Chehab 		u16 set_env_parameters[1] = { 0 };
53459a0bf528SMauro Carvalho Chehab 
5346cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5347cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_C;
53489a0bf528SMauro Carvalho Chehab 		else
5349cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_A;
53509a0bf528SMauro Carvalho Chehab 
53519a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5352ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5353ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5354cd7a67a4SMauro Carvalho Chehab 				     1, set_env_parameters, 1, &cmd_result);
53559a0bf528SMauro Carvalho Chehab 		if (status < 0)
53569a0bf528SMauro Carvalho Chehab 			goto error;
53579a0bf528SMauro Carvalho Chehab 
53589a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5359ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5360ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5361cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5362cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
5363cd7a67a4SMauro Carvalho Chehab 	} else if (number_of_parameters == 4) {
5364cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5365cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_C;
53669a0bf528SMauro Carvalho Chehab 		else
5367cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_A;
53689a0bf528SMauro Carvalho Chehab 
5369cd7a67a4SMauro Carvalho Chehab 		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
53709a0bf528SMauro Carvalho Chehab 		/* Env parameters */
5371868c9a17SMauro Carvalho Chehab 		/* check for LOCKRANGE Extended */
5372cd7a67a4SMauro Carvalho Chehab 		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
53739a0bf528SMauro Carvalho Chehab 
53749a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5375ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5376ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5377cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5378cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
53799a0bf528SMauro Carvalho Chehab 	} else {
53803a4398f5SMauro Carvalho Chehab 		pr_warn("Unknown QAM demodulator parameter count %d\n",
53813a4398f5SMauro Carvalho Chehab 			number_of_parameters);
538294af1b63SMauro Carvalho Chehab 		status = -EINVAL;
53839a0bf528SMauro Carvalho Chehab 	}
53849a0bf528SMauro Carvalho Chehab 
53859a0bf528SMauro Carvalho Chehab error:
53869a0bf528SMauro Carvalho Chehab 	if (status < 0)
53873a4398f5SMauro Carvalho Chehab 		pr_warn("Warning %d on %s\n", status, __func__);
53889a0bf528SMauro Carvalho Chehab 	return status;
53899a0bf528SMauro Carvalho Chehab }
53909a0bf528SMauro Carvalho Chehab 
set_qam(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset)5391cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5392cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset)
53939a0bf528SMauro Carvalho Chehab {
53949a0bf528SMauro Carvalho Chehab 	int status;
5395cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5396cd7a67a4SMauro Carvalho Chehab 	int qam_demod_param_count = state->qam_demod_parameter_count;
53979a0bf528SMauro Carvalho Chehab 
53989a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
53999a0bf528SMauro Carvalho Chehab 	/*
54009a0bf528SMauro Carvalho Chehab 	 * STEP 1: reset demodulator
54019a0bf528SMauro Carvalho Chehab 	 *	resets FEC DI and FEC RS
54029a0bf528SMauro Carvalho Chehab 	 *	resets QAM block
54039a0bf528SMauro Carvalho Chehab 	 *	resets SCU variables
54049a0bf528SMauro Carvalho Chehab 	 */
54059a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54069a0bf528SMauro Carvalho Chehab 	if (status < 0)
54079a0bf528SMauro Carvalho Chehab 		goto error;
54089a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54099a0bf528SMauro Carvalho Chehab 	if (status < 0)
54109a0bf528SMauro Carvalho Chehab 		goto error;
5411cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
54129a0bf528SMauro Carvalho Chehab 	if (status < 0)
54139a0bf528SMauro Carvalho Chehab 		goto error;
54149a0bf528SMauro Carvalho Chehab 
54159a0bf528SMauro Carvalho Chehab 	/*
54169a0bf528SMauro Carvalho Chehab 	 * STEP 2: configure demodulator
54179a0bf528SMauro Carvalho Chehab 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
54189a0bf528SMauro Carvalho Chehab 	 *       SCU variables
54199a0bf528SMauro Carvalho Chehab 	 */
5420cd7a67a4SMauro Carvalho Chehab 	status = qam_set_symbolrate(state);
54219a0bf528SMauro Carvalho Chehab 	if (status < 0)
54229a0bf528SMauro Carvalho Chehab 		goto error;
54239a0bf528SMauro Carvalho Chehab 
54249a0bf528SMauro Carvalho Chehab 	/* Set params */
54259a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
54269a0bf528SMauro Carvalho Chehab 	case QAM_256:
5427cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM256;
54289a0bf528SMauro Carvalho Chehab 		break;
54299a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
54309a0bf528SMauro Carvalho Chehab 	case QAM_64:
5431cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM64;
54329a0bf528SMauro Carvalho Chehab 		break;
54339a0bf528SMauro Carvalho Chehab 	case QAM_16:
5434cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM16;
54359a0bf528SMauro Carvalho Chehab 		break;
54369a0bf528SMauro Carvalho Chehab 	case QAM_32:
5437cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM32;
54389a0bf528SMauro Carvalho Chehab 		break;
54399a0bf528SMauro Carvalho Chehab 	case QAM_128:
5440cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM128;
54419a0bf528SMauro Carvalho Chehab 		break;
54429a0bf528SMauro Carvalho Chehab 	default:
54439a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
54449a0bf528SMauro Carvalho Chehab 		break;
54459a0bf528SMauro Carvalho Chehab 	}
54469a0bf528SMauro Carvalho Chehab 	if (status < 0)
54479a0bf528SMauro Carvalho Chehab 		goto error;
54489a0bf528SMauro Carvalho Chehab 
54499a0bf528SMauro Carvalho Chehab 	/* Use the 4-parameter if it's requested or we're probing for
54509a0bf528SMauro Carvalho Chehab 	 * the correct command. */
54519a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 4
54529a0bf528SMauro Carvalho Chehab 		|| !state->qam_demod_parameter_count) {
5453cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 4;
5454cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
54559a0bf528SMauro Carvalho Chehab 	}
54569a0bf528SMauro Carvalho Chehab 
54579a0bf528SMauro Carvalho Chehab 	/* Use the 2-parameter command if it was requested or if we're
54589a0bf528SMauro Carvalho Chehab 	 * probing for the correct command and the 4-parameter command
54599a0bf528SMauro Carvalho Chehab 	 * failed. */
54609a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 2
54619a0bf528SMauro Carvalho Chehab 		|| (!state->qam_demod_parameter_count && status < 0)) {
5462cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 2;
5463cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
54649a0bf528SMauro Carvalho Chehab 	}
54659a0bf528SMauro Carvalho Chehab 
54669a0bf528SMauro Carvalho Chehab 	if (status < 0) {
54670fb220f2SMauro Carvalho Chehab 		dprintk(1, "Could not set demodulator parameters.\n");
54680fb220f2SMauro Carvalho Chehab 		dprintk(1,
54690fb220f2SMauro Carvalho Chehab 			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
54709a0bf528SMauro Carvalho Chehab 			state->qam_demod_parameter_count,
54719a0bf528SMauro Carvalho Chehab 			state->microcode_name);
54729a0bf528SMauro Carvalho Chehab 		goto error;
54739a0bf528SMauro Carvalho Chehab 	} else if (!state->qam_demod_parameter_count) {
54740fb220f2SMauro Carvalho Chehab 		dprintk(1,
54750fb220f2SMauro Carvalho Chehab 			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
5476cd7a67a4SMauro Carvalho Chehab 			qam_demod_param_count);
54779a0bf528SMauro Carvalho Chehab 
54789a0bf528SMauro Carvalho Chehab 		/*
54799a0bf528SMauro Carvalho Chehab 		 * One of our commands was successful. We don't need to
54809a0bf528SMauro Carvalho Chehab 		 * auto-probe anymore, now that we got the correct command.
54819a0bf528SMauro Carvalho Chehab 		 */
5482cd7a67a4SMauro Carvalho Chehab 		state->qam_demod_parameter_count = qam_demod_param_count;
54839a0bf528SMauro Carvalho Chehab 	}
54849a0bf528SMauro Carvalho Chehab 
54859a0bf528SMauro Carvalho Chehab 	/*
54869a0bf528SMauro Carvalho Chehab 	 * STEP 3: enable the system in a mode where the ADC provides valid
54879a0bf528SMauro Carvalho Chehab 	 * signal setup modulation independent registers
54889a0bf528SMauro Carvalho Chehab 	 */
54899a0bf528SMauro Carvalho Chehab #if 0
5490cd7a67a4SMauro Carvalho Chehab 	status = set_frequency(channel, tuner_freq_offset));
54919a0bf528SMauro Carvalho Chehab 	if (status < 0)
54929a0bf528SMauro Carvalho Chehab 		goto error;
54939a0bf528SMauro Carvalho Chehab #endif
5494ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
5495ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
54969a0bf528SMauro Carvalho Chehab 	if (status < 0)
54979a0bf528SMauro Carvalho Chehab 		goto error;
54989a0bf528SMauro Carvalho Chehab 
54999a0bf528SMauro Carvalho Chehab 	/* Setup BER measurement */
5500ab5060cdSMauro Carvalho Chehab 	status = set_qam_measurement(state, state->m_constellation,
5501ab5060cdSMauro Carvalho Chehab 				     state->props.symbol_rate);
55029a0bf528SMauro Carvalho Chehab 	if (status < 0)
55039a0bf528SMauro Carvalho Chehab 		goto error;
55049a0bf528SMauro Carvalho Chehab 
55059a0bf528SMauro Carvalho Chehab 	/* Reset default values */
55069a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55079a0bf528SMauro Carvalho Chehab 	if (status < 0)
55089a0bf528SMauro Carvalho Chehab 		goto error;
55099a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55109a0bf528SMauro Carvalho Chehab 	if (status < 0)
55119a0bf528SMauro Carvalho Chehab 		goto error;
55129a0bf528SMauro Carvalho Chehab 
55139a0bf528SMauro Carvalho Chehab 	/* Reset default LC values */
55149a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55159a0bf528SMauro Carvalho Chehab 	if (status < 0)
55169a0bf528SMauro Carvalho Chehab 		goto error;
55179a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55189a0bf528SMauro Carvalho Chehab 	if (status < 0)
55199a0bf528SMauro Carvalho Chehab 		goto error;
55209a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
55219a0bf528SMauro Carvalho Chehab 	if (status < 0)
55229a0bf528SMauro Carvalho Chehab 		goto error;
55239a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_MODE__A, 7);
55249a0bf528SMauro Carvalho Chehab 	if (status < 0)
55259a0bf528SMauro Carvalho Chehab 		goto error;
55269a0bf528SMauro Carvalho Chehab 
55279a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
55289a0bf528SMauro Carvalho Chehab 	if (status < 0)
55299a0bf528SMauro Carvalho Chehab 		goto error;
55309a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
55319a0bf528SMauro Carvalho Chehab 	if (status < 0)
55329a0bf528SMauro Carvalho Chehab 		goto error;
55339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
55349a0bf528SMauro Carvalho Chehab 	if (status < 0)
55359a0bf528SMauro Carvalho Chehab 		goto error;
55369a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
55379a0bf528SMauro Carvalho Chehab 	if (status < 0)
55389a0bf528SMauro Carvalho Chehab 		goto error;
55399a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
55409a0bf528SMauro Carvalho Chehab 	if (status < 0)
55419a0bf528SMauro Carvalho Chehab 		goto error;
55429a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
55439a0bf528SMauro Carvalho Chehab 	if (status < 0)
55449a0bf528SMauro Carvalho Chehab 		goto error;
55459a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
55469a0bf528SMauro Carvalho Chehab 	if (status < 0)
55479a0bf528SMauro Carvalho Chehab 		goto error;
55489a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
55499a0bf528SMauro Carvalho Chehab 	if (status < 0)
55509a0bf528SMauro Carvalho Chehab 		goto error;
55519a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
55529a0bf528SMauro Carvalho Chehab 	if (status < 0)
55539a0bf528SMauro Carvalho Chehab 		goto error;
55549a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
55559a0bf528SMauro Carvalho Chehab 	if (status < 0)
55569a0bf528SMauro Carvalho Chehab 		goto error;
55579a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
55589a0bf528SMauro Carvalho Chehab 	if (status < 0)
55599a0bf528SMauro Carvalho Chehab 		goto error;
55609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
55619a0bf528SMauro Carvalho Chehab 	if (status < 0)
55629a0bf528SMauro Carvalho Chehab 		goto error;
55639a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
55649a0bf528SMauro Carvalho Chehab 	if (status < 0)
55659a0bf528SMauro Carvalho Chehab 		goto error;
55669a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
55679a0bf528SMauro Carvalho Chehab 	if (status < 0)
55689a0bf528SMauro Carvalho Chehab 		goto error;
55699a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
55709a0bf528SMauro Carvalho Chehab 	if (status < 0)
55719a0bf528SMauro Carvalho Chehab 		goto error;
55729a0bf528SMauro Carvalho Chehab 
55739a0bf528SMauro Carvalho Chehab 	/* Mirroring, QAM-block starting point not inverted */
5574ab5060cdSMauro Carvalho Chehab 	status = write16(state, QAM_SY_SP_INV__A,
5575ab5060cdSMauro Carvalho Chehab 			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
55769a0bf528SMauro Carvalho Chehab 	if (status < 0)
55779a0bf528SMauro Carvalho Chehab 		goto error;
55789a0bf528SMauro Carvalho Chehab 
55799a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
55809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
55819a0bf528SMauro Carvalho Chehab 	if (status < 0)
55829a0bf528SMauro Carvalho Chehab 		goto error;
55839a0bf528SMauro Carvalho Chehab 
55849a0bf528SMauro Carvalho Chehab 	/* STEP 4: modulation specific setup */
55859a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
55869a0bf528SMauro Carvalho Chehab 	case QAM_16:
5587cd7a67a4SMauro Carvalho Chehab 		status = set_qam16(state);
55889a0bf528SMauro Carvalho Chehab 		break;
55899a0bf528SMauro Carvalho Chehab 	case QAM_32:
5590cd7a67a4SMauro Carvalho Chehab 		status = set_qam32(state);
55919a0bf528SMauro Carvalho Chehab 		break;
55929a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
55939a0bf528SMauro Carvalho Chehab 	case QAM_64:
5594cd7a67a4SMauro Carvalho Chehab 		status = set_qam64(state);
55959a0bf528SMauro Carvalho Chehab 		break;
55969a0bf528SMauro Carvalho Chehab 	case QAM_128:
5597cd7a67a4SMauro Carvalho Chehab 		status = set_qam128(state);
55989a0bf528SMauro Carvalho Chehab 		break;
55999a0bf528SMauro Carvalho Chehab 	case QAM_256:
5600cd7a67a4SMauro Carvalho Chehab 		status = set_qam256(state);
56019a0bf528SMauro Carvalho Chehab 		break;
56029a0bf528SMauro Carvalho Chehab 	default:
56039a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
56049a0bf528SMauro Carvalho Chehab 		break;
56059a0bf528SMauro Carvalho Chehab 	}
56069a0bf528SMauro Carvalho Chehab 	if (status < 0)
56079a0bf528SMauro Carvalho Chehab 		goto error;
56089a0bf528SMauro Carvalho Chehab 
56099a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
56109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56119a0bf528SMauro Carvalho Chehab 	if (status < 0)
56129a0bf528SMauro Carvalho Chehab 		goto error;
56139a0bf528SMauro Carvalho Chehab 
56149a0bf528SMauro Carvalho Chehab 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
56159a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.modulation = channel->modulation; */
56169a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
5617cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, state->m_operation_mode);
56189a0bf528SMauro Carvalho Chehab 	if (status < 0)
56199a0bf528SMauro Carvalho Chehab 		goto error;
56209a0bf528SMauro Carvalho Chehab 
5621cd7a67a4SMauro Carvalho Chehab 	/* start processes */
5622cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
56239a0bf528SMauro Carvalho Chehab 	if (status < 0)
56249a0bf528SMauro Carvalho Chehab 		goto error;
56259a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
56269a0bf528SMauro Carvalho Chehab 	if (status < 0)
56279a0bf528SMauro Carvalho Chehab 		goto error;
56289a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
56299a0bf528SMauro Carvalho Chehab 	if (status < 0)
56309a0bf528SMauro Carvalho Chehab 		goto error;
56319a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
56329a0bf528SMauro Carvalho Chehab 	if (status < 0)
56339a0bf528SMauro Carvalho Chehab 		goto error;
56349a0bf528SMauro Carvalho Chehab 
56359a0bf528SMauro Carvalho Chehab 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5636ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5637ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
5638ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
56399a0bf528SMauro Carvalho Chehab 	if (status < 0)
56409a0bf528SMauro Carvalho Chehab 		goto error;
56419a0bf528SMauro Carvalho Chehab 
56429a0bf528SMauro Carvalho Chehab 	/* update global DRXK data container */
56439a0bf528SMauro Carvalho Chehab /*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
56449a0bf528SMauro Carvalho Chehab 
56459a0bf528SMauro Carvalho Chehab error:
56469a0bf528SMauro Carvalho Chehab 	if (status < 0)
56473a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
56489a0bf528SMauro Carvalho Chehab 	return status;
56499a0bf528SMauro Carvalho Chehab }
56509a0bf528SMauro Carvalho Chehab 
set_qam_standard(struct drxk_state * state,enum operation_mode o_mode)5651cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
5652cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
56539a0bf528SMauro Carvalho Chehab {
56549a0bf528SMauro Carvalho Chehab 	int status;
56559a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
56569a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
56579a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
56589a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
56599a0bf528SMauro Carvalho Chehab #endif
56609a0bf528SMauro Carvalho Chehab 
56619a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
56629a0bf528SMauro Carvalho Chehab 
56639a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
5664cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_qam(state);
56659a0bf528SMauro Carvalho Chehab 
56669a0bf528SMauro Carvalho Chehab 	/* Ensure correct power-up mode */
5667cd7a67a4SMauro Carvalho Chehab 	status = power_up_qam(state);
56689a0bf528SMauro Carvalho Chehab 	if (status < 0)
56699a0bf528SMauro Carvalho Chehab 		goto error;
56709a0bf528SMauro Carvalho Chehab 	/* Reset QAM block */
5671cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
56729a0bf528SMauro Carvalho Chehab 	if (status < 0)
56739a0bf528SMauro Carvalho Chehab 		goto error;
56749a0bf528SMauro Carvalho Chehab 
56759a0bf528SMauro Carvalho Chehab 	/* Setup IQM */
56769a0bf528SMauro Carvalho Chehab 
56779a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
56789a0bf528SMauro Carvalho Chehab 	if (status < 0)
56799a0bf528SMauro Carvalho Chehab 		goto error;
56809a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
56819a0bf528SMauro Carvalho Chehab 	if (status < 0)
56829a0bf528SMauro Carvalho Chehab 		goto error;
56839a0bf528SMauro Carvalho Chehab 
56849a0bf528SMauro Carvalho Chehab 	/* Upload IQM Channel Filter settings by
56859a0bf528SMauro Carvalho Chehab 		boot loader from ROM table */
5686cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
56879a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
5688ab5060cdSMauro Carvalho Chehab 		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5689ab5060cdSMauro Carvalho Chehab 				      DRXK_BLCC_NR_ELEMENTS_TAPS,
5690ab5060cdSMauro Carvalho Chehab 			DRXK_BLC_TIMEOUT);
56919a0bf528SMauro Carvalho Chehab 		break;
56929a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
5693ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5694ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5695ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5696ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
56979a0bf528SMauro Carvalho Chehab 		if (status < 0)
56989a0bf528SMauro Carvalho Chehab 			goto error;
5699ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state,
5700ab5060cdSMauro Carvalho Chehab 				       IQM_CF_TAP_IM0__A,
5701ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5702ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5703ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57049a0bf528SMauro Carvalho Chehab 		break;
57059a0bf528SMauro Carvalho Chehab 	default:
57069a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
57079a0bf528SMauro Carvalho Chehab 	}
57089a0bf528SMauro Carvalho Chehab 	if (status < 0)
57099a0bf528SMauro Carvalho Chehab 		goto error;
57109a0bf528SMauro Carvalho Chehab 
5711ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
57129a0bf528SMauro Carvalho Chehab 	if (status < 0)
57139a0bf528SMauro Carvalho Chehab 		goto error;
57149a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57159a0bf528SMauro Carvalho Chehab 	if (status < 0)
57169a0bf528SMauro Carvalho Chehab 		goto error;
5717ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_MIDTAP__A,
5718ab5060cdSMauro Carvalho Chehab 		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57199a0bf528SMauro Carvalho Chehab 	if (status < 0)
57209a0bf528SMauro Carvalho Chehab 		goto error;
57219a0bf528SMauro Carvalho Chehab 
57229a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 21);
57239a0bf528SMauro Carvalho Chehab 	if (status < 0)
57249a0bf528SMauro Carvalho Chehab 		goto error;
57259a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
57269a0bf528SMauro Carvalho Chehab 	if (status < 0)
57279a0bf528SMauro Carvalho Chehab 		goto error;
57289a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
57299a0bf528SMauro Carvalho Chehab 	if (status < 0)
57309a0bf528SMauro Carvalho Chehab 		goto error;
57319a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
57329a0bf528SMauro Carvalho Chehab 	if (status < 0)
57339a0bf528SMauro Carvalho Chehab 		goto error;
57349a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
57359a0bf528SMauro Carvalho Chehab 	if (status < 0)
57369a0bf528SMauro Carvalho Chehab 		goto error;
57379a0bf528SMauro Carvalho Chehab 
57389a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FS_ADJ_SEL__A, 1);
57399a0bf528SMauro Carvalho Chehab 	if (status < 0)
57409a0bf528SMauro Carvalho Chehab 		goto error;
57419a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_ADJ_SEL__A, 1);
57429a0bf528SMauro Carvalho Chehab 	if (status < 0)
57439a0bf528SMauro Carvalho Chehab 		goto error;
57449a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_ADJ_SEL__A, 1);
57459a0bf528SMauro Carvalho Chehab 	if (status < 0)
57469a0bf528SMauro Carvalho Chehab 		goto error;
57479a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 0);
57489a0bf528SMauro Carvalho Chehab 	if (status < 0)
57499a0bf528SMauro Carvalho Chehab 		goto error;
57509a0bf528SMauro Carvalho Chehab 
57519a0bf528SMauro Carvalho Chehab 	/* IQM Impulse Noise Processing Unit */
57529a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_CLP_VAL__A, 500);
57539a0bf528SMauro Carvalho Chehab 	if (status < 0)
57549a0bf528SMauro Carvalho Chehab 		goto error;
57559a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 1000);
57569a0bf528SMauro Carvalho Chehab 	if (status < 0)
57579a0bf528SMauro Carvalho Chehab 		goto error;
57589a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_BYPASSDET__A, 1);
57599a0bf528SMauro Carvalho Chehab 	if (status < 0)
57609a0bf528SMauro Carvalho Chehab 		goto error;
57619a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);
57629a0bf528SMauro Carvalho Chehab 	if (status < 0)
57639a0bf528SMauro Carvalho Chehab 		goto error;
57649a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 1);
57659a0bf528SMauro Carvalho Chehab 	if (status < 0)
57669a0bf528SMauro Carvalho Chehab 		goto error;
57679a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 1);
57689a0bf528SMauro Carvalho Chehab 	if (status < 0)
57699a0bf528SMauro Carvalho Chehab 		goto error;
57709a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_BYPASS__A, 1);
57719a0bf528SMauro Carvalho Chehab 	if (status < 0)
57729a0bf528SMauro Carvalho Chehab 		goto error;
57739a0bf528SMauro Carvalho Chehab 
57749a0bf528SMauro Carvalho Chehab 	/* turn on IQMAF. Must be done before setAgc**() */
5775cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
57769a0bf528SMauro Carvalho Chehab 	if (status < 0)
57779a0bf528SMauro Carvalho Chehab 		goto error;
57789a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
57799a0bf528SMauro Carvalho Chehab 	if (status < 0)
57809a0bf528SMauro Carvalho Chehab 		goto error;
57819a0bf528SMauro Carvalho Chehab 
57829a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
5783cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
57849a0bf528SMauro Carvalho Chehab 	if (status < 0)
57859a0bf528SMauro Carvalho Chehab 		goto error;
57869a0bf528SMauro Carvalho Chehab 
57879a0bf528SMauro Carvalho Chehab 	/* Set the FSM step period */
57889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
57899a0bf528SMauro Carvalho Chehab 	if (status < 0)
57909a0bf528SMauro Carvalho Chehab 		goto error;
57919a0bf528SMauro Carvalho Chehab 
57929a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
57939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
57949a0bf528SMauro Carvalho Chehab 	if (status < 0)
57959a0bf528SMauro Carvalho Chehab 		goto error;
57969a0bf528SMauro Carvalho Chehab 
57979a0bf528SMauro Carvalho Chehab 	/* No more resets of the IQM, current standard correctly set =>
57989a0bf528SMauro Carvalho Chehab 		now AGCs can be configured. */
57999a0bf528SMauro Carvalho Chehab 
5800cd7a67a4SMauro Carvalho Chehab 	status = init_agc(state, true);
58019a0bf528SMauro Carvalho Chehab 	if (status < 0)
58029a0bf528SMauro Carvalho Chehab 		goto error;
5803cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
58049a0bf528SMauro Carvalho Chehab 	if (status < 0)
58059a0bf528SMauro Carvalho Chehab 		goto error;
58069a0bf528SMauro Carvalho Chehab 
58079a0bf528SMauro Carvalho Chehab 	/* Configure AGC's */
5808cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
58099a0bf528SMauro Carvalho Chehab 	if (status < 0)
58109a0bf528SMauro Carvalho Chehab 		goto error;
5811cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
58129a0bf528SMauro Carvalho Chehab 	if (status < 0)
58139a0bf528SMauro Carvalho Chehab 		goto error;
58149a0bf528SMauro Carvalho Chehab 
58159a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
58169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58179a0bf528SMauro Carvalho Chehab error:
58189a0bf528SMauro Carvalho Chehab 	if (status < 0)
58193a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
58209a0bf528SMauro Carvalho Chehab 	return status;
58219a0bf528SMauro Carvalho Chehab }
58229a0bf528SMauro Carvalho Chehab 
write_gpio(struct drxk_state * state)5823cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state)
58249a0bf528SMauro Carvalho Chehab {
58259a0bf528SMauro Carvalho Chehab 	int status;
58269a0bf528SMauro Carvalho Chehab 	u16 value = 0;
58279a0bf528SMauro Carvalho Chehab 
58289a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
58299a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
5830ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
5831ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58329a0bf528SMauro Carvalho Chehab 	if (status < 0)
58339a0bf528SMauro Carvalho Chehab 		goto error;
58349a0bf528SMauro Carvalho Chehab 
58359a0bf528SMauro Carvalho Chehab 	/*  Write magic word to enable pdr reg write               */
58369a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
58379a0bf528SMauro Carvalho Chehab 	if (status < 0)
58389a0bf528SMauro Carvalho Chehab 		goto error;
58399a0bf528SMauro Carvalho Chehab 
5840cd7a67a4SMauro Carvalho Chehab 	if (state->m_has_sawsw) {
5841cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0001) { /* UIO-1 */
58429a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5843ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5844ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58459a0bf528SMauro Carvalho Chehab 			if (status < 0)
58469a0bf528SMauro Carvalho Chehab 				goto error;
58479a0bf528SMauro Carvalho Chehab 
58489a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
58499a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58509a0bf528SMauro Carvalho Chehab 			if (status < 0)
58519a0bf528SMauro Carvalho Chehab 				goto error;
5852cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0001) == 0)
58539a0bf528SMauro Carvalho Chehab 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
58549a0bf528SMauro Carvalho Chehab 			else
58559a0bf528SMauro Carvalho Chehab 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
58569a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
58579a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58589a0bf528SMauro Carvalho Chehab 			if (status < 0)
58599a0bf528SMauro Carvalho Chehab 				goto error;
58609a0bf528SMauro Carvalho Chehab 		}
5861cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0002) { /* UIO-2 */
58629a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5863ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5864ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58659a0bf528SMauro Carvalho Chehab 			if (status < 0)
58669a0bf528SMauro Carvalho Chehab 				goto error;
58679a0bf528SMauro Carvalho Chehab 
58689a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
58699a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58709a0bf528SMauro Carvalho Chehab 			if (status < 0)
58719a0bf528SMauro Carvalho Chehab 				goto error;
5872cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0002) == 0)
58739a0bf528SMauro Carvalho Chehab 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
58749a0bf528SMauro Carvalho Chehab 			else
58759a0bf528SMauro Carvalho Chehab 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
58769a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
58779a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58789a0bf528SMauro Carvalho Chehab 			if (status < 0)
58799a0bf528SMauro Carvalho Chehab 				goto error;
58809a0bf528SMauro Carvalho Chehab 		}
5881cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0004) { /* UIO-3 */
58829a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5883ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_GPIO_CFG__A,
5884ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58859a0bf528SMauro Carvalho Chehab 			if (status < 0)
58869a0bf528SMauro Carvalho Chehab 				goto error;
58879a0bf528SMauro Carvalho Chehab 
58889a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
58899a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58909a0bf528SMauro Carvalho Chehab 			if (status < 0)
58919a0bf528SMauro Carvalho Chehab 				goto error;
5892cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0004) == 0)
58939a0bf528SMauro Carvalho Chehab 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
58949a0bf528SMauro Carvalho Chehab 			else
58959a0bf528SMauro Carvalho Chehab 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
58969a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
58979a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58989a0bf528SMauro Carvalho Chehab 			if (status < 0)
58999a0bf528SMauro Carvalho Chehab 				goto error;
59009a0bf528SMauro Carvalho Chehab 		}
59019a0bf528SMauro Carvalho Chehab 	}
59029a0bf528SMauro Carvalho Chehab 	/*  Write magic word to disable pdr reg write               */
59039a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59049a0bf528SMauro Carvalho Chehab error:
59059a0bf528SMauro Carvalho Chehab 	if (status < 0)
59063a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59079a0bf528SMauro Carvalho Chehab 	return status;
59089a0bf528SMauro Carvalho Chehab }
59099a0bf528SMauro Carvalho Chehab 
switch_antenna_to_qam(struct drxk_state * state)5910cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state)
59119a0bf528SMauro Carvalho Chehab {
59129a0bf528SMauro Carvalho Chehab 	int status = 0;
59139a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59149a0bf528SMauro Carvalho Chehab 
59159a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59169a0bf528SMauro Carvalho Chehab 
59179a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59189a0bf528SMauro Carvalho Chehab 		return 0;
59199a0bf528SMauro Carvalho Chehab 
5920cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59219a0bf528SMauro Carvalho Chehab 
59229a0bf528SMauro Carvalho Chehab 	if (state->antenna_dvbt ^ gpio_state) {
59239a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-T mode. Switch */
59249a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5925cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
59269a0bf528SMauro Carvalho Chehab 		else
5927cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
5928cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59299a0bf528SMauro Carvalho Chehab 	}
59309a0bf528SMauro Carvalho Chehab 	if (status < 0)
59313a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59329a0bf528SMauro Carvalho Chehab 	return status;
59339a0bf528SMauro Carvalho Chehab }
59349a0bf528SMauro Carvalho Chehab 
switch_antenna_to_dvbt(struct drxk_state * state)5935cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state)
59369a0bf528SMauro Carvalho Chehab {
59379a0bf528SMauro Carvalho Chehab 	int status = 0;
59389a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59399a0bf528SMauro Carvalho Chehab 
59409a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59419a0bf528SMauro Carvalho Chehab 
59429a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59439a0bf528SMauro Carvalho Chehab 		return 0;
59449a0bf528SMauro Carvalho Chehab 
5945cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59469a0bf528SMauro Carvalho Chehab 
59479a0bf528SMauro Carvalho Chehab 	if (!(state->antenna_dvbt ^ gpio_state)) {
59489a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-C mode. Switch */
59499a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5950cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
59519a0bf528SMauro Carvalho Chehab 		else
5952cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
5953cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59549a0bf528SMauro Carvalho Chehab 	}
59559a0bf528SMauro Carvalho Chehab 	if (status < 0)
59563a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59579a0bf528SMauro Carvalho Chehab 	return status;
59589a0bf528SMauro Carvalho Chehab }
59599a0bf528SMauro Carvalho Chehab 
59609a0bf528SMauro Carvalho Chehab 
power_down_device(struct drxk_state * state)5961cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state)
59629a0bf528SMauro Carvalho Chehab {
59639a0bf528SMauro Carvalho Chehab 	/* Power down to requested mode */
59649a0bf528SMauro Carvalho Chehab 	/* Backup some register settings */
59659a0bf528SMauro Carvalho Chehab 	/* Set pins with possible pull-ups connected to them in input mode */
59669a0bf528SMauro Carvalho Chehab 	/* Analog power down */
59679a0bf528SMauro Carvalho Chehab 	/* ADC power down */
59689a0bf528SMauro Carvalho Chehab 	/* Power down device */
59699a0bf528SMauro Carvalho Chehab 	int status;
59709a0bf528SMauro Carvalho Chehab 
59719a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5972cd7a67a4SMauro Carvalho Chehab 	if (state->m_b_p_down_open_bridge) {
59739a0bf528SMauro Carvalho Chehab 		/* Open I2C bridge before power down of DRXK */
59749a0bf528SMauro Carvalho Chehab 		status = ConfigureI2CBridge(state, true);
59759a0bf528SMauro Carvalho Chehab 		if (status < 0)
59769a0bf528SMauro Carvalho Chehab 			goto error;
59779a0bf528SMauro Carvalho Chehab 	}
59789a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
5979cd7a67a4SMauro Carvalho Chehab 	status = dvbt_enable_ofdm_token_ring(state, false);
59809a0bf528SMauro Carvalho Chehab 	if (status < 0)
59819a0bf528SMauro Carvalho Chehab 		goto error;
59829a0bf528SMauro Carvalho Chehab 
5983ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A,
5984ab5060cdSMauro Carvalho Chehab 			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
59859a0bf528SMauro Carvalho Chehab 	if (status < 0)
59869a0bf528SMauro Carvalho Chehab 		goto error;
59879a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
59889a0bf528SMauro Carvalho Chehab 	if (status < 0)
59899a0bf528SMauro Carvalho Chehab 		goto error;
5990cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5991cd7a67a4SMauro Carvalho Chehab 	status = hi_cfg_command(state);
59929a0bf528SMauro Carvalho Chehab error:
59939a0bf528SMauro Carvalho Chehab 	if (status < 0)
59943a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59959a0bf528SMauro Carvalho Chehab 
59969a0bf528SMauro Carvalho Chehab 	return status;
59979a0bf528SMauro Carvalho Chehab }
59989a0bf528SMauro Carvalho Chehab 
init_drxk(struct drxk_state * state)59999a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60009a0bf528SMauro Carvalho Chehab {
60019a0bf528SMauro Carvalho Chehab 	int status = 0, n = 0;
6002cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6003cd7a67a4SMauro Carvalho Chehab 	u16 driver_version;
60049a0bf528SMauro Carvalho Chehab 
60059a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60067369bbf2SNick Desaulniers 	if (state->m_drxk_state == DRXK_UNINITIALIZED) {
60079a0bf528SMauro Carvalho Chehab 		drxk_i2c_lock(state);
6008cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
60099a0bf528SMauro Carvalho Chehab 		if (status < 0)
60109a0bf528SMauro Carvalho Chehab 			goto error;
6011cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
60129a0bf528SMauro Carvalho Chehab 		if (status < 0)
60139a0bf528SMauro Carvalho Chehab 			goto error;
60149a0bf528SMauro Carvalho Chehab 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
6015ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_CC_SOFT_RST__A,
6016ab5060cdSMauro Carvalho Chehab 				 SIO_CC_SOFT_RST_OFDM__M
6017ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_SYS__M
6018ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_OSC__M);
60199a0bf528SMauro Carvalho Chehab 		if (status < 0)
60209a0bf528SMauro Carvalho Chehab 			goto error;
60219a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60229a0bf528SMauro Carvalho Chehab 		if (status < 0)
60239a0bf528SMauro Carvalho Chehab 			goto error;
6024ab5060cdSMauro Carvalho Chehab 		/*
6025ab5060cdSMauro Carvalho Chehab 		 * TODO is this needed? If yes, how much delay in
6026ab5060cdSMauro Carvalho Chehab 		 * worst case scenario
6027ab5060cdSMauro Carvalho Chehab 		 */
6028b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
6029cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_a3_patch_code = true;
6030cd7a67a4SMauro Carvalho Chehab 		status = get_device_capabilities(state);
60319a0bf528SMauro Carvalho Chehab 		if (status < 0)
60329a0bf528SMauro Carvalho Chehab 			goto error;
60339a0bf528SMauro Carvalho Chehab 
60349a0bf528SMauro Carvalho Chehab 		/* Bridge delay, uses oscilator clock */
60359a0bf528SMauro Carvalho Chehab 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60369a0bf528SMauro Carvalho Chehab 		/* SDA brdige delay */
6037cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay =
6038cd7a67a4SMauro Carvalho Chehab 			(u16) ((state->m_osc_clock_freq / 1000) *
60399a0bf528SMauro Carvalho Chehab 				HI_I2C_BRIDGE_DELAY) / 1000;
60409a0bf528SMauro Carvalho Chehab 		/* Clipping */
6041cd7a67a4SMauro Carvalho Chehab 		if (state->m_hi_cfg_bridge_delay >
60429a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6043cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay =
60449a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
60459a0bf528SMauro Carvalho Chehab 		}
60469a0bf528SMauro Carvalho Chehab 		/* SCL bridge delay, same as SDA for now */
6047cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay +=
6048cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay <<
60499a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
60509a0bf528SMauro Carvalho Chehab 
6051cd7a67a4SMauro Carvalho Chehab 		status = init_hi(state);
60529a0bf528SMauro Carvalho Chehab 		if (status < 0)
60539a0bf528SMauro Carvalho Chehab 			goto error;
60549a0bf528SMauro Carvalho Chehab 		/* disable various processes */
60559a0bf528SMauro Carvalho Chehab #if NOA1ROM
60569a0bf528SMauro Carvalho Chehab 		if (!(state->m_DRXK_A1_ROM_CODE)
60579a0bf528SMauro Carvalho Chehab 			&& !(state->m_DRXK_A2_ROM_CODE))
60589a0bf528SMauro Carvalho Chehab #endif
60599a0bf528SMauro Carvalho Chehab 		{
6060ab5060cdSMauro Carvalho Chehab 			status = write16(state, SCU_RAM_GPIO__A,
6061ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
60629a0bf528SMauro Carvalho Chehab 			if (status < 0)
60639a0bf528SMauro Carvalho Chehab 				goto error;
60649a0bf528SMauro Carvalho Chehab 		}
60659a0bf528SMauro Carvalho Chehab 
60669a0bf528SMauro Carvalho Chehab 		/* disable MPEG port */
6067cd7a67a4SMauro Carvalho Chehab 		status = mpegts_disable(state);
60689a0bf528SMauro Carvalho Chehab 		if (status < 0)
60699a0bf528SMauro Carvalho Chehab 			goto error;
60709a0bf528SMauro Carvalho Chehab 
60719a0bf528SMauro Carvalho Chehab 		/* Stop AUD and SCU */
60729a0bf528SMauro Carvalho Chehab 		status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
60739a0bf528SMauro Carvalho Chehab 		if (status < 0)
60749a0bf528SMauro Carvalho Chehab 			goto error;
60759a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
60769a0bf528SMauro Carvalho Chehab 		if (status < 0)
60779a0bf528SMauro Carvalho Chehab 			goto error;
60789a0bf528SMauro Carvalho Chehab 
60799a0bf528SMauro Carvalho Chehab 		/* enable token-ring bus through OFDM block for possible ucode upload */
6080ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6081ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
60829a0bf528SMauro Carvalho Chehab 		if (status < 0)
60839a0bf528SMauro Carvalho Chehab 			goto error;
60849a0bf528SMauro Carvalho Chehab 
60859a0bf528SMauro Carvalho Chehab 		/* include boot loader section */
6086ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_BL_COMM_EXEC__A,
6087ab5060cdSMauro Carvalho Chehab 				 SIO_BL_COMM_EXEC_ACTIVE);
60889a0bf528SMauro Carvalho Chehab 		if (status < 0)
60899a0bf528SMauro Carvalho Chehab 			goto error;
6090cd7a67a4SMauro Carvalho Chehab 		status = bl_chain_cmd(state, 0, 6, 100);
60919a0bf528SMauro Carvalho Chehab 		if (status < 0)
60929a0bf528SMauro Carvalho Chehab 			goto error;
60939a0bf528SMauro Carvalho Chehab 
60949a0bf528SMauro Carvalho Chehab 		if (state->fw) {
6095cd7a67a4SMauro Carvalho Chehab 			status = download_microcode(state, state->fw->data,
60969a0bf528SMauro Carvalho Chehab 						   state->fw->size);
60979a0bf528SMauro Carvalho Chehab 			if (status < 0)
60989a0bf528SMauro Carvalho Chehab 				goto error;
60999a0bf528SMauro Carvalho Chehab 		}
61009a0bf528SMauro Carvalho Chehab 
61019a0bf528SMauro Carvalho Chehab 		/* disable token-ring bus through OFDM block for possible ucode upload */
6102ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6103ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
61049a0bf528SMauro Carvalho Chehab 		if (status < 0)
61059a0bf528SMauro Carvalho Chehab 			goto error;
61069a0bf528SMauro Carvalho Chehab 
61079a0bf528SMauro Carvalho Chehab 		/* Run SCU for a little while to initialize microcode version numbers */
61089a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61099a0bf528SMauro Carvalho Chehab 		if (status < 0)
61109a0bf528SMauro Carvalho Chehab 			goto error;
6111cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
61129a0bf528SMauro Carvalho Chehab 		if (status < 0)
61139a0bf528SMauro Carvalho Chehab 			goto error;
61149a0bf528SMauro Carvalho Chehab 		/* added for test */
61159a0bf528SMauro Carvalho Chehab 		msleep(30);
61169a0bf528SMauro Carvalho Chehab 
6117cd7a67a4SMauro Carvalho Chehab 		power_mode = DRXK_POWER_DOWN_OFDM;
6118cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
61199a0bf528SMauro Carvalho Chehab 		if (status < 0)
61209a0bf528SMauro Carvalho Chehab 			goto error;
61219a0bf528SMauro Carvalho Chehab 
61229a0bf528SMauro Carvalho Chehab 		/* Stamp driver version number in SCU data RAM in BCD code
612339c1cb2bSJonathan McCrohan 			Done to enable field application engineers to retrieve drxdriver version
61249a0bf528SMauro Carvalho Chehab 			via I2C from SCU RAM.
61259a0bf528SMauro Carvalho Chehab 			Not using SCU command interface for SCU register access since no
61269a0bf528SMauro Carvalho Chehab 			microcode may be present.
61279a0bf528SMauro Carvalho Chehab 			*/
6128cd7a67a4SMauro Carvalho Chehab 		driver_version =
61299a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61309a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61319a0bf528SMauro Carvalho Chehab 			((DRXK_VERSION_MAJOR % 10) << 4) +
61329a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_MINOR % 10);
6133ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6134ab5060cdSMauro Carvalho Chehab 				 driver_version);
61359a0bf528SMauro Carvalho Chehab 		if (status < 0)
61369a0bf528SMauro Carvalho Chehab 			goto error;
6137cd7a67a4SMauro Carvalho Chehab 		driver_version =
61389a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61399a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61409a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
61419a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_PATCH % 10);
6142ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6143ab5060cdSMauro Carvalho Chehab 				 driver_version);
61449a0bf528SMauro Carvalho Chehab 		if (status < 0)
61459a0bf528SMauro Carvalho Chehab 			goto error;
61469a0bf528SMauro Carvalho Chehab 
61473a4398f5SMauro Carvalho Chehab 		pr_info("DRXK driver version %d.%d.%d\n",
61489a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
61499a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_PATCH);
61509a0bf528SMauro Carvalho Chehab 
6151ab5060cdSMauro Carvalho Chehab 		/*
6152ab5060cdSMauro Carvalho Chehab 		 * Dirty fix of default values for ROM/PATCH microcode
6153ab5060cdSMauro Carvalho Chehab 		 * Dirty because this fix makes it impossible to setup
6154ab5060cdSMauro Carvalho Chehab 		 * suitable values before calling DRX_Open. This solution
6155ab5060cdSMauro Carvalho Chehab 		 * requires changes to RF AGC speed to be done via the CTRL
6156ab5060cdSMauro Carvalho Chehab 		 * function after calling DRX_Open
6157ab5060cdSMauro Carvalho Chehab 		 */
61589a0bf528SMauro Carvalho Chehab 
6159cd7a67a4SMauro Carvalho Chehab 		/* m_dvbt_rf_agc_cfg.speed = 3; */
61609a0bf528SMauro Carvalho Chehab 
61619a0bf528SMauro Carvalho Chehab 		/* Reset driver debug flags to 0 */
61629a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
61639a0bf528SMauro Carvalho Chehab 		if (status < 0)
61649a0bf528SMauro Carvalho Chehab 			goto error;
61659a0bf528SMauro Carvalho Chehab 		/* driver 0.9.0 */
61669a0bf528SMauro Carvalho Chehab 		/* Setup FEC OC:
61679a0bf528SMauro Carvalho Chehab 			NOTE: No more full FEC resets allowed afterwards!! */
61689a0bf528SMauro Carvalho Chehab 		status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
61699a0bf528SMauro Carvalho Chehab 		if (status < 0)
61709a0bf528SMauro Carvalho Chehab 			goto error;
61719a0bf528SMauro Carvalho Chehab 		/* MPEGTS functions are still the same */
6172cd7a67a4SMauro Carvalho Chehab 		status = mpegts_dto_init(state);
61739a0bf528SMauro Carvalho Chehab 		if (status < 0)
61749a0bf528SMauro Carvalho Chehab 			goto error;
6175cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
61769a0bf528SMauro Carvalho Chehab 		if (status < 0)
61779a0bf528SMauro Carvalho Chehab 			goto error;
6178cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_polarity(state);
61799a0bf528SMauro Carvalho Chehab 		if (status < 0)
61809a0bf528SMauro Carvalho Chehab 			goto error;
6181cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
61829a0bf528SMauro Carvalho Chehab 		if (status < 0)
61839a0bf528SMauro Carvalho Chehab 			goto error;
61849a0bf528SMauro Carvalho Chehab 		/* added: configure GPIO */
6185cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
61869a0bf528SMauro Carvalho Chehab 		if (status < 0)
61879a0bf528SMauro Carvalho Chehab 			goto error;
61889a0bf528SMauro Carvalho Chehab 
6189cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_STOPPED;
61909a0bf528SMauro Carvalho Chehab 
6191cd7a67a4SMauro Carvalho Chehab 		if (state->m_b_power_down) {
6192cd7a67a4SMauro Carvalho Chehab 			status = power_down_device(state);
61939a0bf528SMauro Carvalho Chehab 			if (status < 0)
61949a0bf528SMauro Carvalho Chehab 				goto error;
6195cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_POWERED_DOWN;
61969a0bf528SMauro Carvalho Chehab 		} else
6197cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_STOPPED;
61989a0bf528SMauro Carvalho Chehab 
61999a0bf528SMauro Carvalho Chehab 		/* Initialize the supported delivery systems */
62009a0bf528SMauro Carvalho Chehab 		n = 0;
6201cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbc) {
62029a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62039a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62049a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-C",
62059a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62069a0bf528SMauro Carvalho Chehab 		}
6207cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbt) {
62089a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBT;
62099a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-T",
62109a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62119a0bf528SMauro Carvalho Chehab 		}
62129a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62139a0bf528SMauro Carvalho Chehab 	}
62149a0bf528SMauro Carvalho Chehab error:
62159a0bf528SMauro Carvalho Chehab 	if (status < 0) {
6216cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_NO_DEV;
62179a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
62199a0bf528SMauro Carvalho Chehab 	}
62209a0bf528SMauro Carvalho Chehab 
62219a0bf528SMauro Carvalho Chehab 	return status;
62229a0bf528SMauro Carvalho Chehab }
62239a0bf528SMauro Carvalho Chehab 
load_firmware_cb(const struct firmware * fw,void * context)62249a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62259a0bf528SMauro Carvalho Chehab 			     void *context)
62269a0bf528SMauro Carvalho Chehab {
62279a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = context;
62289a0bf528SMauro Carvalho Chehab 
62299a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62309a0bf528SMauro Carvalho Chehab 	if (!fw) {
62313a4398f5SMauro Carvalho Chehab 		pr_err("Could not load firmware file %s.\n",
62329a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62333a4398f5SMauro Carvalho Chehab 		pr_info("Copy %s to your hotplug directory!\n",
62349a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62359a0bf528SMauro Carvalho Chehab 		state->microcode_name = NULL;
62369a0bf528SMauro Carvalho Chehab 
62379a0bf528SMauro Carvalho Chehab 		/*
62389a0bf528SMauro Carvalho Chehab 		 * As firmware is now load asynchronous, it is not possible
62399a0bf528SMauro Carvalho Chehab 		 * anymore to fail at frontend attach. We might silently
62409a0bf528SMauro Carvalho Chehab 		 * return here, and hope that the driver won't crash.
62419a0bf528SMauro Carvalho Chehab 		 * We might also change all DVB callbacks to return -ENODEV
62429a0bf528SMauro Carvalho Chehab 		 * if the device is not initialized.
62439a0bf528SMauro Carvalho Chehab 		 * As the DRX-K devices have their own internal firmware,
62449a0bf528SMauro Carvalho Chehab 		 * let's just hope that it will match a firmware revision
62459a0bf528SMauro Carvalho Chehab 		 * compatible with this driver and proceed.
62469a0bf528SMauro Carvalho Chehab 		 */
62479a0bf528SMauro Carvalho Chehab 	}
62489a0bf528SMauro Carvalho Chehab 	state->fw = fw;
62499a0bf528SMauro Carvalho Chehab 
62509a0bf528SMauro Carvalho Chehab 	init_drxk(state);
62519a0bf528SMauro Carvalho Chehab }
62529a0bf528SMauro Carvalho Chehab 
drxk_release(struct dvb_frontend * fe)62539a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
62549a0bf528SMauro Carvalho Chehab {
62559a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62569a0bf528SMauro Carvalho Chehab 
62579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
62589a0bf528SMauro Carvalho Chehab 	release_firmware(state->fw);
62599a0bf528SMauro Carvalho Chehab 
62609a0bf528SMauro Carvalho Chehab 	kfree(state);
62619a0bf528SMauro Carvalho Chehab }
62629a0bf528SMauro Carvalho Chehab 
drxk_sleep(struct dvb_frontend * fe)62639a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
62649a0bf528SMauro Carvalho Chehab {
62659a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62669a0bf528SMauro Carvalho Chehab 
62679a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
62689a0bf528SMauro Carvalho Chehab 
6269cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
62709a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6271cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
62729a0bf528SMauro Carvalho Chehab 		return 0;
62739a0bf528SMauro Carvalho Chehab 
6274cd7a67a4SMauro Carvalho Chehab 	shut_down(state);
62759a0bf528SMauro Carvalho Chehab 	return 0;
62769a0bf528SMauro Carvalho Chehab }
62779a0bf528SMauro Carvalho Chehab 
drxk_gate_ctrl(struct dvb_frontend * fe,int enable)62789a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
62799a0bf528SMauro Carvalho Chehab {
62809a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62819a0bf528SMauro Carvalho Chehab 
62829a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
62839a0bf528SMauro Carvalho Chehab 
6284cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
62859a0bf528SMauro Carvalho Chehab 		return -ENODEV;
62869a0bf528SMauro Carvalho Chehab 
62879a0bf528SMauro Carvalho Chehab 	return ConfigureI2CBridge(state, enable ? true : false);
62889a0bf528SMauro Carvalho Chehab }
62899a0bf528SMauro Carvalho Chehab 
drxk_set_parameters(struct dvb_frontend * fe)62909a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
62919a0bf528SMauro Carvalho Chehab {
62929a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
62939a0bf528SMauro Carvalho Chehab 	u32 delsys  = p->delivery_system, old_delsys;
62949a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62959a0bf528SMauro Carvalho Chehab 	u32 IF;
62969a0bf528SMauro Carvalho Chehab 
62979a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
62989a0bf528SMauro Carvalho Chehab 
6299cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63009a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63019a0bf528SMauro Carvalho Chehab 
6302cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63039a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
63049a0bf528SMauro Carvalho Chehab 
63059a0bf528SMauro Carvalho Chehab 	if (!fe->ops.tuner_ops.get_if_frequency) {
63063a4398f5SMauro Carvalho Chehab 		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63079a0bf528SMauro Carvalho Chehab 		return -EINVAL;
63089a0bf528SMauro Carvalho Chehab 	}
63099a0bf528SMauro Carvalho Chehab 
63109a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63119a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 1);
63129a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
63139a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
63149a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63159a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 0);
63169a0bf528SMauro Carvalho Chehab 
63179a0bf528SMauro Carvalho Chehab 	old_delsys = state->props.delivery_system;
63189a0bf528SMauro Carvalho Chehab 	state->props = *p;
63199a0bf528SMauro Carvalho Chehab 
63209a0bf528SMauro Carvalho Chehab 	if (old_delsys != delsys) {
6321cd7a67a4SMauro Carvalho Chehab 		shut_down(state);
63229a0bf528SMauro Carvalho Chehab 		switch (delsys) {
63239a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_A:
63249a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_C:
6325cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbc)
63269a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6327ab5060cdSMauro Carvalho Chehab 			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6328ab5060cdSMauro Carvalho Chehab 						true : false;
63299a0bf528SMauro Carvalho Chehab 			if (state->m_itut_annex_c)
6330cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_C);
63319a0bf528SMauro Carvalho Chehab 			else
6332cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_A);
63339a0bf528SMauro Carvalho Chehab 			break;
63349a0bf528SMauro Carvalho Chehab 		case SYS_DVBT:
6335cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbt)
63369a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6337cd7a67a4SMauro Carvalho Chehab 			setoperation_mode(state, OM_DVBT);
63389a0bf528SMauro Carvalho Chehab 			break;
63399a0bf528SMauro Carvalho Chehab 		default:
63409a0bf528SMauro Carvalho Chehab 			return -EINVAL;
63419a0bf528SMauro Carvalho Chehab 		}
63429a0bf528SMauro Carvalho Chehab 	}
63439a0bf528SMauro Carvalho Chehab 
63449a0bf528SMauro Carvalho Chehab 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
6345cd7a67a4SMauro Carvalho Chehab 	start(state, 0, IF);
63469a0bf528SMauro Carvalho Chehab 
634739c1cb2bSJonathan McCrohan 	/* After set_frontend, stats aren't available */
63488f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
63498f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63508f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63518f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63528f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63538f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63548f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63558f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63568f3741e0SMauro Carvalho Chehab 
63579a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
63589a0bf528SMauro Carvalho Chehab 
63599a0bf528SMauro Carvalho Chehab 	return 0;
63609a0bf528SMauro Carvalho Chehab }
63619a0bf528SMauro Carvalho Chehab 
get_strength(struct drxk_state * state,u64 * strength)636259a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength)
636359a7a23cSMauro Carvalho Chehab {
636459a7a23cSMauro Carvalho Chehab 	int status;
6365cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc   rf_agc, if_agc;
6366cd7a67a4SMauro Carvalho Chehab 	u32          total_gain  = 0;
636759a7a23cSMauro Carvalho Chehab 	u32          atten      = 0;
6368cd7a67a4SMauro Carvalho Chehab 	u32          agc_range   = 0;
636959a7a23cSMauro Carvalho Chehab 	u16            scu_lvl  = 0;
637059a7a23cSMauro Carvalho Chehab 	u16            scu_coc  = 0;
637159a7a23cSMauro Carvalho Chehab 	/* FIXME: those are part of the tuner presets */
6372cd7a67a4SMauro Carvalho Chehab 	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
6373cd7a67a4SMauro Carvalho Chehab 	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
637459a7a23cSMauro Carvalho Chehab 
637559a7a23cSMauro Carvalho Chehab 	*strength = 0;
637659a7a23cSMauro Carvalho Chehab 
6377cd7a67a4SMauro Carvalho Chehab 	if (is_dvbt(state)) {
6378cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_dvbt_rf_agc_cfg;
6379cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_dvbt_if_agc_cfg;
6380cd7a67a4SMauro Carvalho Chehab 	} else if (is_qam(state)) {
6381cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_qam_rf_agc_cfg;
6382cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_qam_if_agc_cfg;
638359a7a23cSMauro Carvalho Chehab 	} else {
6384cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_atv_rf_agc_cfg;
6385cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_atv_if_agc_cfg;
638659a7a23cSMauro Carvalho Chehab 	}
638759a7a23cSMauro Carvalho Chehab 
6388cd7a67a4SMauro Carvalho Chehab 	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6389cd7a67a4SMauro Carvalho Chehab 		/* SCU output_level */
639059a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
639159a7a23cSMauro Carvalho Chehab 		if (status < 0)
639259a7a23cSMauro Carvalho Chehab 			return status;
639359a7a23cSMauro Carvalho Chehab 
639459a7a23cSMauro Carvalho Chehab 		/* SCU c.o.c. */
6395d259a5eeSChristophe JAILLET 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
639659a7a23cSMauro Carvalho Chehab 		if (status < 0)
639759a7a23cSMauro Carvalho Chehab 			return status;
639859a7a23cSMauro Carvalho Chehab 
639959a7a23cSMauro Carvalho Chehab 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6400cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = scu_lvl + scu_coc;
640159a7a23cSMauro Carvalho Chehab 		else
6402cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = 0xffff;
640359a7a23cSMauro Carvalho Chehab 
640459a7a23cSMauro Carvalho Chehab 		/* Take RF gain into account */
6405cd7a67a4SMauro Carvalho Chehab 		total_gain += tuner_rf_gain;
640659a7a23cSMauro Carvalho Chehab 
640759a7a23cSMauro Carvalho Chehab 		/* clip output value */
6408cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level < rf_agc.min_output_level)
6409cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.min_output_level;
6410cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level > rf_agc.max_output_level)
6411cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.max_output_level;
641259a7a23cSMauro Carvalho Chehab 
6413cd7a67a4SMauro Carvalho Chehab 		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6414cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
641559a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6416cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_rf_gain)) *
6417cd7a67a4SMauro Carvalho Chehab 				((u32)(rf_agc.output_level - rf_agc.min_output_level))
6418cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
641959a7a23cSMauro Carvalho Chehab 		}
642059a7a23cSMauro Carvalho Chehab 	}
642159a7a23cSMauro Carvalho Chehab 
6422cd7a67a4SMauro Carvalho Chehab 	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
642359a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6424cd7a67a4SMauro Carvalho Chehab 				&if_agc.output_level);
642559a7a23cSMauro Carvalho Chehab 		if (status < 0)
642659a7a23cSMauro Carvalho Chehab 			return status;
642759a7a23cSMauro Carvalho Chehab 
642859a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6429cd7a67a4SMauro Carvalho Chehab 				&if_agc.top);
643059a7a23cSMauro Carvalho Chehab 		if (status < 0)
643159a7a23cSMauro Carvalho Chehab 			return status;
643259a7a23cSMauro Carvalho Chehab 
643359a7a23cSMauro Carvalho Chehab 		/* Take IF gain into account */
6434cd7a67a4SMauro Carvalho Chehab 		total_gain += (u32) tuner_if_gain;
643559a7a23cSMauro Carvalho Chehab 
643659a7a23cSMauro Carvalho Chehab 		/* clip output value */
6437cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level < if_agc.min_output_level)
6438cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.min_output_level;
6439cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level > if_agc.max_output_level)
6440cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.max_output_level;
644159a7a23cSMauro Carvalho Chehab 
6442cd7a67a4SMauro Carvalho Chehab 		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
6443cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
644459a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6445cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_if_gain)) *
6446cd7a67a4SMauro Carvalho Chehab 				((u32)(if_agc.output_level - if_agc.min_output_level))
6447cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
644859a7a23cSMauro Carvalho Chehab 		}
644959a7a23cSMauro Carvalho Chehab 	}
645059a7a23cSMauro Carvalho Chehab 
645159a7a23cSMauro Carvalho Chehab 	/*
645259a7a23cSMauro Carvalho Chehab 	 * Convert to 0..65535 scale.
645359a7a23cSMauro Carvalho Chehab 	 * If it can't be measured (AGC is disabled), just show 100%.
645459a7a23cSMauro Carvalho Chehab 	 */
6455cd7a67a4SMauro Carvalho Chehab 	if (total_gain > 0)
6456cd7a67a4SMauro Carvalho Chehab 		*strength = (65535UL * atten / total_gain / 100);
645759a7a23cSMauro Carvalho Chehab 	else
645859a7a23cSMauro Carvalho Chehab 		*strength = 65535;
645959a7a23cSMauro Carvalho Chehab 
646059a7a23cSMauro Carvalho Chehab 	return 0;
646159a7a23cSMauro Carvalho Chehab }
646259a7a23cSMauro Carvalho Chehab 
drxk_get_stats(struct dvb_frontend * fe)64638f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe)
64649a0bf528SMauro Carvalho Chehab {
64658f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
64669a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64678f3741e0SMauro Carvalho Chehab 	int status;
64689a0bf528SMauro Carvalho Chehab 	u32 stat;
64698f3741e0SMauro Carvalho Chehab 	u16 reg16;
64708f3741e0SMauro Carvalho Chehab 	u32 post_bit_count;
64718f3741e0SMauro Carvalho Chehab 	u32 post_bit_err_count;
64728f3741e0SMauro Carvalho Chehab 	u32 post_bit_error_scale;
64738f3741e0SMauro Carvalho Chehab 	u32 pre_bit_err_count;
64748f3741e0SMauro Carvalho Chehab 	u32 pre_bit_count;
64758f3741e0SMauro Carvalho Chehab 	u32 pkt_count;
64768f3741e0SMauro Carvalho Chehab 	u32 pkt_error_count;
647759a7a23cSMauro Carvalho Chehab 	s32 cnr;
64789a0bf528SMauro Carvalho Chehab 
6479cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
64809a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6481cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
64829a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64839a0bf528SMauro Carvalho Chehab 
64848f3741e0SMauro Carvalho Chehab 	/* get status */
64858f3741e0SMauro Carvalho Chehab 	state->fe_status = 0;
6486cd7a67a4SMauro Carvalho Chehab 	get_lock_status(state, &stat);
64879a0bf528SMauro Carvalho Chehab 	if (stat == MPEG_LOCK)
64888f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x1f;
64899a0bf528SMauro Carvalho Chehab 	if (stat == FEC_LOCK)
64908f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x0f;
64919a0bf528SMauro Carvalho Chehab 	if (stat == DEMOD_LOCK)
64928f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x07;
64938f3741e0SMauro Carvalho Chehab 
649459a7a23cSMauro Carvalho Chehab 	/*
649559a7a23cSMauro Carvalho Chehab 	 * Estimate signal strength from AGC
649659a7a23cSMauro Carvalho Chehab 	 */
649759a7a23cSMauro Carvalho Chehab 	get_strength(state, &c->strength.stat[0].uvalue);
649859a7a23cSMauro Carvalho Chehab 	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
649959a7a23cSMauro Carvalho Chehab 
650059a7a23cSMauro Carvalho Chehab 
65018f3741e0SMauro Carvalho Chehab 	if (stat >= DEMOD_LOCK) {
6502cd7a67a4SMauro Carvalho Chehab 		get_signal_to_noise(state, &cnr);
65038f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].svalue = cnr * 100;
65048f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
65058f3741e0SMauro Carvalho Chehab 	} else {
65068f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65078f3741e0SMauro Carvalho Chehab 	}
65088f3741e0SMauro Carvalho Chehab 
65098f3741e0SMauro Carvalho Chehab 	if (stat < FEC_LOCK) {
65108f3741e0SMauro Carvalho Chehab 		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65118f3741e0SMauro Carvalho Chehab 		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65128f3741e0SMauro Carvalho Chehab 		c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65138f3741e0SMauro Carvalho Chehab 		c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65148f3741e0SMauro Carvalho Chehab 		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65158f3741e0SMauro Carvalho Chehab 		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65168f3741e0SMauro Carvalho Chehab 		return 0;
65178f3741e0SMauro Carvalho Chehab 	}
65188f3741e0SMauro Carvalho Chehab 
65198f3741e0SMauro Carvalho Chehab 	/* Get post BER */
65208f3741e0SMauro Carvalho Chehab 
65218f3741e0SMauro Carvalho Chehab 	/* BER measurement is valid if at least FEC lock is achieved */
65228f3741e0SMauro Carvalho Chehab 
6523ab5060cdSMauro Carvalho Chehab 	/*
6524ab5060cdSMauro Carvalho Chehab 	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6525ab5060cdSMauro Carvalho Chehab 	 * written to set nr of symbols or bits over which to measure
6526ab5060cdSMauro Carvalho Chehab 	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6527ab5060cdSMauro Carvalho Chehab 	 */
65288f3741e0SMauro Carvalho Chehab 
65298f3741e0SMauro Carvalho Chehab 	/* Read registers for post/preViterbi BER calculation */
65308f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
65318f3741e0SMauro Carvalho Chehab 	if (status < 0)
65328f3741e0SMauro Carvalho Chehab 		goto error;
65338f3741e0SMauro Carvalho Chehab 	pre_bit_err_count = reg16;
65348f3741e0SMauro Carvalho Chehab 
65358f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
65368f3741e0SMauro Carvalho Chehab 	if (status < 0)
65378f3741e0SMauro Carvalho Chehab 		goto error;
65388f3741e0SMauro Carvalho Chehab 	pre_bit_count = reg16;
65398f3741e0SMauro Carvalho Chehab 
65408f3741e0SMauro Carvalho Chehab 	/* Number of bit-errors */
65418f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
65428f3741e0SMauro Carvalho Chehab 	if (status < 0)
65438f3741e0SMauro Carvalho Chehab 		goto error;
65448f3741e0SMauro Carvalho Chehab 	post_bit_err_count = reg16;
65458f3741e0SMauro Carvalho Chehab 
65468f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
65478f3741e0SMauro Carvalho Chehab 	if (status < 0)
65488f3741e0SMauro Carvalho Chehab 		goto error;
65498f3741e0SMauro Carvalho Chehab 	post_bit_error_scale = reg16;
65508f3741e0SMauro Carvalho Chehab 
65518f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
65528f3741e0SMauro Carvalho Chehab 	if (status < 0)
65538f3741e0SMauro Carvalho Chehab 		goto error;
65548f3741e0SMauro Carvalho Chehab 	pkt_count = reg16;
65558f3741e0SMauro Carvalho Chehab 
65568f3741e0SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
65578f3741e0SMauro Carvalho Chehab 	if (status < 0)
65588f3741e0SMauro Carvalho Chehab 		goto error;
65598f3741e0SMauro Carvalho Chehab 	pkt_error_count = reg16;
65608f3741e0SMauro Carvalho Chehab 	write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
65618f3741e0SMauro Carvalho Chehab 
65628f3741e0SMauro Carvalho Chehab 	post_bit_err_count *= post_bit_error_scale;
65638f3741e0SMauro Carvalho Chehab 
65648f3741e0SMauro Carvalho Chehab 	post_bit_count = pkt_count * 204 * 8;
65658f3741e0SMauro Carvalho Chehab 
65668f3741e0SMauro Carvalho Chehab 	/* Store the results */
65678f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
65688f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].uvalue += pkt_error_count;
65698f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].scale = FE_SCALE_COUNTER;
65708f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].uvalue += pkt_count;
65718f3741e0SMauro Carvalho Chehab 
65728f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
65738f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
65748f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
65758f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].uvalue += pre_bit_count;
65768f3741e0SMauro Carvalho Chehab 
65778f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
65788f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].uvalue += post_bit_err_count;
65798f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
65808f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].uvalue += post_bit_count;
65818f3741e0SMauro Carvalho Chehab 
65828f3741e0SMauro Carvalho Chehab error:
65838f3741e0SMauro Carvalho Chehab 	return status;
65848f3741e0SMauro Carvalho Chehab }
65858f3741e0SMauro Carvalho Chehab 
65868f3741e0SMauro Carvalho Chehab 
drxk_read_status(struct dvb_frontend * fe,enum fe_status * status)65870df289a2SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status)
65888f3741e0SMauro Carvalho Chehab {
65898f3741e0SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
65908f3741e0SMauro Carvalho Chehab 	int rc;
65918f3741e0SMauro Carvalho Chehab 
65928f3741e0SMauro Carvalho Chehab 	dprintk(1, "\n");
65938f3741e0SMauro Carvalho Chehab 
65948f3741e0SMauro Carvalho Chehab 	rc = drxk_get_stats(fe);
65958f3741e0SMauro Carvalho Chehab 	if (rc < 0)
65968f3741e0SMauro Carvalho Chehab 		return rc;
65978f3741e0SMauro Carvalho Chehab 
65988f3741e0SMauro Carvalho Chehab 	*status = state->fe_status;
65998f3741e0SMauro Carvalho Chehab 
66009a0bf528SMauro Carvalho Chehab 	return 0;
66019a0bf528SMauro Carvalho Chehab }
66029a0bf528SMauro Carvalho Chehab 
drxk_read_signal_strength(struct dvb_frontend * fe,u16 * strength)66039a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
66049a0bf528SMauro Carvalho Chehab 				     u16 *strength)
66059a0bf528SMauro Carvalho Chehab {
66069a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
6607340e7696SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
66089a0bf528SMauro Carvalho Chehab 
66099a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66109a0bf528SMauro Carvalho Chehab 
6611cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66129a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6613cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66149a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66159a0bf528SMauro Carvalho Chehab 
6616340e7696SMauro Carvalho Chehab 	*strength = c->strength.stat[0].uvalue;
66179a0bf528SMauro Carvalho Chehab 	return 0;
66189a0bf528SMauro Carvalho Chehab }
66199a0bf528SMauro Carvalho Chehab 
drxk_read_snr(struct dvb_frontend * fe,u16 * snr)66209a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
66219a0bf528SMauro Carvalho Chehab {
66229a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66239a0bf528SMauro Carvalho Chehab 	s32 snr2;
66249a0bf528SMauro Carvalho Chehab 
66259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66269a0bf528SMauro Carvalho Chehab 
6627cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66289a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6629cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66309a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66319a0bf528SMauro Carvalho Chehab 
6632cd7a67a4SMauro Carvalho Chehab 	get_signal_to_noise(state, &snr2);
66338f3741e0SMauro Carvalho Chehab 
66348f3741e0SMauro Carvalho Chehab 	/* No negative SNR, clip to zero */
66358f3741e0SMauro Carvalho Chehab 	if (snr2 < 0)
66368f3741e0SMauro Carvalho Chehab 		snr2 = 0;
66379a0bf528SMauro Carvalho Chehab 	*snr = snr2 & 0xffff;
66389a0bf528SMauro Carvalho Chehab 	return 0;
66399a0bf528SMauro Carvalho Chehab }
66409a0bf528SMauro Carvalho Chehab 
drxk_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)66419a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
66429a0bf528SMauro Carvalho Chehab {
66439a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
664420694e96SHans Verkuil 	u16 err = 0;
66459a0bf528SMauro Carvalho Chehab 
66469a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66479a0bf528SMauro Carvalho Chehab 
6648cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66499a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6650cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66519a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66529a0bf528SMauro Carvalho Chehab 
6653cd7a67a4SMauro Carvalho Chehab 	dvbtqam_get_acc_pkt_err(state, &err);
66549a0bf528SMauro Carvalho Chehab 	*ucblocks = (u32) err;
66559a0bf528SMauro Carvalho Chehab 	return 0;
66569a0bf528SMauro Carvalho Chehab }
66579a0bf528SMauro Carvalho Chehab 
drxk_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * sets)6658ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe,
6659ab5060cdSMauro Carvalho Chehab 				  struct dvb_frontend_tune_settings *sets)
66609a0bf528SMauro Carvalho Chehab {
66619a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66629a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
66639a0bf528SMauro Carvalho Chehab 
66649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66659a0bf528SMauro Carvalho Chehab 
6666cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66679a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6668cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66699a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66709a0bf528SMauro Carvalho Chehab 
66719a0bf528SMauro Carvalho Chehab 	switch (p->delivery_system) {
66729a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_A:
66739a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_C:
66749a0bf528SMauro Carvalho Chehab 	case SYS_DVBT:
66759a0bf528SMauro Carvalho Chehab 		sets->min_delay_ms = 3000;
66769a0bf528SMauro Carvalho Chehab 		sets->max_drift = 0;
66779a0bf528SMauro Carvalho Chehab 		sets->step_size = 0;
66789a0bf528SMauro Carvalho Chehab 		return 0;
66799a0bf528SMauro Carvalho Chehab 	default:
66809a0bf528SMauro Carvalho Chehab 		return -EINVAL;
66819a0bf528SMauro Carvalho Chehab 	}
66829a0bf528SMauro Carvalho Chehab }
66839a0bf528SMauro Carvalho Chehab 
6684bd336e63SMax Kellermann static const struct dvb_frontend_ops drxk_ops = {
66859a0bf528SMauro Carvalho Chehab 	/* .delsys will be filled dynamically */
66869a0bf528SMauro Carvalho Chehab 	.info = {
66879a0bf528SMauro Carvalho Chehab 		.name = "DRXK",
6688f1b1eabfSMauro Carvalho Chehab 		.frequency_min_hz =  47 * MHz,
6689f1b1eabfSMauro Carvalho Chehab 		.frequency_max_hz = 865 * MHz,
66909a0bf528SMauro Carvalho Chehab 		 /* For DVB-C */
66919a0bf528SMauro Carvalho Chehab 		.symbol_rate_min =   870000,
66929a0bf528SMauro Carvalho Chehab 		.symbol_rate_max = 11700000,
66939a0bf528SMauro Carvalho Chehab 		/* For DVB-T */
6694f1b1eabfSMauro Carvalho Chehab 		.frequency_stepsize_hz = 166667,
66959a0bf528SMauro Carvalho Chehab 
66969a0bf528SMauro Carvalho Chehab 		.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
66979a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
66989a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
66999a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
67009a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
67019a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
67029a0bf528SMauro Carvalho Chehab 	},
67039a0bf528SMauro Carvalho Chehab 
67049a0bf528SMauro Carvalho Chehab 	.release = drxk_release,
67059a0bf528SMauro Carvalho Chehab 	.sleep = drxk_sleep,
67069a0bf528SMauro Carvalho Chehab 	.i2c_gate_ctrl = drxk_gate_ctrl,
67079a0bf528SMauro Carvalho Chehab 
67089a0bf528SMauro Carvalho Chehab 	.set_frontend = drxk_set_parameters,
67099a0bf528SMauro Carvalho Chehab 	.get_tune_settings = drxk_get_tune_settings,
67109a0bf528SMauro Carvalho Chehab 
67119a0bf528SMauro Carvalho Chehab 	.read_status = drxk_read_status,
67129a0bf528SMauro Carvalho Chehab 	.read_signal_strength = drxk_read_signal_strength,
67139a0bf528SMauro Carvalho Chehab 	.read_snr = drxk_read_snr,
67149a0bf528SMauro Carvalho Chehab 	.read_ucblocks = drxk_read_ucblocks,
67159a0bf528SMauro Carvalho Chehab };
67169a0bf528SMauro Carvalho Chehab 
drxk_attach(const struct drxk_config * config,struct i2c_adapter * i2c)67179a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
67189a0bf528SMauro Carvalho Chehab 				 struct i2c_adapter *i2c)
67199a0bf528SMauro Carvalho Chehab {
67208f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *p;
67219a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = NULL;
67229a0bf528SMauro Carvalho Chehab 	u8 adr = config->adr;
67239a0bf528SMauro Carvalho Chehab 	int status;
67249a0bf528SMauro Carvalho Chehab 
67259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67269a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
67279a0bf528SMauro Carvalho Chehab 	if (!state)
67289a0bf528SMauro Carvalho Chehab 		return NULL;
67299a0bf528SMauro Carvalho Chehab 
67309a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
67319a0bf528SMauro Carvalho Chehab 	state->demod_address = adr;
67329a0bf528SMauro Carvalho Chehab 	state->single_master = config->single_master;
67339a0bf528SMauro Carvalho Chehab 	state->microcode_name = config->microcode_name;
67349a0bf528SMauro Carvalho Chehab 	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
67359a0bf528SMauro Carvalho Chehab 	state->no_i2c_bridge = config->no_i2c_bridge;
67369a0bf528SMauro Carvalho Chehab 	state->antenna_gpio = config->antenna_gpio;
67379a0bf528SMauro Carvalho Chehab 	state->antenna_dvbt = config->antenna_dvbt;
6738cd7a67a4SMauro Carvalho Chehab 	state->m_chunk_size = config->chunk_size;
67399a0bf528SMauro Carvalho Chehab 	state->enable_merr_cfg = config->enable_merr_cfg;
67409a0bf528SMauro Carvalho Chehab 
67419a0bf528SMauro Carvalho Chehab 	if (config->dynamic_clk) {
67425a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = false;
67435a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = false;
67449a0bf528SMauro Carvalho Chehab 	} else {
67455a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = true;
67465a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = true;
67479a0bf528SMauro Carvalho Chehab 	}
67489a0bf528SMauro Carvalho Chehab 
67499a0bf528SMauro Carvalho Chehab 
67509a0bf528SMauro Carvalho Chehab 	if (config->mpeg_out_clk_strength)
6751cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
67529a0bf528SMauro Carvalho Chehab 	else
6753cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = 0x06;
67549a0bf528SMauro Carvalho Chehab 
67559a0bf528SMauro Carvalho Chehab 	if (config->parallel_ts)
6756cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = true;
67579a0bf528SMauro Carvalho Chehab 	else
6758cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = false;
67599a0bf528SMauro Carvalho Chehab 
67609a0bf528SMauro Carvalho Chehab 	/* NOTE: as more UIO bits will be used, add them to the mask */
6761cd7a67a4SMauro Carvalho Chehab 	state->uio_mask = config->antenna_gpio;
67629a0bf528SMauro Carvalho Chehab 
67639a0bf528SMauro Carvalho Chehab 	/* Default gpio to DVB-C */
67649a0bf528SMauro Carvalho Chehab 	if (!state->antenna_dvbt && state->antenna_gpio)
6765cd7a67a4SMauro Carvalho Chehab 		state->m_gpio |= state->antenna_gpio;
67669a0bf528SMauro Carvalho Chehab 	else
6767cd7a67a4SMauro Carvalho Chehab 		state->m_gpio &= ~state->antenna_gpio;
67689a0bf528SMauro Carvalho Chehab 
67699a0bf528SMauro Carvalho Chehab 	mutex_init(&state->mutex);
67709a0bf528SMauro Carvalho Chehab 
67719a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
67729a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
67739a0bf528SMauro Carvalho Chehab 
67749a0bf528SMauro Carvalho Chehab 	init_state(state);
67759a0bf528SMauro Carvalho Chehab 
67769a0bf528SMauro Carvalho Chehab 	/* Load firmware and initialize DRX-K */
67779a0bf528SMauro Carvalho Chehab 	if (state->microcode_name) {
67788e30783bSMauro Carvalho Chehab 		const struct firmware *fw = NULL;
67798e30783bSMauro Carvalho Chehab 
67808e30783bSMauro Carvalho Chehab 		status = request_firmware(&fw, state->microcode_name,
67818e30783bSMauro Carvalho Chehab 					  state->i2c->dev.parent);
67828e30783bSMauro Carvalho Chehab 		if (status < 0)
67838e30783bSMauro Carvalho Chehab 			fw = NULL;
67848e30783bSMauro Carvalho Chehab 		load_firmware_cb(fw, state);
67859a0bf528SMauro Carvalho Chehab 	} else if (init_drxk(state) < 0)
67869a0bf528SMauro Carvalho Chehab 		goto error;
67879a0bf528SMauro Carvalho Chehab 
67888f3741e0SMauro Carvalho Chehab 
67898f3741e0SMauro Carvalho Chehab 	/* Initialize stats */
67908f3741e0SMauro Carvalho Chehab 	p = &state->frontend.dtv_property_cache;
67918f3741e0SMauro Carvalho Chehab 	p->strength.len = 1;
67928f3741e0SMauro Carvalho Chehab 	p->cnr.len = 1;
67938f3741e0SMauro Carvalho Chehab 	p->block_error.len = 1;
67948f3741e0SMauro Carvalho Chehab 	p->block_count.len = 1;
67958f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.len = 1;
67968f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.len = 1;
67978f3741e0SMauro Carvalho Chehab 	p->post_bit_error.len = 1;
67988f3741e0SMauro Carvalho Chehab 	p->post_bit_count.len = 1;
67998f3741e0SMauro Carvalho Chehab 
68008f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
68018f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68028f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68038f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68048f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68058f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68068f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68078f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68088f3741e0SMauro Carvalho Chehab 
68093a4398f5SMauro Carvalho Chehab 	pr_info("frontend initialized.\n");
68109a0bf528SMauro Carvalho Chehab 	return &state->frontend;
68119a0bf528SMauro Carvalho Chehab 
68129a0bf528SMauro Carvalho Chehab error:
68133a4398f5SMauro Carvalho Chehab 	pr_err("not found\n");
68149a0bf528SMauro Carvalho Chehab 	kfree(state);
68159a0bf528SMauro Carvalho Chehab 	return NULL;
68169a0bf528SMauro Carvalho Chehab }
6817*86495af1SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(drxk_attach);
68189a0bf528SMauro Carvalho Chehab 
68199a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
68209a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
68219a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6822