19a0bf528SMauro Carvalho Chehab /*
29a0bf528SMauro Carvalho Chehab  * drxk_hard: DRX-K DVB-C/T demodulator driver
39a0bf528SMauro Carvalho Chehab  *
49a0bf528SMauro Carvalho Chehab  * Copyright (C) 2010-2011 Digital Devices GmbH
59a0bf528SMauro Carvalho Chehab  *
69a0bf528SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or
79a0bf528SMauro Carvalho Chehab  * modify it under the terms of the GNU General Public License
89a0bf528SMauro Carvalho Chehab  * version 2 only, as published by the Free Software Foundation.
99a0bf528SMauro Carvalho Chehab  *
109a0bf528SMauro Carvalho Chehab  *
119a0bf528SMauro Carvalho Chehab  * This program is distributed in the hope that it will be useful,
129a0bf528SMauro Carvalho Chehab  * but WITHOUT ANY WARRANTY; without even the implied warranty of
139a0bf528SMauro Carvalho Chehab  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149a0bf528SMauro Carvalho Chehab  * GNU General Public License for more details.
159a0bf528SMauro Carvalho Chehab  *
169a0bf528SMauro Carvalho Chehab  *
179a0bf528SMauro Carvalho Chehab  * You should have received a copy of the GNU General Public License
189a0bf528SMauro Carvalho Chehab  * along with this program; if not, write to the Free Software
199a0bf528SMauro Carvalho Chehab  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
209a0bf528SMauro Carvalho Chehab  * 02110-1301, USA
219a0bf528SMauro Carvalho Chehab  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
229a0bf528SMauro Carvalho Chehab  */
239a0bf528SMauro Carvalho Chehab 
243a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
253a4398f5SMauro Carvalho Chehab 
269a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
279a0bf528SMauro Carvalho Chehab #include <linux/module.h>
289a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
299a0bf528SMauro Carvalho Chehab #include <linux/init.h>
309a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
319a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
329a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
339a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
349a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
359a0bf528SMauro Carvalho Chehab 
369a0bf528SMauro Carvalho Chehab #include "dvb_frontend.h"
379a0bf528SMauro Carvalho Chehab #include "drxk.h"
389a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
39b5e9eb6fSMauro Carvalho Chehab #include "dvb_math.h"
409a0bf528SMauro Carvalho Chehab 
41cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
42cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state);
43cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
44cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
45cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
46cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode);
47cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
48cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset);
49cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
50cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
51cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state);
52cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
53cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset);
54cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
55cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
56cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state);
57cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state);
589a0bf528SMauro Carvalho Chehab 
59cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state)
609a0bf528SMauro Carvalho Chehab {
61cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_DVBT;
629a0bf528SMauro Carvalho Chehab }
639a0bf528SMauro Carvalho Chehab 
64cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state)
659a0bf528SMauro Carvalho Chehab {
66cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_QAM_ITU_A ||
67cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_B ||
68cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_C;
699a0bf528SMauro Carvalho Chehab }
709a0bf528SMauro Carvalho Chehab 
719a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
729a0bf528SMauro Carvalho Chehab 
739a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
749a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
759a0bf528SMauro Carvalho Chehab 
769a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83  165
779a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93  250
789a0bf528SMauro Carvalho Chehab 
799a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
809a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
819a0bf528SMauro Carvalho Chehab #endif
829a0bf528SMauro Carvalho Chehab 
839a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
849a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
859a0bf528SMauro Carvalho Chehab #endif
869a0bf528SMauro Carvalho Chehab 
879a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
889a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
899a0bf528SMauro Carvalho Chehab 
909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
919a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV   4
929a0bf528SMauro Carvalho Chehab #endif
939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
949a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV   6
959a0bf528SMauro Carvalho Chehab #endif
969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
979a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV   7
989a0bf528SMauro Carvalho Chehab #endif
999a0bf528SMauro Carvalho Chehab 
1009a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
1019a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM   3
1029a0bf528SMauro Carvalho Chehab #endif
1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
1049a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM   4
1059a0bf528SMauro Carvalho Chehab #endif
1069a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
1079a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM   7
1089a0bf528SMauro Carvalho Chehab #endif
1099a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
1109a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
1119a0bf528SMauro Carvalho Chehab #endif
1129a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
1139a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
1149a0bf528SMauro Carvalho Chehab #endif
1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1169a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
1179a0bf528SMauro Carvalho Chehab #endif
1189a0bf528SMauro Carvalho Chehab 
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1209a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab 
1239a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1249a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
1259a0bf528SMauro Carvalho Chehab #endif
1269a0bf528SMauro Carvalho Chehab 
1279a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1289a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
1299a0bf528SMauro Carvalho Chehab #endif
1309a0bf528SMauro Carvalho Chehab 
1319a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1329a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
1339a0bf528SMauro Carvalho Chehab #endif
1349a0bf528SMauro Carvalho Chehab 
1359a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1369a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
1379a0bf528SMauro Carvalho Chehab #endif
1389a0bf528SMauro Carvalho Chehab 
1399a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
1409a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
1419a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
1429a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG      24
1439a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
1449a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
1459a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM      48
1469a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE        0
1479a0bf528SMauro Carvalho Chehab 
1489a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT                100
1499a0bf528SMauro Carvalho Chehab 
1509a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS      2
1519a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE     6
1529a0bf528SMauro Carvalho Chehab 
1539a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS      28
1549a0bf528SMauro Carvalho Chehab 
1559a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1569a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
1579a0bf528SMauro Carvalho Chehab #endif
1589a0bf528SMauro Carvalho Chehab 
1599a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
1609a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
1619a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
1629a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
1639a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
1649a0bf528SMauro Carvalho Chehab 
1659a0bf528SMauro Carvalho Chehab static unsigned int debug;
1669a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1679a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1689a0bf528SMauro Carvalho Chehab 
1699a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do {			\
1709a0bf528SMauro Carvalho Chehab if (debug >= level)						\
1710fb220f2SMauro Carvalho Chehab 	pr_debug(fmt, ##arg);					\
1729a0bf528SMauro Carvalho Chehab } while (0)
1739a0bf528SMauro Carvalho Chehab 
1749a0bf528SMauro Carvalho Chehab 
1759a0bf528SMauro Carvalho Chehab static inline u32 MulDiv32(u32 a, u32 b, u32 c)
1769a0bf528SMauro Carvalho Chehab {
1779a0bf528SMauro Carvalho Chehab 	u64 tmp64;
1789a0bf528SMauro Carvalho Chehab 
1799a0bf528SMauro Carvalho Chehab 	tmp64 = (u64) a * (u64) b;
1809a0bf528SMauro Carvalho Chehab 	do_div(tmp64, c);
1819a0bf528SMauro Carvalho Chehab 
1829a0bf528SMauro Carvalho Chehab 	return (u32) tmp64;
1839a0bf528SMauro Carvalho Chehab }
1849a0bf528SMauro Carvalho Chehab 
185ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c)
1869a0bf528SMauro Carvalho Chehab {
1879a0bf528SMauro Carvalho Chehab 	int i = 0;
1889a0bf528SMauro Carvalho Chehab 	u32 Q1 = 0;
1899a0bf528SMauro Carvalho Chehab 	u32 R0 = 0;
1909a0bf528SMauro Carvalho Chehab 
1919a0bf528SMauro Carvalho Chehab 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
192ab5060cdSMauro Carvalho Chehab 	Q1 = a / c;		/*
193ab5060cdSMauro Carvalho Chehab 				 * integer part, only the 4 least significant
194ab5060cdSMauro Carvalho Chehab 				 * bits will be visible in the result
195ab5060cdSMauro Carvalho Chehab 				 */
1969a0bf528SMauro Carvalho Chehab 
1979a0bf528SMauro Carvalho Chehab 	/* division using radix 16, 7 nibbles in the result */
1989a0bf528SMauro Carvalho Chehab 	for (i = 0; i < 7; i++) {
1999a0bf528SMauro Carvalho Chehab 		Q1 = (Q1 << 4) | (R0 / c);
2009a0bf528SMauro Carvalho Chehab 		R0 = (R0 % c) << 4;
2019a0bf528SMauro Carvalho Chehab 	}
2029a0bf528SMauro Carvalho Chehab 	/* rounding */
2039a0bf528SMauro Carvalho Chehab 	if ((R0 >> 3) >= c)
2049a0bf528SMauro Carvalho Chehab 		Q1++;
2059a0bf528SMauro Carvalho Chehab 
2069a0bf528SMauro Carvalho Chehab 	return Q1;
2079a0bf528SMauro Carvalho Chehab }
2089a0bf528SMauro Carvalho Chehab 
209b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value)
2109a0bf528SMauro Carvalho Chehab {
211b5e9eb6fSMauro Carvalho Chehab 	return (100L * intlog10(value)) >> 24;
2129a0bf528SMauro Carvalho Chehab }
2139a0bf528SMauro Carvalho Chehab 
2149a0bf528SMauro Carvalho Chehab /****************************************************************************/
2159a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
2169a0bf528SMauro Carvalho Chehab /****************************************************************************/
2179a0bf528SMauro Carvalho Chehab 
2189a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
2199a0bf528SMauro Carvalho Chehab {
2209a0bf528SMauro Carvalho Chehab 	i2c_lock_adapter(state->i2c);
2219a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = true;
2229a0bf528SMauro Carvalho Chehab 
2239a0bf528SMauro Carvalho Chehab 	return 0;
2249a0bf528SMauro Carvalho Chehab }
2259a0bf528SMauro Carvalho Chehab 
2269a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
2279a0bf528SMauro Carvalho Chehab {
2289a0bf528SMauro Carvalho Chehab 	if (!state->drxk_i2c_exclusive_lock)
2299a0bf528SMauro Carvalho Chehab 		return;
2309a0bf528SMauro Carvalho Chehab 
2319a0bf528SMauro Carvalho Chehab 	i2c_unlock_adapter(state->i2c);
2329a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = false;
2339a0bf528SMauro Carvalho Chehab }
2349a0bf528SMauro Carvalho Chehab 
2359a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
2369a0bf528SMauro Carvalho Chehab 			     unsigned len)
2379a0bf528SMauro Carvalho Chehab {
2389a0bf528SMauro Carvalho Chehab 	if (state->drxk_i2c_exclusive_lock)
2399a0bf528SMauro Carvalho Chehab 		return __i2c_transfer(state->i2c, msgs, len);
2409a0bf528SMauro Carvalho Chehab 	else
2419a0bf528SMauro Carvalho Chehab 		return i2c_transfer(state->i2c, msgs, len);
2429a0bf528SMauro Carvalho Chehab }
2439a0bf528SMauro Carvalho Chehab 
2449a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
2459a0bf528SMauro Carvalho Chehab {
2469a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
2479a0bf528SMauro Carvalho Chehab 				    .buf = val, .len = 1}
2489a0bf528SMauro Carvalho Chehab 	};
2499a0bf528SMauro Carvalho Chehab 
2509a0bf528SMauro Carvalho Chehab 	return drxk_i2c_transfer(state, msgs, 1);
2519a0bf528SMauro Carvalho Chehab }
2529a0bf528SMauro Carvalho Chehab 
2539a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
2549a0bf528SMauro Carvalho Chehab {
2559a0bf528SMauro Carvalho Chehab 	int status;
2569a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg = {
2579a0bf528SMauro Carvalho Chehab 	    .addr = adr, .flags = 0, .buf = data, .len = len };
2589a0bf528SMauro Carvalho Chehab 
2599a0bf528SMauro Carvalho Chehab 	dprintk(3, ":");
2609a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2619a0bf528SMauro Carvalho Chehab 		int i;
2629a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
2630fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", data[i]);
2640fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
2659a0bf528SMauro Carvalho Chehab 	}
2669a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, &msg, 1);
2679a0bf528SMauro Carvalho Chehab 	if (status >= 0 && status != 1)
2689a0bf528SMauro Carvalho Chehab 		status = -EIO;
2699a0bf528SMauro Carvalho Chehab 
2709a0bf528SMauro Carvalho Chehab 	if (status < 0)
2713a4398f5SMauro Carvalho Chehab 		pr_err("i2c write error at addr 0x%02x\n", adr);
2729a0bf528SMauro Carvalho Chehab 
2739a0bf528SMauro Carvalho Chehab 	return status;
2749a0bf528SMauro Carvalho Chehab }
2759a0bf528SMauro Carvalho Chehab 
2769a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
2779a0bf528SMauro Carvalho Chehab 		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
2789a0bf528SMauro Carvalho Chehab {
2799a0bf528SMauro Carvalho Chehab 	int status;
2809a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[2] = {
2819a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = 0,
2829a0bf528SMauro Carvalho Chehab 				    .buf = msg, .len = len},
2839a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = I2C_M_RD,
2849a0bf528SMauro Carvalho Chehab 		 .buf = answ, .len = alen}
2859a0bf528SMauro Carvalho Chehab 	};
2869a0bf528SMauro Carvalho Chehab 
2879a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, msgs, 2);
2889a0bf528SMauro Carvalho Chehab 	if (status != 2) {
2899a0bf528SMauro Carvalho Chehab 		if (debug > 2)
2900fb220f2SMauro Carvalho Chehab 			pr_cont(": ERROR!\n");
2919a0bf528SMauro Carvalho Chehab 		if (status >= 0)
2929a0bf528SMauro Carvalho Chehab 			status = -EIO;
2939a0bf528SMauro Carvalho Chehab 
2943a4398f5SMauro Carvalho Chehab 		pr_err("i2c read error at addr 0x%02x\n", adr);
2959a0bf528SMauro Carvalho Chehab 		return status;
2969a0bf528SMauro Carvalho Chehab 	}
2979a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2989a0bf528SMauro Carvalho Chehab 		int i;
2999a0bf528SMauro Carvalho Chehab 		dprintk(2, ": read from");
3009a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
3010fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", msg[i]);
3020fb220f2SMauro Carvalho Chehab 		pr_cont(", value = ");
3039a0bf528SMauro Carvalho Chehab 		for (i = 0; i < alen; i++)
3040fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", answ[i]);
3050fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
3069a0bf528SMauro Carvalho Chehab 	}
3079a0bf528SMauro Carvalho Chehab 	return 0;
3089a0bf528SMauro Carvalho Chehab }
3099a0bf528SMauro Carvalho Chehab 
3109a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
3119a0bf528SMauro Carvalho Chehab {
3129a0bf528SMauro Carvalho Chehab 	int status;
3139a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[2], len;
3149a0bf528SMauro Carvalho Chehab 
3159a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3169a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3179a0bf528SMauro Carvalho Chehab 
3189a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3199a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3209a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3219a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3229a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3239a0bf528SMauro Carvalho Chehab 		len = 4;
3249a0bf528SMauro Carvalho Chehab 	} else {
3259a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3269a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3279a0bf528SMauro Carvalho Chehab 		len = 2;
3289a0bf528SMauro Carvalho Chehab 	}
3299a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3309a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 2);
3319a0bf528SMauro Carvalho Chehab 	if (status < 0)
3329a0bf528SMauro Carvalho Chehab 		return status;
3339a0bf528SMauro Carvalho Chehab 	if (data)
3349a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8);
3359a0bf528SMauro Carvalho Chehab 
3369a0bf528SMauro Carvalho Chehab 	return 0;
3379a0bf528SMauro Carvalho Chehab }
3389a0bf528SMauro Carvalho Chehab 
3399a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
3409a0bf528SMauro Carvalho Chehab {
3419a0bf528SMauro Carvalho Chehab 	return read16_flags(state, reg, data, 0);
3429a0bf528SMauro Carvalho Chehab }
3439a0bf528SMauro Carvalho Chehab 
3449a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
3459a0bf528SMauro Carvalho Chehab {
3469a0bf528SMauro Carvalho Chehab 	int status;
3479a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[4], len;
3489a0bf528SMauro Carvalho Chehab 
3499a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3509a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3519a0bf528SMauro Carvalho Chehab 
3529a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3539a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3549a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3559a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3569a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3579a0bf528SMauro Carvalho Chehab 		len = 4;
3589a0bf528SMauro Carvalho Chehab 	} else {
3599a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3609a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3619a0bf528SMauro Carvalho Chehab 		len = 2;
3629a0bf528SMauro Carvalho Chehab 	}
3639a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3649a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 4);
3659a0bf528SMauro Carvalho Chehab 	if (status < 0)
3669a0bf528SMauro Carvalho Chehab 		return status;
3679a0bf528SMauro Carvalho Chehab 	if (data)
3689a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8) |
3699a0bf528SMauro Carvalho Chehab 		    (mm2[2] << 16) | (mm2[3] << 24);
3709a0bf528SMauro Carvalho Chehab 
3719a0bf528SMauro Carvalho Chehab 	return 0;
3729a0bf528SMauro Carvalho Chehab }
3739a0bf528SMauro Carvalho Chehab 
3749a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
3759a0bf528SMauro Carvalho Chehab {
3769a0bf528SMauro Carvalho Chehab 	return read32_flags(state, reg, data, 0);
3779a0bf528SMauro Carvalho Chehab }
3789a0bf528SMauro Carvalho Chehab 
3799a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
3809a0bf528SMauro Carvalho Chehab {
3819a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[6], len;
3829a0bf528SMauro Carvalho Chehab 
3839a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3849a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3859a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3869a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3879a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3889a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3899a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3909a0bf528SMauro Carvalho Chehab 		len = 4;
3919a0bf528SMauro Carvalho Chehab 	} else {
3929a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3939a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3949a0bf528SMauro Carvalho Chehab 		len = 2;
3959a0bf528SMauro Carvalho Chehab 	}
3969a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3979a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
3989a0bf528SMauro Carvalho Chehab 
3999a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
4009a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 2);
4019a0bf528SMauro Carvalho Chehab }
4029a0bf528SMauro Carvalho Chehab 
4039a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
4049a0bf528SMauro Carvalho Chehab {
4059a0bf528SMauro Carvalho Chehab 	return write16_flags(state, reg, data, 0);
4069a0bf528SMauro Carvalho Chehab }
4079a0bf528SMauro Carvalho Chehab 
4089a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
4099a0bf528SMauro Carvalho Chehab {
4109a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[8], len;
4119a0bf528SMauro Carvalho Chehab 
4129a0bf528SMauro Carvalho Chehab 	if (state->single_master)
4139a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
4149a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
4159a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
4169a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
4179a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
4189a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
4199a0bf528SMauro Carvalho Chehab 		len = 4;
4209a0bf528SMauro Carvalho Chehab 	} else {
4219a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
4229a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
4239a0bf528SMauro Carvalho Chehab 		len = 2;
4249a0bf528SMauro Carvalho Chehab 	}
4259a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
4269a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
4279a0bf528SMauro Carvalho Chehab 	mm[len + 2] = (data >> 16) & 0xff;
4289a0bf528SMauro Carvalho Chehab 	mm[len + 3] = (data >> 24) & 0xff;
4299a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
4309a0bf528SMauro Carvalho Chehab 
4319a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 4);
4329a0bf528SMauro Carvalho Chehab }
4339a0bf528SMauro Carvalho Chehab 
4349a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
4359a0bf528SMauro Carvalho Chehab {
4369a0bf528SMauro Carvalho Chehab 	return write32_flags(state, reg, data, 0);
4379a0bf528SMauro Carvalho Chehab }
4389a0bf528SMauro Carvalho Chehab 
439cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address,
440cd7a67a4SMauro Carvalho Chehab 		      const int block_size, const u8 p_block[])
4419a0bf528SMauro Carvalho Chehab {
442cd7a67a4SMauro Carvalho Chehab 	int status = 0, blk_size = block_size;
443cd7a67a4SMauro Carvalho Chehab 	u8 flags = 0;
4449a0bf528SMauro Carvalho Chehab 
4459a0bf528SMauro Carvalho Chehab 	if (state->single_master)
446cd7a67a4SMauro Carvalho Chehab 		flags |= 0xC0;
4479a0bf528SMauro Carvalho Chehab 
448cd7a67a4SMauro Carvalho Chehab 	while (blk_size > 0) {
449cd7a67a4SMauro Carvalho Chehab 		int chunk = blk_size > state->m_chunk_size ?
450cd7a67a4SMauro Carvalho Chehab 		    state->m_chunk_size : blk_size;
451cd7a67a4SMauro Carvalho Chehab 		u8 *adr_buf = &state->chunk[0];
452cd7a67a4SMauro Carvalho Chehab 		u32 adr_length = 0;
4539a0bf528SMauro Carvalho Chehab 
454cd7a67a4SMauro Carvalho Chehab 		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
455cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
456cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = ((address >> 16) & 0xFF);
457cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] = ((address >> 24) & 0xFF);
458cd7a67a4SMauro Carvalho Chehab 			adr_buf[3] = ((address >> 7) & 0xFF);
459cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] |= flags;
460cd7a67a4SMauro Carvalho Chehab 			adr_length = 4;
461cd7a67a4SMauro Carvalho Chehab 			if (chunk == state->m_chunk_size)
462cd7a67a4SMauro Carvalho Chehab 				chunk -= 2;
4639a0bf528SMauro Carvalho Chehab 		} else {
464cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = ((address << 1) & 0xFF);
465cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = (((address >> 16) & 0x0F) |
466cd7a67a4SMauro Carvalho Chehab 				     ((address >> 18) & 0xF0));
467cd7a67a4SMauro Carvalho Chehab 			adr_length = 2;
4689a0bf528SMauro Carvalho Chehab 		}
469cd7a67a4SMauro Carvalho Chehab 		memcpy(&state->chunk[adr_length], p_block, chunk);
470cd7a67a4SMauro Carvalho Chehab 		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
4719a0bf528SMauro Carvalho Chehab 		if (debug > 1) {
4729a0bf528SMauro Carvalho Chehab 			int i;
473cd7a67a4SMauro Carvalho Chehab 			if (p_block)
474cd7a67a4SMauro Carvalho Chehab 				for (i = 0; i < chunk; i++)
4750fb220f2SMauro Carvalho Chehab 					pr_cont(" %02x", p_block[i]);
4760fb220f2SMauro Carvalho Chehab 			pr_cont("\n");
4779a0bf528SMauro Carvalho Chehab 		}
4789a0bf528SMauro Carvalho Chehab 		status = i2c_write(state, state->demod_address,
479cd7a67a4SMauro Carvalho Chehab 				   &state->chunk[0], chunk + adr_length);
4809a0bf528SMauro Carvalho Chehab 		if (status < 0) {
4813a4398f5SMauro Carvalho Chehab 			pr_err("%s: i2c write error at addr 0x%02x\n",
482cd7a67a4SMauro Carvalho Chehab 			       __func__, address);
4839a0bf528SMauro Carvalho Chehab 			break;
4849a0bf528SMauro Carvalho Chehab 		}
485cd7a67a4SMauro Carvalho Chehab 		p_block += chunk;
486cd7a67a4SMauro Carvalho Chehab 		address += (chunk >> 1);
487cd7a67a4SMauro Carvalho Chehab 		blk_size -= chunk;
4889a0bf528SMauro Carvalho Chehab 	}
4899a0bf528SMauro Carvalho Chehab 	return status;
4909a0bf528SMauro Carvalho Chehab }
4919a0bf528SMauro Carvalho Chehab 
4929a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
4939a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
4949a0bf528SMauro Carvalho Chehab #endif
4959a0bf528SMauro Carvalho Chehab 
496cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state)
4979a0bf528SMauro Carvalho Chehab {
4989a0bf528SMauro Carvalho Chehab 	int status;
4999a0bf528SMauro Carvalho Chehab 	u8 data = 0;
500cd7a67a4SMauro Carvalho Chehab 	u16 retry_count = 0;
5019a0bf528SMauro Carvalho Chehab 
5029a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5039a0bf528SMauro Carvalho Chehab 
5049a0bf528SMauro Carvalho Chehab 	status = i2c_read1(state, state->demod_address, &data);
5059a0bf528SMauro Carvalho Chehab 	if (status < 0) {
5069a0bf528SMauro Carvalho Chehab 		do {
5079a0bf528SMauro Carvalho Chehab 			data = 0;
5089a0bf528SMauro Carvalho Chehab 			status = i2c_write(state, state->demod_address,
5099a0bf528SMauro Carvalho Chehab 					   &data, 1);
510b72852baSMauro Carvalho Chehab 			usleep_range(10000, 11000);
511cd7a67a4SMauro Carvalho Chehab 			retry_count++;
5129a0bf528SMauro Carvalho Chehab 			if (status < 0)
5139a0bf528SMauro Carvalho Chehab 				continue;
5149a0bf528SMauro Carvalho Chehab 			status = i2c_read1(state, state->demod_address,
5159a0bf528SMauro Carvalho Chehab 					   &data);
5169a0bf528SMauro Carvalho Chehab 		} while (status < 0 &&
517cd7a67a4SMauro Carvalho Chehab 			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
518cd7a67a4SMauro Carvalho Chehab 		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
5199a0bf528SMauro Carvalho Chehab 			goto error;
5209a0bf528SMauro Carvalho Chehab 	}
5219a0bf528SMauro Carvalho Chehab 
5229a0bf528SMauro Carvalho Chehab 	/* Make sure all clk domains are active */
5239a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
5249a0bf528SMauro Carvalho Chehab 	if (status < 0)
5259a0bf528SMauro Carvalho Chehab 		goto error;
5269a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5279a0bf528SMauro Carvalho Chehab 	if (status < 0)
5289a0bf528SMauro Carvalho Chehab 		goto error;
5299a0bf528SMauro Carvalho Chehab 	/* Enable pll lock tests */
5309a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PLL_LOCK__A, 1);
5319a0bf528SMauro Carvalho Chehab 	if (status < 0)
5329a0bf528SMauro Carvalho Chehab 		goto error;
5339a0bf528SMauro Carvalho Chehab 
534cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_UP;
5359a0bf528SMauro Carvalho Chehab 
5369a0bf528SMauro Carvalho Chehab error:
5379a0bf528SMauro Carvalho Chehab 	if (status < 0)
5383a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
5399a0bf528SMauro Carvalho Chehab 
5409a0bf528SMauro Carvalho Chehab 	return status;
5419a0bf528SMauro Carvalho Chehab }
5429a0bf528SMauro Carvalho Chehab 
5439a0bf528SMauro Carvalho Chehab 
5449a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
5459a0bf528SMauro Carvalho Chehab {
5469a0bf528SMauro Carvalho Chehab 	/*
5479a0bf528SMauro Carvalho Chehab 	 * FIXME: most (all?) of the values bellow should be moved into
5489a0bf528SMauro Carvalho Chehab 	 * struct drxk_config, as they are probably board-specific
5499a0bf528SMauro Carvalho Chehab 	 */
550cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
551cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_output_level = 0;
552cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_min_level = 0;
553cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_max_level = 0x7FFF;
554cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_speed = 3;
5559a0bf528SMauro Carvalho Chehab 
556cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
557cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_output_level = 0;
558cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_min_level = 0;
559cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
560cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_speed = 3;
561cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_top = 9500;
562cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_cut_off_current = 4000;
5639a0bf528SMauro Carvalho Chehab 
564cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
565cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_output_level = 0;
566cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_min_level = 0;
567cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_max_level = 0;
568cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_speed = 3;
5699a0bf528SMauro Carvalho Chehab 
570cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
571cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_output_level = 0;
572cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_min_level = 0;
573cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_max_level = 0;
574cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_top = 9500;
575cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_cut_off_current = 4000;
576cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_speed = 3;
5779a0bf528SMauro Carvalho Chehab 
5789a0bf528SMauro Carvalho Chehab 	u32 ulQual83 = DEFAULT_MER_83;
5799a0bf528SMauro Carvalho Chehab 	u32 ulQual93 = DEFAULT_MER_93;
5809a0bf528SMauro Carvalho Chehab 
581cd7a67a4SMauro Carvalho Chehab 	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
582cd7a67a4SMauro Carvalho Chehab 	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
5839a0bf528SMauro Carvalho Chehab 
5849a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
5859a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_mode output mode is drive always */
5869a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
587cd7a67a4SMauro Carvalho Chehab 	u32 ul_gpio_cfg = 0x0113;
588cd7a67a4SMauro Carvalho Chehab 	u32 ul_invert_ts_clock = 0;
589cd7a67a4SMauro Carvalho Chehab 	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
590cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbt_bitrate = 50000000;
591cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
5929a0bf528SMauro Carvalho Chehab 
593cd7a67a4SMauro Carvalho Chehab 	u32 ul_insert_rs_byte = 0;
5949a0bf528SMauro Carvalho Chehab 
595cd7a67a4SMauro Carvalho Chehab 	u32 ul_rf_mirror = 1;
596cd7a67a4SMauro Carvalho Chehab 	u32 ul_power_down = 0;
5979a0bf528SMauro Carvalho Chehab 
5989a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5999a0bf528SMauro Carvalho Chehab 
600cd7a67a4SMauro Carvalho Chehab 	state->m_has_lna = false;
601cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbt = false;
602cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbc = false;
603cd7a67a4SMauro Carvalho Chehab 	state->m_has_atv = false;
604cd7a67a4SMauro Carvalho Chehab 	state->m_has_oob = false;
605cd7a67a4SMauro Carvalho Chehab 	state->m_has_audio = false;
6069a0bf528SMauro Carvalho Chehab 
607cd7a67a4SMauro Carvalho Chehab 	if (!state->m_chunk_size)
608cd7a67a4SMauro Carvalho Chehab 		state->m_chunk_size = 124;
6099a0bf528SMauro Carvalho Chehab 
610cd7a67a4SMauro Carvalho Chehab 	state->m_osc_clock_freq = 0;
611cd7a67a4SMauro Carvalho Chehab 	state->m_smart_ant_inverted = false;
612cd7a67a4SMauro Carvalho Chehab 	state->m_b_p_down_open_bridge = false;
6139a0bf528SMauro Carvalho Chehab 
6149a0bf528SMauro Carvalho Chehab 	/* real system clock frequency in kHz */
615cd7a67a4SMauro Carvalho Chehab 	state->m_sys_clock_freq = 151875;
6169a0bf528SMauro Carvalho Chehab 	/* Timing div, 250ns/Psys */
6179a0bf528SMauro Carvalho Chehab 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
618cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
6199a0bf528SMauro Carvalho Chehab 				   HI_I2C_DELAY) / 1000;
6209a0bf528SMauro Carvalho Chehab 	/* Clipping */
621cd7a67a4SMauro Carvalho Chehab 	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
622cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
623cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
6249a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
625cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
6269a0bf528SMauro Carvalho Chehab 
627cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = (ul_power_down != 0);
6289a0bf528SMauro Carvalho Chehab 
629cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_a3_patch_code = false;
6309a0bf528SMauro Carvalho Chehab 
6319a0bf528SMauro Carvalho Chehab 	/* Init AGC and PGA parameters */
6329a0bf528SMauro Carvalho Chehab 	/* VSB IF */
633949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
634949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
635949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
636949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
637949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
638cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pga_cfg = 140;
6399a0bf528SMauro Carvalho Chehab 
6409a0bf528SMauro Carvalho Chehab 	/* VSB RF */
641949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
642949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
643949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
644949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
645949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
646949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
647949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
648cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.reference = 0x07;
649cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
6509a0bf528SMauro Carvalho Chehab 
6519a0bf528SMauro Carvalho Chehab 	state->m_Quality83percent = DEFAULT_MER_83;
6529a0bf528SMauro Carvalho Chehab 	state->m_Quality93percent = DEFAULT_MER_93;
6539a0bf528SMauro Carvalho Chehab 	if (ulQual93 <= 500 && ulQual83 < ulQual93) {
6549a0bf528SMauro Carvalho Chehab 		state->m_Quality83percent = ulQual83;
6559a0bf528SMauro Carvalho Chehab 		state->m_Quality93percent = ulQual93;
6569a0bf528SMauro Carvalho Chehab 	}
6579a0bf528SMauro Carvalho Chehab 
6589a0bf528SMauro Carvalho Chehab 	/* ATV IF */
659949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
660949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
661949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
662949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
663949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
6649a0bf528SMauro Carvalho Chehab 
6659a0bf528SMauro Carvalho Chehab 	/* ATV RF */
666949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
667949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
668949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
669949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
670949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
671949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
672949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
673cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.reference = 0x04;
674cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.use_pre_saw = true;
6759a0bf528SMauro Carvalho Chehab 
6769a0bf528SMauro Carvalho Chehab 
6779a0bf528SMauro Carvalho Chehab 	/* DVBT RF */
678cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
679cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.output_level = 0;
680cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
681cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
682cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.top = 0x2100;
683cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
684cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.speed = 1;
6859a0bf528SMauro Carvalho Chehab 
6869a0bf528SMauro Carvalho Chehab 
6879a0bf528SMauro Carvalho Chehab 	/* DVBT IF */
688cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
689cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.output_level = 0;
690cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.min_output_level = 0;
691cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
692cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.top = 13424;
693cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
694cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.speed = 3;
695cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
696cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
6979a0bf528SMauro Carvalho Chehab 	/* state->m_dvbtPgaCfg = 140; */
6989a0bf528SMauro Carvalho Chehab 
699cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.reference = 4;
700cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
7019a0bf528SMauro Carvalho Chehab 
7029a0bf528SMauro Carvalho Chehab 	/* QAM RF */
703cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
704cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.output_level = 0;
705cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.min_output_level = 6023;
706cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.max_output_level = 27000;
707cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.top = 0x2380;
708cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
709cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.speed = 3;
7109a0bf528SMauro Carvalho Chehab 
7119a0bf528SMauro Carvalho Chehab 	/* QAM IF */
712cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
713cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.output_level = 0;
714cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.min_output_level = 0;
715cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.max_output_level = 9000;
716cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.top = 0x0511;
717cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.cut_off_current = 0;
718cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.speed = 3;
719cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
720cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
7219a0bf528SMauro Carvalho Chehab 
722cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pga_cfg = 140;
723cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.reference = 4;
724cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.use_pre_saw = false;
7259a0bf528SMauro Carvalho Chehab 
726cd7a67a4SMauro Carvalho Chehab 	state->m_operation_mode = OM_NONE;
727cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_state = DRXK_UNINITIALIZED;
7289a0bf528SMauro Carvalho Chehab 
7299a0bf528SMauro Carvalho Chehab 	/* MPEG output configuration */
730cd7a67a4SMauro Carvalho Chehab 	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG ouput */
731cd7a67a4SMauro Carvalho Chehab 	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
732cd7a67a4SMauro Carvalho Chehab 	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
733cd7a67a4SMauro Carvalho Chehab 	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
734cd7a67a4SMauro Carvalho Chehab 	state->m_invert_str = false;	/* If TRUE; invert STR signals */
735cd7a67a4SMauro Carvalho Chehab 	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
736cd7a67a4SMauro Carvalho Chehab 	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
7379a0bf528SMauro Carvalho Chehab 
7389a0bf528SMauro Carvalho Chehab 	/* If TRUE; static MPEG clockrate will be used;
7399a0bf528SMauro Carvalho Chehab 	   otherwise clockrate will adapt to the bitrate of the TS */
7409a0bf528SMauro Carvalho Chehab 
741cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_bitrate = ul_dvbt_bitrate;
742cd7a67a4SMauro Carvalho Chehab 	state->m_dvbc_bitrate = ul_dvbc_bitrate;
7439a0bf528SMauro Carvalho Chehab 
744cd7a67a4SMauro Carvalho Chehab 	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
7459a0bf528SMauro Carvalho Chehab 
7469a0bf528SMauro Carvalho Chehab 	/* Maximum bitrate in b/s in case static clockrate is selected */
747cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_ts_static_bitrate = 19392658;
748cd7a67a4SMauro Carvalho Chehab 	state->m_disable_te_ihandling = false;
7499a0bf528SMauro Carvalho Chehab 
750cd7a67a4SMauro Carvalho Chehab 	if (ul_insert_rs_byte)
751cd7a67a4SMauro Carvalho Chehab 		state->m_insert_rs_byte = true;
7529a0bf528SMauro Carvalho Chehab 
753cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
754cd7a67a4SMauro Carvalho Chehab 	if (ul_mpeg_lock_time_out < 10000)
755cd7a67a4SMauro Carvalho Chehab 		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
756cd7a67a4SMauro Carvalho Chehab 	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
757cd7a67a4SMauro Carvalho Chehab 	if (ul_demod_lock_time_out < 10000)
758cd7a67a4SMauro Carvalho Chehab 		state->m_demod_lock_time_out = ul_demod_lock_time_out;
7599a0bf528SMauro Carvalho Chehab 
7609a0bf528SMauro Carvalho Chehab 	/* QAM defaults */
761cd7a67a4SMauro Carvalho Chehab 	state->m_constellation = DRX_CONSTELLATION_AUTO;
762cd7a67a4SMauro Carvalho Chehab 	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
763cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
764cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_prescale = 1;
7659a0bf528SMauro Carvalho Chehab 
766cd7a67a4SMauro Carvalho Chehab 	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
767cd7a67a4SMauro Carvalho Chehab 	state->m_agcfast_clip_ctrl_delay = 0;
7689a0bf528SMauro Carvalho Chehab 
769949dd08dSMauro Carvalho Chehab 	state->m_gpio_cfg = ul_gpio_cfg;
7709a0bf528SMauro Carvalho Chehab 
771cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = false;
772cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_DOWN;
7739a0bf528SMauro Carvalho Chehab 
774cd7a67a4SMauro Carvalho Chehab 	state->m_rfmirror = (ul_rf_mirror == 0);
775cd7a67a4SMauro Carvalho Chehab 	state->m_if_agc_pol = false;
7769a0bf528SMauro Carvalho Chehab 	return 0;
7779a0bf528SMauro Carvalho Chehab }
7789a0bf528SMauro Carvalho Chehab 
779cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state)
7809a0bf528SMauro Carvalho Chehab {
7819a0bf528SMauro Carvalho Chehab 	int status = 0;
7829a0bf528SMauro Carvalho Chehab 	u32 jtag = 0;
7839a0bf528SMauro Carvalho Chehab 	u16 bid = 0;
7849a0bf528SMauro Carvalho Chehab 	u16 key = 0;
7859a0bf528SMauro Carvalho Chehab 
7869a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7879a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
788ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
789ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7909a0bf528SMauro Carvalho Chehab 	if (status < 0)
7919a0bf528SMauro Carvalho Chehab 		goto error;
7929a0bf528SMauro Carvalho Chehab 	/* Check device id */
7939a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_TOP_COMM_KEY__A, &key);
7949a0bf528SMauro Carvalho Chehab 	if (status < 0)
7959a0bf528SMauro Carvalho Chehab 		goto error;
7969a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7979a0bf528SMauro Carvalho Chehab 	if (status < 0)
7989a0bf528SMauro Carvalho Chehab 		goto error;
7999a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
8009a0bf528SMauro Carvalho Chehab 	if (status < 0)
8019a0bf528SMauro Carvalho Chehab 		goto error;
8029a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
8039a0bf528SMauro Carvalho Chehab 	if (status < 0)
8049a0bf528SMauro Carvalho Chehab 		goto error;
8059a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
8069a0bf528SMauro Carvalho Chehab error:
8079a0bf528SMauro Carvalho Chehab 	if (status < 0)
8083a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
8099a0bf528SMauro Carvalho Chehab 	return status;
8109a0bf528SMauro Carvalho Chehab }
8119a0bf528SMauro Carvalho Chehab 
812cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state)
8139a0bf528SMauro Carvalho Chehab {
814cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_ohw_cfg = 0;
815cd7a67a4SMauro Carvalho Chehab 	u32 sio_top_jtagid_lo = 0;
8169a0bf528SMauro Carvalho Chehab 	int status;
8179a0bf528SMauro Carvalho Chehab 	const char *spin = "";
8189a0bf528SMauro Carvalho Chehab 
8199a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
8209a0bf528SMauro Carvalho Chehab 
8219a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
8229a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
823ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
824ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
8259a0bf528SMauro Carvalho Chehab 	if (status < 0)
8269a0bf528SMauro Carvalho Chehab 		goto error;
8278418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
8289a0bf528SMauro Carvalho Chehab 	if (status < 0)
8299a0bf528SMauro Carvalho Chehab 		goto error;
830cd7a67a4SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
8319a0bf528SMauro Carvalho Chehab 	if (status < 0)
8329a0bf528SMauro Carvalho Chehab 		goto error;
8339a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
8349a0bf528SMauro Carvalho Chehab 	if (status < 0)
8359a0bf528SMauro Carvalho Chehab 		goto error;
8369a0bf528SMauro Carvalho Chehab 
837cd7a67a4SMauro Carvalho Chehab 	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
8389a0bf528SMauro Carvalho Chehab 	case 0:
8399a0bf528SMauro Carvalho Chehab 		/* ignore (bypass ?) */
8409a0bf528SMauro Carvalho Chehab 		break;
8419a0bf528SMauro Carvalho Chehab 	case 1:
8429a0bf528SMauro Carvalho Chehab 		/* 27 MHz */
843cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 27000;
8449a0bf528SMauro Carvalho Chehab 		break;
8459a0bf528SMauro Carvalho Chehab 	case 2:
8469a0bf528SMauro Carvalho Chehab 		/* 20.25 MHz */
847cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8489a0bf528SMauro Carvalho Chehab 		break;
8499a0bf528SMauro Carvalho Chehab 	case 3:
8509a0bf528SMauro Carvalho Chehab 		/* 4 MHz */
851cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8529a0bf528SMauro Carvalho Chehab 		break;
8539a0bf528SMauro Carvalho Chehab 	default:
8543a4398f5SMauro Carvalho Chehab 		pr_err("Clock Frequency is unknown\n");
8559a0bf528SMauro Carvalho Chehab 		return -EINVAL;
8569a0bf528SMauro Carvalho Chehab 	}
8579a0bf528SMauro Carvalho Chehab 	/*
8589a0bf528SMauro Carvalho Chehab 		Determine device capabilities
8599a0bf528SMauro Carvalho Chehab 		Based on pinning v14
8609a0bf528SMauro Carvalho Chehab 		*/
861cd7a67a4SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
8629a0bf528SMauro Carvalho Chehab 	if (status < 0)
8639a0bf528SMauro Carvalho Chehab 		goto error;
8649a0bf528SMauro Carvalho Chehab 
8653a4398f5SMauro Carvalho Chehab 	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
8669a0bf528SMauro Carvalho Chehab 
8679a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
868cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
8699a0bf528SMauro Carvalho Chehab 	case 0:
870cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A1;
8719a0bf528SMauro Carvalho Chehab 		spin = "A1";
8729a0bf528SMauro Carvalho Chehab 		break;
8739a0bf528SMauro Carvalho Chehab 	case 2:
874cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A2;
8759a0bf528SMauro Carvalho Chehab 		spin = "A2";
8769a0bf528SMauro Carvalho Chehab 		break;
8779a0bf528SMauro Carvalho Chehab 	case 3:
878cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A3;
8799a0bf528SMauro Carvalho Chehab 		spin = "A3";
8809a0bf528SMauro Carvalho Chehab 		break;
8819a0bf528SMauro Carvalho Chehab 	default:
882cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_UNKNOWN;
8839a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
8843a4398f5SMauro Carvalho Chehab 		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
8859a0bf528SMauro Carvalho Chehab 		goto error2;
8869a0bf528SMauro Carvalho Chehab 	}
887cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
8889a0bf528SMauro Carvalho Chehab 	case 0x13:
8899a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3913K_TYPE_ID */
890cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
891cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
892cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = false;
893cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
894cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
895cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
896cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
897cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = false;
898cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = false;
899cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9009a0bf528SMauro Carvalho Chehab 		break;
9019a0bf528SMauro Carvalho Chehab 	case 0x15:
9029a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3915K_TYPE_ID */
903cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
904cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
905cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
906cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
907cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
908cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
909cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
910cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
911cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
912cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9139a0bf528SMauro Carvalho Chehab 		break;
9149a0bf528SMauro Carvalho Chehab 	case 0x16:
9159a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3916K_TYPE_ID */
916cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
917cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
918cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
919cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
920cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
921cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
922cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
923cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
924cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
925cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9269a0bf528SMauro Carvalho Chehab 		break;
9279a0bf528SMauro Carvalho Chehab 	case 0x18:
9289a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3918K_TYPE_ID */
929cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
930cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
931cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
932cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
933cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
934cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
935cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
936cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
937cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
938cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9399a0bf528SMauro Carvalho Chehab 		break;
9409a0bf528SMauro Carvalho Chehab 	case 0x21:
9419a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3921K_TYPE_ID */
942cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
943cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
944cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
945cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
946cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
947cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
948cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
949cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
950cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
951cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9529a0bf528SMauro Carvalho Chehab 		break;
9539a0bf528SMauro Carvalho Chehab 	case 0x23:
9549a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3923K_TYPE_ID */
955cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
956cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
957cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
958cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
959cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
960cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
961cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
962cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
963cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
964cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9659a0bf528SMauro Carvalho Chehab 		break;
9669a0bf528SMauro Carvalho Chehab 	case 0x25:
9679a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3925K_TYPE_ID */
968cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
969cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
970cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
971cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
972cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
973cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
974cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
975cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
976cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
977cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9789a0bf528SMauro Carvalho Chehab 		break;
9799a0bf528SMauro Carvalho Chehab 	case 0x26:
9809a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3926K_TYPE_ID */
981cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
982cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
983cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
984cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
985cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
986cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
987cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
988cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
989cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
990cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9919a0bf528SMauro Carvalho Chehab 		break;
9929a0bf528SMauro Carvalho Chehab 	default:
9933a4398f5SMauro Carvalho Chehab 		pr_err("DeviceID 0x%02x not supported\n",
994cd7a67a4SMauro Carvalho Chehab 			((sio_top_jtagid_lo >> 12) & 0xFF));
9959a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
9969a0bf528SMauro Carvalho Chehab 		goto error2;
9979a0bf528SMauro Carvalho Chehab 	}
9989a0bf528SMauro Carvalho Chehab 
9993a4398f5SMauro Carvalho Chehab 	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1000cd7a67a4SMauro Carvalho Chehab 	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
1001cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq / 1000,
1002cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq % 1000);
10039a0bf528SMauro Carvalho Chehab 
10049a0bf528SMauro Carvalho Chehab error:
10059a0bf528SMauro Carvalho Chehab 	if (status < 0)
10063a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10079a0bf528SMauro Carvalho Chehab 
10089a0bf528SMauro Carvalho Chehab error2:
10099a0bf528SMauro Carvalho Chehab 	return status;
10109a0bf528SMauro Carvalho Chehab }
10119a0bf528SMauro Carvalho Chehab 
1012cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
10139a0bf528SMauro Carvalho Chehab {
10149a0bf528SMauro Carvalho Chehab 	int status;
10159a0bf528SMauro Carvalho Chehab 	bool powerdown_cmd;
10169a0bf528SMauro Carvalho Chehab 
10179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10189a0bf528SMauro Carvalho Chehab 
10199a0bf528SMauro Carvalho Chehab 	/* Write command */
10209a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
10219a0bf528SMauro Carvalho Chehab 	if (status < 0)
10229a0bf528SMauro Carvalho Chehab 		goto error;
10239a0bf528SMauro Carvalho Chehab 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1024b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
10259a0bf528SMauro Carvalho Chehab 
10269a0bf528SMauro Carvalho Chehab 	powerdown_cmd =
10279a0bf528SMauro Carvalho Chehab 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1028cd7a67a4SMauro Carvalho Chehab 		    ((state->m_hi_cfg_ctrl) &
10299a0bf528SMauro Carvalho Chehab 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
10309a0bf528SMauro Carvalho Chehab 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
10319a0bf528SMauro Carvalho Chehab 	if (powerdown_cmd == false) {
10329a0bf528SMauro Carvalho Chehab 		/* Wait until command rdy */
1033cd7a67a4SMauro Carvalho Chehab 		u32 retry_count = 0;
1034cd7a67a4SMauro Carvalho Chehab 		u16 wait_cmd;
10359a0bf528SMauro Carvalho Chehab 
10369a0bf528SMauro Carvalho Chehab 		do {
1037b72852baSMauro Carvalho Chehab 			usleep_range(1000, 2000);
1038cd7a67a4SMauro Carvalho Chehab 			retry_count += 1;
10399a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
1040cd7a67a4SMauro Carvalho Chehab 					  &wait_cmd);
1041cd7a67a4SMauro Carvalho Chehab 		} while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
1042cd7a67a4SMauro Carvalho Chehab 			 && (wait_cmd != 0));
10439a0bf528SMauro Carvalho Chehab 		if (status < 0)
10449a0bf528SMauro Carvalho Chehab 			goto error;
1045cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
10469a0bf528SMauro Carvalho Chehab 	}
10479a0bf528SMauro Carvalho Chehab error:
10489a0bf528SMauro Carvalho Chehab 	if (status < 0)
10493a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10509a0bf528SMauro Carvalho Chehab 
10519a0bf528SMauro Carvalho Chehab 	return status;
10529a0bf528SMauro Carvalho Chehab }
10539a0bf528SMauro Carvalho Chehab 
1054cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state)
10559a0bf528SMauro Carvalho Chehab {
10569a0bf528SMauro Carvalho Chehab 	int status;
10579a0bf528SMauro Carvalho Chehab 
10589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10599a0bf528SMauro Carvalho Chehab 
10609a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
10619a0bf528SMauro Carvalho Chehab 
1062ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1063ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timeout);
10649a0bf528SMauro Carvalho Chehab 	if (status < 0)
10659a0bf528SMauro Carvalho Chehab 		goto error;
1066ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1067ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_ctrl);
10689a0bf528SMauro Carvalho Chehab 	if (status < 0)
10699a0bf528SMauro Carvalho Chehab 		goto error;
1070ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1071ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_wake_up_key);
10729a0bf528SMauro Carvalho Chehab 	if (status < 0)
10739a0bf528SMauro Carvalho Chehab 		goto error;
1074ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1075ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_bridge_delay);
10769a0bf528SMauro Carvalho Chehab 	if (status < 0)
10779a0bf528SMauro Carvalho Chehab 		goto error;
1078ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1079ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timing_div);
10809a0bf528SMauro Carvalho Chehab 	if (status < 0)
10819a0bf528SMauro Carvalho Chehab 		goto error;
1082ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1083ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
10849a0bf528SMauro Carvalho Chehab 	if (status < 0)
10859a0bf528SMauro Carvalho Chehab 		goto error;
1086b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
10879a0bf528SMauro Carvalho Chehab 	if (status < 0)
10889a0bf528SMauro Carvalho Chehab 		goto error;
10899a0bf528SMauro Carvalho Chehab 
1090cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
10919a0bf528SMauro Carvalho Chehab error:
10929a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
10939a0bf528SMauro Carvalho Chehab 	if (status < 0)
10943a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10959a0bf528SMauro Carvalho Chehab 	return status;
10969a0bf528SMauro Carvalho Chehab }
10979a0bf528SMauro Carvalho Chehab 
1098cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state)
10999a0bf528SMauro Carvalho Chehab {
11009a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
11019a0bf528SMauro Carvalho Chehab 
1102cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1103cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timeout = 0x96FF;
11049a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
1105cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
11069a0bf528SMauro Carvalho Chehab 
1107cd7a67a4SMauro Carvalho Chehab 	return hi_cfg_command(state);
11089a0bf528SMauro Carvalho Chehab }
11099a0bf528SMauro Carvalho Chehab 
1110cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
11119a0bf528SMauro Carvalho Chehab {
11129a0bf528SMauro Carvalho Chehab 	int status = -1;
1113cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mclk_cfg = 0;
1114cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mdx_cfg = 0;
11159a0bf528SMauro Carvalho Chehab 	u16 err_cfg = 0;
11169a0bf528SMauro Carvalho Chehab 
11179a0bf528SMauro Carvalho Chehab 	dprintk(1, ": mpeg %s, %s mode\n",
1118cd7a67a4SMauro Carvalho Chehab 		mpeg_enable ? "enable" : "disable",
1119cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel ? "parallel" : "serial");
11209a0bf528SMauro Carvalho Chehab 
11219a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
1122ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1123ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
11249a0bf528SMauro Carvalho Chehab 	if (status < 0)
11259a0bf528SMauro Carvalho Chehab 		goto error;
11269a0bf528SMauro Carvalho Chehab 
11279a0bf528SMauro Carvalho Chehab 	/*  MPEG TS pad configuration */
11288418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
11299a0bf528SMauro Carvalho Chehab 	if (status < 0)
11309a0bf528SMauro Carvalho Chehab 		goto error;
11319a0bf528SMauro Carvalho Chehab 
1132cd7a67a4SMauro Carvalho Chehab 	if (mpeg_enable == false) {
11339a0bf528SMauro Carvalho Chehab 		/*  Set MPEG TS pads to inputmode */
11349a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
11359a0bf528SMauro Carvalho Chehab 		if (status < 0)
11369a0bf528SMauro Carvalho Chehab 			goto error;
11379a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
11389a0bf528SMauro Carvalho Chehab 		if (status < 0)
11399a0bf528SMauro Carvalho Chehab 			goto error;
11409a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
11419a0bf528SMauro Carvalho Chehab 		if (status < 0)
11429a0bf528SMauro Carvalho Chehab 			goto error;
11439a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
11449a0bf528SMauro Carvalho Chehab 		if (status < 0)
11459a0bf528SMauro Carvalho Chehab 			goto error;
11469a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
11479a0bf528SMauro Carvalho Chehab 		if (status < 0)
11489a0bf528SMauro Carvalho Chehab 			goto error;
11499a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11509a0bf528SMauro Carvalho Chehab 		if (status < 0)
11519a0bf528SMauro Carvalho Chehab 			goto error;
11529a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11539a0bf528SMauro Carvalho Chehab 		if (status < 0)
11549a0bf528SMauro Carvalho Chehab 			goto error;
11559a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11569a0bf528SMauro Carvalho Chehab 		if (status < 0)
11579a0bf528SMauro Carvalho Chehab 			goto error;
11589a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11599a0bf528SMauro Carvalho Chehab 		if (status < 0)
11609a0bf528SMauro Carvalho Chehab 			goto error;
11619a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11629a0bf528SMauro Carvalho Chehab 		if (status < 0)
11639a0bf528SMauro Carvalho Chehab 			goto error;
11649a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11659a0bf528SMauro Carvalho Chehab 		if (status < 0)
11669a0bf528SMauro Carvalho Chehab 			goto error;
11679a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
11689a0bf528SMauro Carvalho Chehab 		if (status < 0)
11699a0bf528SMauro Carvalho Chehab 			goto error;
11709a0bf528SMauro Carvalho Chehab 	} else {
11719a0bf528SMauro Carvalho Chehab 		/* Enable MPEG output */
1172cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mdx_cfg =
1173cd7a67a4SMauro Carvalho Chehab 			((state->m_ts_data_strength <<
11749a0bf528SMauro Carvalho Chehab 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1175cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
11769a0bf528SMauro Carvalho Chehab 					SIO_PDR_MCLK_CFG_DRIVE__B) |
11779a0bf528SMauro Carvalho Chehab 					0x0003);
11789a0bf528SMauro Carvalho Chehab 
1179cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
11809a0bf528SMauro Carvalho Chehab 		if (status < 0)
11819a0bf528SMauro Carvalho Chehab 			goto error;
11829a0bf528SMauro Carvalho Chehab 
11839a0bf528SMauro Carvalho Chehab 		if (state->enable_merr_cfg)
1184cd7a67a4SMauro Carvalho Chehab 			err_cfg = sio_pdr_mdx_cfg;
11859a0bf528SMauro Carvalho Chehab 
11869a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
11879a0bf528SMauro Carvalho Chehab 		if (status < 0)
11889a0bf528SMauro Carvalho Chehab 			goto error;
11899a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
11909a0bf528SMauro Carvalho Chehab 		if (status < 0)
11919a0bf528SMauro Carvalho Chehab 			goto error;
11929a0bf528SMauro Carvalho Chehab 
1193cd7a67a4SMauro Carvalho Chehab 		if (state->m_enable_parallel == true) {
11949a0bf528SMauro Carvalho Chehab 			/* paralel -> enable MD1 to MD7 */
1195ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A,
1196ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11979a0bf528SMauro Carvalho Chehab 			if (status < 0)
11989a0bf528SMauro Carvalho Chehab 				goto error;
1199ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A,
1200ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12019a0bf528SMauro Carvalho Chehab 			if (status < 0)
12029a0bf528SMauro Carvalho Chehab 				goto error;
1203ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A,
1204ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12059a0bf528SMauro Carvalho Chehab 			if (status < 0)
12069a0bf528SMauro Carvalho Chehab 				goto error;
1207ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A,
1208ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12099a0bf528SMauro Carvalho Chehab 			if (status < 0)
12109a0bf528SMauro Carvalho Chehab 				goto error;
1211ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A,
1212ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12139a0bf528SMauro Carvalho Chehab 			if (status < 0)
12149a0bf528SMauro Carvalho Chehab 				goto error;
1215ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A,
1216ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12179a0bf528SMauro Carvalho Chehab 			if (status < 0)
12189a0bf528SMauro Carvalho Chehab 				goto error;
1219ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A,
1220ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12219a0bf528SMauro Carvalho Chehab 			if (status < 0)
12229a0bf528SMauro Carvalho Chehab 				goto error;
12239a0bf528SMauro Carvalho Chehab 		} else {
1224cd7a67a4SMauro Carvalho Chehab 			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
12259a0bf528SMauro Carvalho Chehab 						SIO_PDR_MD0_CFG_DRIVE__B)
12269a0bf528SMauro Carvalho Chehab 					| 0x0003);
12279a0bf528SMauro Carvalho Chehab 			/* serial -> disable MD1 to MD7 */
12289a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
12299a0bf528SMauro Carvalho Chehab 			if (status < 0)
12309a0bf528SMauro Carvalho Chehab 				goto error;
12319a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
12329a0bf528SMauro Carvalho Chehab 			if (status < 0)
12339a0bf528SMauro Carvalho Chehab 				goto error;
12349a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
12359a0bf528SMauro Carvalho Chehab 			if (status < 0)
12369a0bf528SMauro Carvalho Chehab 				goto error;
12379a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
12389a0bf528SMauro Carvalho Chehab 			if (status < 0)
12399a0bf528SMauro Carvalho Chehab 				goto error;
12409a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
12419a0bf528SMauro Carvalho Chehab 			if (status < 0)
12429a0bf528SMauro Carvalho Chehab 				goto error;
12439a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
12449a0bf528SMauro Carvalho Chehab 			if (status < 0)
12459a0bf528SMauro Carvalho Chehab 				goto error;
12469a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12479a0bf528SMauro Carvalho Chehab 			if (status < 0)
12489a0bf528SMauro Carvalho Chehab 				goto error;
12499a0bf528SMauro Carvalho Chehab 		}
1250cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
12519a0bf528SMauro Carvalho Chehab 		if (status < 0)
12529a0bf528SMauro Carvalho Chehab 			goto error;
1253cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
12549a0bf528SMauro Carvalho Chehab 		if (status < 0)
12559a0bf528SMauro Carvalho Chehab 			goto error;
12569a0bf528SMauro Carvalho Chehab 	}
12579a0bf528SMauro Carvalho Chehab 	/*  Enable MB output over MPEG pads and ctl input */
12589a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
12599a0bf528SMauro Carvalho Chehab 	if (status < 0)
12609a0bf528SMauro Carvalho Chehab 		goto error;
12619a0bf528SMauro Carvalho Chehab 	/*  Write nomagic word to enable pdr reg write */
12629a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
12639a0bf528SMauro Carvalho Chehab error:
12649a0bf528SMauro Carvalho Chehab 	if (status < 0)
12653a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12669a0bf528SMauro Carvalho Chehab 	return status;
12679a0bf528SMauro Carvalho Chehab }
12689a0bf528SMauro Carvalho Chehab 
1269cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state)
12709a0bf528SMauro Carvalho Chehab {
12719a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12729a0bf528SMauro Carvalho Chehab 
1273cd7a67a4SMauro Carvalho Chehab 	return mpegts_configure_pins(state, false);
12749a0bf528SMauro Carvalho Chehab }
12759a0bf528SMauro Carvalho Chehab 
1276cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state,
1277cd7a67a4SMauro Carvalho Chehab 		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
12789a0bf528SMauro Carvalho Chehab {
1279cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
12809a0bf528SMauro Carvalho Chehab 	int status;
12819a0bf528SMauro Carvalho Chehab 	unsigned long end;
12829a0bf528SMauro Carvalho Chehab 
12839a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12849a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
12859a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
12869a0bf528SMauro Carvalho Chehab 	if (status < 0)
12879a0bf528SMauro Carvalho Chehab 		goto error;
1288cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
12899a0bf528SMauro Carvalho Chehab 	if (status < 0)
12909a0bf528SMauro Carvalho Chehab 		goto error;
1291cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
12929a0bf528SMauro Carvalho Chehab 	if (status < 0)
12939a0bf528SMauro Carvalho Chehab 		goto error;
12949a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
12959a0bf528SMauro Carvalho Chehab 	if (status < 0)
12969a0bf528SMauro Carvalho Chehab 		goto error;
12979a0bf528SMauro Carvalho Chehab 
1298cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
12999a0bf528SMauro Carvalho Chehab 	do {
1300b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1301cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
13029a0bf528SMauro Carvalho Chehab 		if (status < 0)
13039a0bf528SMauro Carvalho Chehab 			goto error;
1304cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) &&
13059a0bf528SMauro Carvalho Chehab 			((time_is_after_jiffies(end))));
13069a0bf528SMauro Carvalho Chehab 
1307cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
13083a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
13099a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
13109a0bf528SMauro Carvalho Chehab 		goto error2;
13119a0bf528SMauro Carvalho Chehab 	}
13129a0bf528SMauro Carvalho Chehab error:
13139a0bf528SMauro Carvalho Chehab 	if (status < 0)
13143a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
13159a0bf528SMauro Carvalho Chehab error2:
13169a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
13179a0bf528SMauro Carvalho Chehab 	return status;
13189a0bf528SMauro Carvalho Chehab }
13199a0bf528SMauro Carvalho Chehab 
13209a0bf528SMauro Carvalho Chehab 
1321cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state,
1322cd7a67a4SMauro Carvalho Chehab 			     const u8 p_mc_image[], u32 length)
13239a0bf528SMauro Carvalho Chehab {
1324cd7a67a4SMauro Carvalho Chehab 	const u8 *p_src = p_mc_image;
1325cd7a67a4SMauro Carvalho Chehab 	u32 address;
1326cd7a67a4SMauro Carvalho Chehab 	u16 n_blocks;
1327cd7a67a4SMauro Carvalho Chehab 	u16 block_size;
13289a0bf528SMauro Carvalho Chehab 	u32 offset = 0;
13299a0bf528SMauro Carvalho Chehab 	u32 i;
13309a0bf528SMauro Carvalho Chehab 	int status = 0;
13319a0bf528SMauro Carvalho Chehab 
13329a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13339a0bf528SMauro Carvalho Chehab 
13349a0bf528SMauro Carvalho Chehab 	/* down the drain (we don't care about MAGIC_WORD) */
13359a0bf528SMauro Carvalho Chehab #if 0
13369a0bf528SMauro Carvalho Chehab 	/* For future reference */
1337cd7a67a4SMauro Carvalho Chehab 	drain = (p_src[0] << 8) | p_src[1];
13389a0bf528SMauro Carvalho Chehab #endif
1339cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13409a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
1341cd7a67a4SMauro Carvalho Chehab 	n_blocks = (p_src[0] << 8) | p_src[1];
1342cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13439a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
13449a0bf528SMauro Carvalho Chehab 
1345cd7a67a4SMauro Carvalho Chehab 	for (i = 0; i < n_blocks; i += 1) {
1346cd7a67a4SMauro Carvalho Chehab 		address = (p_src[0] << 24) | (p_src[1] << 16) |
1347cd7a67a4SMauro Carvalho Chehab 		    (p_src[2] << 8) | p_src[3];
1348cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u32);
13499a0bf528SMauro Carvalho Chehab 		offset += sizeof(u32);
13509a0bf528SMauro Carvalho Chehab 
1351cd7a67a4SMauro Carvalho Chehab 		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1352cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13539a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13549a0bf528SMauro Carvalho Chehab 
13559a0bf528SMauro Carvalho Chehab #if 0
13569a0bf528SMauro Carvalho Chehab 		/* For future reference */
1357cd7a67a4SMauro Carvalho Chehab 		flags = (p_src[0] << 8) | p_src[1];
13589a0bf528SMauro Carvalho Chehab #endif
1359cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13609a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13619a0bf528SMauro Carvalho Chehab 
13629a0bf528SMauro Carvalho Chehab #if 0
13639a0bf528SMauro Carvalho Chehab 		/* For future reference */
1364cd7a67a4SMauro Carvalho Chehab 		block_crc = (p_src[0] << 8) | p_src[1];
13659a0bf528SMauro Carvalho Chehab #endif
1366cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13679a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13689a0bf528SMauro Carvalho Chehab 
1369cd7a67a4SMauro Carvalho Chehab 		if (offset + block_size > length) {
13703a4398f5SMauro Carvalho Chehab 			pr_err("Firmware is corrupted.\n");
13719a0bf528SMauro Carvalho Chehab 			return -EINVAL;
13729a0bf528SMauro Carvalho Chehab 		}
13739a0bf528SMauro Carvalho Chehab 
1374cd7a67a4SMauro Carvalho Chehab 		status = write_block(state, address, block_size, p_src);
13759a0bf528SMauro Carvalho Chehab 		if (status < 0) {
13763a4398f5SMauro Carvalho Chehab 			pr_err("Error %d while loading firmware\n", status);
13779a0bf528SMauro Carvalho Chehab 			break;
13789a0bf528SMauro Carvalho Chehab 		}
1379cd7a67a4SMauro Carvalho Chehab 		p_src += block_size;
1380cd7a67a4SMauro Carvalho Chehab 		offset += block_size;
13819a0bf528SMauro Carvalho Chehab 	}
13829a0bf528SMauro Carvalho Chehab 	return status;
13839a0bf528SMauro Carvalho Chehab }
13849a0bf528SMauro Carvalho Chehab 
1385cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
13869a0bf528SMauro Carvalho Chehab {
13879a0bf528SMauro Carvalho Chehab 	int status;
13889a0bf528SMauro Carvalho Chehab 	u16 data = 0;
1389cd7a67a4SMauro Carvalho Chehab 	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1390cd7a67a4SMauro Carvalho Chehab 	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
13919a0bf528SMauro Carvalho Chehab 	unsigned long end;
13929a0bf528SMauro Carvalho Chehab 
13939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13949a0bf528SMauro Carvalho Chehab 
13959a0bf528SMauro Carvalho Chehab 	if (enable == false) {
1396cd7a67a4SMauro Carvalho Chehab 		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1397cd7a67a4SMauro Carvalho Chehab 		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
13989a0bf528SMauro Carvalho Chehab 	}
13999a0bf528SMauro Carvalho Chehab 
14009a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1401cd7a67a4SMauro Carvalho Chehab 	if (status >= 0 && data == desired_status) {
14029a0bf528SMauro Carvalho Chehab 		/* tokenring already has correct status */
14039a0bf528SMauro Carvalho Chehab 		return status;
14049a0bf528SMauro Carvalho Chehab 	}
14059a0bf528SMauro Carvalho Chehab 	/* Disable/enable dvbt tokenring bridge   */
1406cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
14079a0bf528SMauro Carvalho Chehab 
14089a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
14099a0bf528SMauro Carvalho Chehab 	do {
14109a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1411ab5060cdSMauro Carvalho Chehab 		if ((status >= 0 && data == desired_status)
1412ab5060cdSMauro Carvalho Chehab 		    || time_is_after_jiffies(end))
14139a0bf528SMauro Carvalho Chehab 			break;
1414b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
14159a0bf528SMauro Carvalho Chehab 	} while (1);
1416cd7a67a4SMauro Carvalho Chehab 	if (data != desired_status) {
14173a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
14189a0bf528SMauro Carvalho Chehab 		return -EINVAL;
14199a0bf528SMauro Carvalho Chehab 	}
14209a0bf528SMauro Carvalho Chehab 	return status;
14219a0bf528SMauro Carvalho Chehab }
14229a0bf528SMauro Carvalho Chehab 
1423cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state)
14249a0bf528SMauro Carvalho Chehab {
14259a0bf528SMauro Carvalho Chehab 	int status = 0;
1426cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
1427cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_ipr_mode = 0;
14289a0bf528SMauro Carvalho Chehab 
14299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14309a0bf528SMauro Carvalho Chehab 
14319a0bf528SMauro Carvalho Chehab 	/* Gracefull shutdown (byte boundaries) */
1432cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
14339a0bf528SMauro Carvalho Chehab 	if (status < 0)
14349a0bf528SMauro Carvalho Chehab 		goto error;
1435cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1436cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
14379a0bf528SMauro Carvalho Chehab 	if (status < 0)
14389a0bf528SMauro Carvalho Chehab 		goto error;
14399a0bf528SMauro Carvalho Chehab 
14409a0bf528SMauro Carvalho Chehab 	/* Suppress MCLK during absence of data */
1441cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
14429a0bf528SMauro Carvalho Chehab 	if (status < 0)
14439a0bf528SMauro Carvalho Chehab 		goto error;
1444cd7a67a4SMauro Carvalho Chehab 	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1445cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
14469a0bf528SMauro Carvalho Chehab 
14479a0bf528SMauro Carvalho Chehab error:
14489a0bf528SMauro Carvalho Chehab 	if (status < 0)
14493a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14509a0bf528SMauro Carvalho Chehab 
14519a0bf528SMauro Carvalho Chehab 	return status;
14529a0bf528SMauro Carvalho Chehab }
14539a0bf528SMauro Carvalho Chehab 
14549a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
1455cd7a67a4SMauro Carvalho Chehab 		       u16 cmd, u8 parameter_len,
1456cd7a67a4SMauro Carvalho Chehab 		       u16 *parameter, u8 result_len, u16 *result)
14579a0bf528SMauro Carvalho Chehab {
14589a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
14599a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
14609a0bf528SMauro Carvalho Chehab #endif
1461cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
14629a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
14639a0bf528SMauro Carvalho Chehab 	unsigned long end;
14649a0bf528SMauro Carvalho Chehab 	u8 buffer[34];
14659a0bf528SMauro Carvalho Chehab 	int cnt = 0, ii;
14669a0bf528SMauro Carvalho Chehab 	const char *p;
14679a0bf528SMauro Carvalho Chehab 	char errname[30];
14689a0bf528SMauro Carvalho Chehab 
14699a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14709a0bf528SMauro Carvalho Chehab 
1471cd7a67a4SMauro Carvalho Chehab 	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1472cd7a67a4SMauro Carvalho Chehab 	    ((result_len > 0) && (result == NULL))) {
14733a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14749a0bf528SMauro Carvalho Chehab 		return status;
14759a0bf528SMauro Carvalho Chehab 	}
14769a0bf528SMauro Carvalho Chehab 
14779a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
14789a0bf528SMauro Carvalho Chehab 
14799a0bf528SMauro Carvalho Chehab 	/* assume that the command register is ready
14809a0bf528SMauro Carvalho Chehab 		since it is checked afterwards */
1481cd7a67a4SMauro Carvalho Chehab 	for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
14829a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = (parameter[ii] & 0xFF);
14839a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
14849a0bf528SMauro Carvalho Chehab 	}
14859a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = (cmd & 0xFF);
14869a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
14879a0bf528SMauro Carvalho Chehab 
14889a0bf528SMauro Carvalho Chehab 	write_block(state, SCU_RAM_PARAM_0__A -
1489cd7a67a4SMauro Carvalho Chehab 			(parameter_len - 1), cnt, buffer);
14909a0bf528SMauro Carvalho Chehab 	/* Wait until SCU has processed command */
14919a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
14929a0bf528SMauro Carvalho Chehab 	do {
1493b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1494cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
14959a0bf528SMauro Carvalho Chehab 		if (status < 0)
14969a0bf528SMauro Carvalho Chehab 			goto error;
1497cd7a67a4SMauro Carvalho Chehab 	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1498cd7a67a4SMauro Carvalho Chehab 	if (cur_cmd != DRX_SCU_READY) {
14993a4398f5SMauro Carvalho Chehab 		pr_err("SCU not ready\n");
15009a0bf528SMauro Carvalho Chehab 		status = -EIO;
15019a0bf528SMauro Carvalho Chehab 		goto error2;
15029a0bf528SMauro Carvalho Chehab 	}
15039a0bf528SMauro Carvalho Chehab 	/* read results */
1504cd7a67a4SMauro Carvalho Chehab 	if ((result_len > 0) && (result != NULL)) {
15059a0bf528SMauro Carvalho Chehab 		s16 err;
15069a0bf528SMauro Carvalho Chehab 		int ii;
15079a0bf528SMauro Carvalho Chehab 
1508cd7a67a4SMauro Carvalho Chehab 		for (ii = result_len - 1; ii >= 0; ii -= 1) {
1509ab5060cdSMauro Carvalho Chehab 			status = read16(state, SCU_RAM_PARAM_0__A - ii,
1510ab5060cdSMauro Carvalho Chehab 					&result[ii]);
15119a0bf528SMauro Carvalho Chehab 			if (status < 0)
15129a0bf528SMauro Carvalho Chehab 				goto error;
15139a0bf528SMauro Carvalho Chehab 		}
15149a0bf528SMauro Carvalho Chehab 
15159a0bf528SMauro Carvalho Chehab 		/* Check if an error was reported by SCU */
15169a0bf528SMauro Carvalho Chehab 		err = (s16)result[0];
15179a0bf528SMauro Carvalho Chehab 		if (err >= 0)
15189a0bf528SMauro Carvalho Chehab 			goto error;
15199a0bf528SMauro Carvalho Chehab 
15209a0bf528SMauro Carvalho Chehab 		/* check for the known error codes */
15219a0bf528SMauro Carvalho Chehab 		switch (err) {
15229a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKCMD:
15239a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKCMD";
15249a0bf528SMauro Carvalho Chehab 			break;
15259a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKSTD:
15269a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKSTD";
15279a0bf528SMauro Carvalho Chehab 			break;
15289a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_SIZE:
15299a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_SIZE";
15309a0bf528SMauro Carvalho Chehab 			break;
15319a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_INVPAR:
15329a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_INVPAR";
15339a0bf528SMauro Carvalho Chehab 			break;
15349a0bf528SMauro Carvalho Chehab 		default: /* Other negative values are errors */
15359a0bf528SMauro Carvalho Chehab 			sprintf(errname, "ERROR: %d\n", err);
15369a0bf528SMauro Carvalho Chehab 			p = errname;
15379a0bf528SMauro Carvalho Chehab 		}
15383a4398f5SMauro Carvalho Chehab 		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
15399a0bf528SMauro Carvalho Chehab 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
15409a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
15419a0bf528SMauro Carvalho Chehab 		goto error2;
15429a0bf528SMauro Carvalho Chehab 	}
15439a0bf528SMauro Carvalho Chehab 
15449a0bf528SMauro Carvalho Chehab error:
15459a0bf528SMauro Carvalho Chehab 	if (status < 0)
15463a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15479a0bf528SMauro Carvalho Chehab error2:
15489a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
15499a0bf528SMauro Carvalho Chehab 	return status;
15509a0bf528SMauro Carvalho Chehab }
15519a0bf528SMauro Carvalho Chehab 
1552cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active)
15539a0bf528SMauro Carvalho Chehab {
15549a0bf528SMauro Carvalho Chehab 	u16 data = 0;
15559a0bf528SMauro Carvalho Chehab 	int status;
15569a0bf528SMauro Carvalho Chehab 
15579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15589a0bf528SMauro Carvalho Chehab 
15599a0bf528SMauro Carvalho Chehab 	/* Configure IQM */
15609a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_STDBY__A, &data);
15619a0bf528SMauro Carvalho Chehab 	if (status < 0)
15629a0bf528SMauro Carvalho Chehab 		goto error;
15639a0bf528SMauro Carvalho Chehab 
15649a0bf528SMauro Carvalho Chehab 	if (!active) {
15659a0bf528SMauro Carvalho Chehab 		data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
15669a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_AMP_STANDBY
15679a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_PD_STANDBY
15689a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
15699a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
15709a0bf528SMauro Carvalho Chehab 	} else {
15719a0bf528SMauro Carvalho Chehab 		data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
15729a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
15739a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_PD_STANDBY)
15749a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
15759a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
15769a0bf528SMauro Carvalho Chehab 			);
15779a0bf528SMauro Carvalho Chehab 	}
15789a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_STDBY__A, data);
15799a0bf528SMauro Carvalho Chehab 
15809a0bf528SMauro Carvalho Chehab error:
15819a0bf528SMauro Carvalho Chehab 	if (status < 0)
15823a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15839a0bf528SMauro Carvalho Chehab 	return status;
15849a0bf528SMauro Carvalho Chehab }
15859a0bf528SMauro Carvalho Chehab 
1586cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
15879a0bf528SMauro Carvalho Chehab {
15889a0bf528SMauro Carvalho Chehab 	int status = 0;
1589cd7a67a4SMauro Carvalho Chehab 	u16 sio_cc_pwd_mode = 0;
15909a0bf528SMauro Carvalho Chehab 
15919a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15929a0bf528SMauro Carvalho Chehab 
15939a0bf528SMauro Carvalho Chehab 	/* Check arguments */
15949a0bf528SMauro Carvalho Chehab 	if (mode == NULL)
15959a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15969a0bf528SMauro Carvalho Chehab 
15979a0bf528SMauro Carvalho Chehab 	switch (*mode) {
15989a0bf528SMauro Carvalho Chehab 	case DRX_POWER_UP:
1599cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
16009a0bf528SMauro Carvalho Chehab 		break;
16019a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_OFDM:
1602cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
16039a0bf528SMauro Carvalho Chehab 		break;
16049a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_CORE:
1605cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
16069a0bf528SMauro Carvalho Chehab 		break;
16079a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_PLL:
1608cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
16099a0bf528SMauro Carvalho Chehab 		break;
16109a0bf528SMauro Carvalho Chehab 	case DRX_POWER_DOWN:
1611cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
16129a0bf528SMauro Carvalho Chehab 		break;
16139a0bf528SMauro Carvalho Chehab 	default:
16149a0bf528SMauro Carvalho Chehab 		/* Unknow sleep mode */
16159a0bf528SMauro Carvalho Chehab 		return -EINVAL;
16169a0bf528SMauro Carvalho Chehab 	}
16179a0bf528SMauro Carvalho Chehab 
16189a0bf528SMauro Carvalho Chehab 	/* If already in requested power mode, do nothing */
1619cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode == *mode)
16209a0bf528SMauro Carvalho Chehab 		return 0;
16219a0bf528SMauro Carvalho Chehab 
16229a0bf528SMauro Carvalho Chehab 	/* For next steps make sure to start from DRX_POWER_UP mode */
1623cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode != DRX_POWER_UP) {
1624cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
16259a0bf528SMauro Carvalho Chehab 		if (status < 0)
16269a0bf528SMauro Carvalho Chehab 			goto error;
1627cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, true);
16289a0bf528SMauro Carvalho Chehab 		if (status < 0)
16299a0bf528SMauro Carvalho Chehab 			goto error;
16309a0bf528SMauro Carvalho Chehab 	}
16319a0bf528SMauro Carvalho Chehab 
16329a0bf528SMauro Carvalho Chehab 	if (*mode == DRX_POWER_UP) {
16339a0bf528SMauro Carvalho Chehab 		/* Restore analog & pin configuartion */
16349a0bf528SMauro Carvalho Chehab 	} else {
16359a0bf528SMauro Carvalho Chehab 		/* Power down to requested mode */
16369a0bf528SMauro Carvalho Chehab 		/* Backup some register settings */
16379a0bf528SMauro Carvalho Chehab 		/* Set pins with possible pull-ups connected
16389a0bf528SMauro Carvalho Chehab 		   to them in input mode */
16399a0bf528SMauro Carvalho Chehab 		/* Analog power down */
16409a0bf528SMauro Carvalho Chehab 		/* ADC power down */
16419a0bf528SMauro Carvalho Chehab 		/* Power down device */
16429a0bf528SMauro Carvalho Chehab 		/* stop all comm_exec */
16439a0bf528SMauro Carvalho Chehab 		/* Stop and power down previous standard */
1644cd7a67a4SMauro Carvalho Chehab 		switch (state->m_operation_mode) {
16459a0bf528SMauro Carvalho Chehab 		case OM_DVBT:
1646cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16479a0bf528SMauro Carvalho Chehab 			if (status < 0)
16489a0bf528SMauro Carvalho Chehab 				goto error;
1649cd7a67a4SMauro Carvalho Chehab 			status = power_down_dvbt(state, false);
16509a0bf528SMauro Carvalho Chehab 			if (status < 0)
16519a0bf528SMauro Carvalho Chehab 				goto error;
16529a0bf528SMauro Carvalho Chehab 			break;
16539a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_A:
16549a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_C:
1655cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16569a0bf528SMauro Carvalho Chehab 			if (status < 0)
16579a0bf528SMauro Carvalho Chehab 				goto error;
1658cd7a67a4SMauro Carvalho Chehab 			status = power_down_qam(state);
16599a0bf528SMauro Carvalho Chehab 			if (status < 0)
16609a0bf528SMauro Carvalho Chehab 				goto error;
16619a0bf528SMauro Carvalho Chehab 			break;
16629a0bf528SMauro Carvalho Chehab 		default:
16639a0bf528SMauro Carvalho Chehab 			break;
16649a0bf528SMauro Carvalho Chehab 		}
1665cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, false);
16669a0bf528SMauro Carvalho Chehab 		if (status < 0)
16679a0bf528SMauro Carvalho Chehab 			goto error;
1668cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
16699a0bf528SMauro Carvalho Chehab 		if (status < 0)
16709a0bf528SMauro Carvalho Chehab 			goto error;
16719a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
16729a0bf528SMauro Carvalho Chehab 		if (status < 0)
16739a0bf528SMauro Carvalho Chehab 			goto error;
16749a0bf528SMauro Carvalho Chehab 
16759a0bf528SMauro Carvalho Chehab 		if (*mode != DRXK_POWER_DOWN_OFDM) {
1676cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_ctrl |=
16779a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1678cd7a67a4SMauro Carvalho Chehab 			status = hi_cfg_command(state);
16799a0bf528SMauro Carvalho Chehab 			if (status < 0)
16809a0bf528SMauro Carvalho Chehab 				goto error;
16819a0bf528SMauro Carvalho Chehab 		}
16829a0bf528SMauro Carvalho Chehab 	}
1683cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = *mode;
16849a0bf528SMauro Carvalho Chehab 
16859a0bf528SMauro Carvalho Chehab error:
16869a0bf528SMauro Carvalho Chehab 	if (status < 0)
16873a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
16889a0bf528SMauro Carvalho Chehab 
16899a0bf528SMauro Carvalho Chehab 	return status;
16909a0bf528SMauro Carvalho Chehab }
16919a0bf528SMauro Carvalho Chehab 
1692cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
16939a0bf528SMauro Carvalho Chehab {
1694cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1695cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
16969a0bf528SMauro Carvalho Chehab 	u16 data = 0;
16979a0bf528SMauro Carvalho Chehab 	int status;
16989a0bf528SMauro Carvalho Chehab 
16999a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17009a0bf528SMauro Carvalho Chehab 
17019a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
17029a0bf528SMauro Carvalho Chehab 	if (status < 0)
17039a0bf528SMauro Carvalho Chehab 		goto error;
17049a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
17059a0bf528SMauro Carvalho Chehab 		/* Send OFDM stop command */
1706ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1707ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1708ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1709ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
17109a0bf528SMauro Carvalho Chehab 		if (status < 0)
17119a0bf528SMauro Carvalho Chehab 			goto error;
17129a0bf528SMauro Carvalho Chehab 		/* Send OFDM reset command */
1713ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1714ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1715ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1716ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
17179a0bf528SMauro Carvalho Chehab 		if (status < 0)
17189a0bf528SMauro Carvalho Chehab 			goto error;
17199a0bf528SMauro Carvalho Chehab 	}
17209a0bf528SMauro Carvalho Chehab 
17219a0bf528SMauro Carvalho Chehab 	/* Reset datapath for OFDM, processors first */
17229a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
17239a0bf528SMauro Carvalho Chehab 	if (status < 0)
17249a0bf528SMauro Carvalho Chehab 		goto error;
17259a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
17269a0bf528SMauro Carvalho Chehab 	if (status < 0)
17279a0bf528SMauro Carvalho Chehab 		goto error;
17289a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
17299a0bf528SMauro Carvalho Chehab 	if (status < 0)
17309a0bf528SMauro Carvalho Chehab 		goto error;
17319a0bf528SMauro Carvalho Chehab 
17329a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
1733cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
17349a0bf528SMauro Carvalho Chehab 	if (status < 0)
17359a0bf528SMauro Carvalho Chehab 		goto error;
17369a0bf528SMauro Carvalho Chehab 
17379a0bf528SMauro Carvalho Chehab 	/* powerdown to OFDM mode          */
1738cd7a67a4SMauro Carvalho Chehab 	if (set_power_mode) {
1739cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
17409a0bf528SMauro Carvalho Chehab 		if (status < 0)
17419a0bf528SMauro Carvalho Chehab 			goto error;
17429a0bf528SMauro Carvalho Chehab 	}
17439a0bf528SMauro Carvalho Chehab error:
17449a0bf528SMauro Carvalho Chehab 	if (status < 0)
17453a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
17469a0bf528SMauro Carvalho Chehab 	return status;
17479a0bf528SMauro Carvalho Chehab }
17489a0bf528SMauro Carvalho Chehab 
1749cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state,
1750cd7a67a4SMauro Carvalho Chehab 			    enum operation_mode o_mode)
17519a0bf528SMauro Carvalho Chehab {
17529a0bf528SMauro Carvalho Chehab 	int status = 0;
17539a0bf528SMauro Carvalho Chehab 
17549a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17559a0bf528SMauro Carvalho Chehab 	/*
17569a0bf528SMauro Carvalho Chehab 	   Stop and power down previous standard
17579a0bf528SMauro Carvalho Chehab 	   TODO investigate total power down instead of partial
17589a0bf528SMauro Carvalho Chehab 	   power down depending on "previous" standard.
17599a0bf528SMauro Carvalho Chehab 	 */
17609a0bf528SMauro Carvalho Chehab 
17619a0bf528SMauro Carvalho Chehab 	/* disable HW lock indicator */
1762ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1763ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
17649a0bf528SMauro Carvalho Chehab 	if (status < 0)
17659a0bf528SMauro Carvalho Chehab 		goto error;
17669a0bf528SMauro Carvalho Chehab 
17679a0bf528SMauro Carvalho Chehab 	/* Device is already at the required mode */
1768cd7a67a4SMauro Carvalho Chehab 	if (state->m_operation_mode == o_mode)
17699a0bf528SMauro Carvalho Chehab 		return 0;
17709a0bf528SMauro Carvalho Chehab 
1771cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
17729a0bf528SMauro Carvalho Chehab 		/* OM_NONE was added for start up */
17739a0bf528SMauro Carvalho Chehab 	case OM_NONE:
17749a0bf528SMauro Carvalho Chehab 		break;
17759a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1776cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17779a0bf528SMauro Carvalho Chehab 		if (status < 0)
17789a0bf528SMauro Carvalho Chehab 			goto error;
1779cd7a67a4SMauro Carvalho Chehab 		status = power_down_dvbt(state, true);
17809a0bf528SMauro Carvalho Chehab 		if (status < 0)
17819a0bf528SMauro Carvalho Chehab 			goto error;
1782cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17839a0bf528SMauro Carvalho Chehab 		break;
17849a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
17859a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1786cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17879a0bf528SMauro Carvalho Chehab 		if (status < 0)
17889a0bf528SMauro Carvalho Chehab 			goto error;
1789cd7a67a4SMauro Carvalho Chehab 		status = power_down_qam(state);
17909a0bf528SMauro Carvalho Chehab 		if (status < 0)
17919a0bf528SMauro Carvalho Chehab 			goto error;
1792cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17939a0bf528SMauro Carvalho Chehab 		break;
17949a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17959a0bf528SMauro Carvalho Chehab 	default:
17969a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17979a0bf528SMauro Carvalho Chehab 		goto error;
17989a0bf528SMauro Carvalho Chehab 	}
17999a0bf528SMauro Carvalho Chehab 
18009a0bf528SMauro Carvalho Chehab 	/*
18019a0bf528SMauro Carvalho Chehab 		Power up new standard
18029a0bf528SMauro Carvalho Chehab 		*/
1803cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
18049a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
18059a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-T\n");
1806cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1807cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt_standard(state, o_mode);
18089a0bf528SMauro Carvalho Chehab 		if (status < 0)
18099a0bf528SMauro Carvalho Chehab 			goto error;
18109a0bf528SMauro Carvalho Chehab 		break;
18119a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
18129a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
18139a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-C Annex %c\n",
1814cd7a67a4SMauro Carvalho Chehab 			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1815cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1816cd7a67a4SMauro Carvalho Chehab 		status = set_qam_standard(state, o_mode);
18179a0bf528SMauro Carvalho Chehab 		if (status < 0)
18189a0bf528SMauro Carvalho Chehab 			goto error;
18199a0bf528SMauro Carvalho Chehab 		break;
18209a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18219a0bf528SMauro Carvalho Chehab 	default:
18229a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
18239a0bf528SMauro Carvalho Chehab 	}
18249a0bf528SMauro Carvalho Chehab error:
18259a0bf528SMauro Carvalho Chehab 	if (status < 0)
18263a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18279a0bf528SMauro Carvalho Chehab 	return status;
18289a0bf528SMauro Carvalho Chehab }
18299a0bf528SMauro Carvalho Chehab 
1830cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq,
1831cd7a67a4SMauro Carvalho Chehab 		 s32 intermediate_frequency)
18329a0bf528SMauro Carvalho Chehab {
18339a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18349a0bf528SMauro Carvalho Chehab 
1835cd7a67a4SMauro Carvalho Chehab 	u16 i_freqk_hz;
1836cd7a67a4SMauro Carvalho Chehab 	s32 offsetk_hz = offset_freq / 1000;
18379a0bf528SMauro Carvalho Chehab 
18389a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
1839cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state != DRXK_STOPPED &&
1840cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state != DRXK_DTV_STARTED)
18419a0bf528SMauro Carvalho Chehab 		goto error;
18429a0bf528SMauro Carvalho Chehab 
1843cd7a67a4SMauro Carvalho Chehab 	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
18449a0bf528SMauro Carvalho Chehab 
1845cd7a67a4SMauro Carvalho Chehab 	if (intermediate_frequency < 0) {
1846cd7a67a4SMauro Carvalho Chehab 		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1847cd7a67a4SMauro Carvalho Chehab 		intermediate_frequency = -intermediate_frequency;
18489a0bf528SMauro Carvalho Chehab 	}
18499a0bf528SMauro Carvalho Chehab 
1850cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18519a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18529a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1853cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1854cd7a67a4SMauro Carvalho Chehab 		status = set_qam(state, i_freqk_hz, offsetk_hz);
18559a0bf528SMauro Carvalho Chehab 		if (status < 0)
18569a0bf528SMauro Carvalho Chehab 			goto error;
1857cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18589a0bf528SMauro Carvalho Chehab 		break;
18599a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1860cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1861cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
18629a0bf528SMauro Carvalho Chehab 		if (status < 0)
18639a0bf528SMauro Carvalho Chehab 			goto error;
1864cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
18659a0bf528SMauro Carvalho Chehab 		if (status < 0)
18669a0bf528SMauro Carvalho Chehab 			goto error;
1867cd7a67a4SMauro Carvalho Chehab 		status = dvbt_start(state);
18689a0bf528SMauro Carvalho Chehab 		if (status < 0)
18699a0bf528SMauro Carvalho Chehab 			goto error;
1870cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18719a0bf528SMauro Carvalho Chehab 		break;
18729a0bf528SMauro Carvalho Chehab 	default:
18739a0bf528SMauro Carvalho Chehab 		break;
18749a0bf528SMauro Carvalho Chehab 	}
18759a0bf528SMauro Carvalho Chehab error:
18769a0bf528SMauro Carvalho Chehab 	if (status < 0)
18773a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18789a0bf528SMauro Carvalho Chehab 	return status;
18799a0bf528SMauro Carvalho Chehab }
18809a0bf528SMauro Carvalho Chehab 
1881cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state)
18829a0bf528SMauro Carvalho Chehab {
18839a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18849a0bf528SMauro Carvalho Chehab 
1885cd7a67a4SMauro Carvalho Chehab 	mpegts_stop(state);
18869a0bf528SMauro Carvalho Chehab 	return 0;
18879a0bf528SMauro Carvalho Chehab }
18889a0bf528SMauro Carvalho Chehab 
1889cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
18909a0bf528SMauro Carvalho Chehab {
18919a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18929a0bf528SMauro Carvalho Chehab 
18939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18949a0bf528SMauro Carvalho Chehab 
1895cd7a67a4SMauro Carvalho Chehab 	if (p_lock_status == NULL)
18969a0bf528SMauro Carvalho Chehab 		goto error;
18979a0bf528SMauro Carvalho Chehab 
1898cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
18999a0bf528SMauro Carvalho Chehab 
19009a0bf528SMauro Carvalho Chehab 	/* define the SCU command code */
1901cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
19029a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
19039a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
19049a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1905cd7a67a4SMauro Carvalho Chehab 		status = get_qam_lock_status(state, p_lock_status);
19069a0bf528SMauro Carvalho Chehab 		break;
19079a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1908cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_lock_status(state, p_lock_status);
19099a0bf528SMauro Carvalho Chehab 		break;
19109a0bf528SMauro Carvalho Chehab 	default:
19119a0bf528SMauro Carvalho Chehab 		break;
19129a0bf528SMauro Carvalho Chehab 	}
19139a0bf528SMauro Carvalho Chehab error:
19149a0bf528SMauro Carvalho Chehab 	if (status < 0)
19153a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19169a0bf528SMauro Carvalho Chehab 	return status;
19179a0bf528SMauro Carvalho Chehab }
19189a0bf528SMauro Carvalho Chehab 
1919cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state)
19209a0bf528SMauro Carvalho Chehab {
19219a0bf528SMauro Carvalho Chehab 	int status;
19229a0bf528SMauro Carvalho Chehab 
1923cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
19249a0bf528SMauro Carvalho Chehab 
19259a0bf528SMauro Carvalho Chehab 	/* Allow OC to sync again */
1926cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
19279a0bf528SMauro Carvalho Chehab 	if (status < 0)
19289a0bf528SMauro Carvalho Chehab 		goto error;
1929cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1930cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
19319a0bf528SMauro Carvalho Chehab 	if (status < 0)
19329a0bf528SMauro Carvalho Chehab 		goto error;
19339a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
19349a0bf528SMauro Carvalho Chehab error:
19359a0bf528SMauro Carvalho Chehab 	if (status < 0)
19363a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19379a0bf528SMauro Carvalho Chehab 	return status;
19389a0bf528SMauro Carvalho Chehab }
19399a0bf528SMauro Carvalho Chehab 
1940cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state)
19419a0bf528SMauro Carvalho Chehab {
19429a0bf528SMauro Carvalho Chehab 	int status;
19439a0bf528SMauro Carvalho Chehab 
19449a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19459a0bf528SMauro Carvalho Chehab 
19469a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
19479a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
19489a0bf528SMauro Carvalho Chehab 	if (status < 0)
19499a0bf528SMauro Carvalho Chehab 		goto error;
19509a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
19519a0bf528SMauro Carvalho Chehab 	if (status < 0)
19529a0bf528SMauro Carvalho Chehab 		goto error;
19539a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
19549a0bf528SMauro Carvalho Chehab 	if (status < 0)
19559a0bf528SMauro Carvalho Chehab 		goto error;
19569a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
19579a0bf528SMauro Carvalho Chehab 	if (status < 0)
19589a0bf528SMauro Carvalho Chehab 		goto error;
19599a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
19609a0bf528SMauro Carvalho Chehab 	if (status < 0)
19619a0bf528SMauro Carvalho Chehab 		goto error;
19629a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
19639a0bf528SMauro Carvalho Chehab 	if (status < 0)
19649a0bf528SMauro Carvalho Chehab 		goto error;
19659a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
19669a0bf528SMauro Carvalho Chehab 	if (status < 0)
19679a0bf528SMauro Carvalho Chehab 		goto error;
19689a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
19699a0bf528SMauro Carvalho Chehab 	if (status < 0)
19709a0bf528SMauro Carvalho Chehab 		goto error;
19719a0bf528SMauro Carvalho Chehab 
19729a0bf528SMauro Carvalho Chehab 	/* Additional configuration */
19739a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_OCR_INVERT__A, 0);
19749a0bf528SMauro Carvalho Chehab 	if (status < 0)
19759a0bf528SMauro Carvalho Chehab 		goto error;
19769a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_LWM__A, 2);
19779a0bf528SMauro Carvalho Chehab 	if (status < 0)
19789a0bf528SMauro Carvalho Chehab 		goto error;
19799a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
19809a0bf528SMauro Carvalho Chehab error:
19819a0bf528SMauro Carvalho Chehab 	if (status < 0)
19823a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19839a0bf528SMauro Carvalho Chehab 
19849a0bf528SMauro Carvalho Chehab 	return status;
19859a0bf528SMauro Carvalho Chehab }
19869a0bf528SMauro Carvalho Chehab 
1987cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state,
1988cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
19899a0bf528SMauro Carvalho Chehab {
19909a0bf528SMauro Carvalho Chehab 	int status;
19919a0bf528SMauro Carvalho Chehab 
1992cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
1993cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
1994cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1995cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1996cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
1997cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
1998cd7a67a4SMauro Carvalho Chehab 	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
1999cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_mode = 0;
2000cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_int_upd_rate = 0;
2001cd7a67a4SMauro Carvalho Chehab 	u32 max_bit_rate = 0;
2002cd7a67a4SMauro Carvalho Chehab 	bool static_clk = false;
20039a0bf528SMauro Carvalho Chehab 
20049a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
20059a0bf528SMauro Carvalho Chehab 
20069a0bf528SMauro Carvalho Chehab 	/* Check insertion of the Reed-Solomon parity bytes */
2007cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
20089a0bf528SMauro Carvalho Chehab 	if (status < 0)
20099a0bf528SMauro Carvalho Chehab 		goto error;
2010cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
20119a0bf528SMauro Carvalho Chehab 	if (status < 0)
20129a0bf528SMauro Carvalho Chehab 		goto error;
2013cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2014cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2015cd7a67a4SMauro Carvalho Chehab 	if (state->m_insert_rs_byte == true) {
20169a0bf528SMauro Carvalho Chehab 		/* enable parity symbol forward */
2017cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
20189a0bf528SMauro Carvalho Chehab 		/* MVAL disable during parity bytes */
2019cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
20209a0bf528SMauro Carvalho Chehab 		/* TS burst length to 204 */
2021cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_burst_len = 204;
20229a0bf528SMauro Carvalho Chehab 	}
20239a0bf528SMauro Carvalho Chehab 
20249a0bf528SMauro Carvalho Chehab 	/* Check serial or parrallel output */
2025cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2026cd7a67a4SMauro Carvalho Chehab 	if (state->m_enable_parallel == false) {
20279a0bf528SMauro Carvalho Chehab 		/* MPEG data output is serial -> set ipr_mode[0] */
2028cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
20299a0bf528SMauro Carvalho Chehab 	}
20309a0bf528SMauro Carvalho Chehab 
2031cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
20329a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2033cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbt_bitrate;
2034cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 3;
2035cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xC00000;
2036cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbt_static_clk;
20379a0bf528SMauro Carvalho Chehab 		break;
20389a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
20399a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2040cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 0x0004;
2041cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
2042cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbc_bitrate;
2043cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbc_static_clk;
20449a0bf528SMauro Carvalho Chehab 		break;
20459a0bf528SMauro Carvalho Chehab 	default:
20469a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
20479a0bf528SMauro Carvalho Chehab 	}		/* switch (standard) */
20489a0bf528SMauro Carvalho Chehab 	if (status < 0)
20499a0bf528SMauro Carvalho Chehab 		goto error;
20509a0bf528SMauro Carvalho Chehab 
20519a0bf528SMauro Carvalho Chehab 	/* Configure DTO's */
2052cd7a67a4SMauro Carvalho Chehab 	if (static_clk) {
2053cd7a67a4SMauro Carvalho Chehab 		u32 bit_rate = 0;
20549a0bf528SMauro Carvalho Chehab 
20559a0bf528SMauro Carvalho Chehab 		/* Rational DTO for MCLK source (static MCLK rate),
20569a0bf528SMauro Carvalho Chehab 			Dynamic DTO for optimal grouping
20579a0bf528SMauro Carvalho Chehab 			(avoid intra-packet gaps),
20589a0bf528SMauro Carvalho Chehab 			DTO offset enable to sync TS burst with MSTRT */
2059cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
20609a0bf528SMauro Carvalho Chehab 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2061cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
20629a0bf528SMauro Carvalho Chehab 				FEC_OC_FCT_MODE_VIRT_ENA__M);
20639a0bf528SMauro Carvalho Chehab 
20649a0bf528SMauro Carvalho Chehab 		/* Check user defined bitrate */
2065cd7a67a4SMauro Carvalho Chehab 		bit_rate = max_bit_rate;
2066cd7a67a4SMauro Carvalho Chehab 		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
2067cd7a67a4SMauro Carvalho Chehab 			bit_rate = 75900000UL;
20689a0bf528SMauro Carvalho Chehab 		}
20699a0bf528SMauro Carvalho Chehab 		/* Rational DTO period:
20709a0bf528SMauro Carvalho Chehab 			dto_period = (Fsys / bitrate) - 2
20719a0bf528SMauro Carvalho Chehab 
2072cd7a67a4SMauro Carvalho Chehab 			result should be floored,
20739a0bf528SMauro Carvalho Chehab 			to make sure >= requested bitrate
20749a0bf528SMauro Carvalho Chehab 			*/
2075cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2076cd7a67a4SMauro Carvalho Chehab 						* 1000) / bit_rate);
2077cd7a67a4SMauro Carvalho Chehab 		if (fec_oc_dto_period <= 2)
2078cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period = 0;
20799a0bf528SMauro Carvalho Chehab 		else
2080cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period -= 2;
2081cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 8;
20829a0bf528SMauro Carvalho Chehab 	} else {
2083cd7a67a4SMauro Carvalho Chehab 		/* (commonAttr->static_clk == false) => dynamic mode */
2084cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2085cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2086cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 5;
20879a0bf528SMauro Carvalho Chehab 	}
20889a0bf528SMauro Carvalho Chehab 
20899a0bf528SMauro Carvalho Chehab 	/* Write appropriate registers with requested configuration */
2090cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
20919a0bf528SMauro Carvalho Chehab 	if (status < 0)
20929a0bf528SMauro Carvalho Chehab 		goto error;
2093cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
20949a0bf528SMauro Carvalho Chehab 	if (status < 0)
20959a0bf528SMauro Carvalho Chehab 		goto error;
2096cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
20979a0bf528SMauro Carvalho Chehab 	if (status < 0)
20989a0bf528SMauro Carvalho Chehab 		goto error;
2099cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
21009a0bf528SMauro Carvalho Chehab 	if (status < 0)
21019a0bf528SMauro Carvalho Chehab 		goto error;
2102cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
21039a0bf528SMauro Carvalho Chehab 	if (status < 0)
21049a0bf528SMauro Carvalho Chehab 		goto error;
2105cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
21069a0bf528SMauro Carvalho Chehab 	if (status < 0)
21079a0bf528SMauro Carvalho Chehab 		goto error;
21089a0bf528SMauro Carvalho Chehab 
21099a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
2110cd7a67a4SMauro Carvalho Chehab 	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
21119a0bf528SMauro Carvalho Chehab 	if (status < 0)
21129a0bf528SMauro Carvalho Chehab 		goto error;
2113ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2114ab5060cdSMauro Carvalho Chehab 			 fec_oc_tmd_int_upd_rate);
21159a0bf528SMauro Carvalho Chehab 	if (status < 0)
21169a0bf528SMauro Carvalho Chehab 		goto error;
2117cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
21189a0bf528SMauro Carvalho Chehab error:
21199a0bf528SMauro Carvalho Chehab 	if (status < 0)
21203a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
21219a0bf528SMauro Carvalho Chehab 	return status;
21229a0bf528SMauro Carvalho Chehab }
21239a0bf528SMauro Carvalho Chehab 
2124cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state)
21259a0bf528SMauro Carvalho Chehab {
2126cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_invert = 0;
21279a0bf528SMauro Carvalho Chehab 
21289a0bf528SMauro Carvalho Chehab 	/* Data mask for the output data byte */
2129cd7a67a4SMauro Carvalho Chehab 	u16 invert_data_mask =
21309a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
21319a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
21329a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
21339a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
21349a0bf528SMauro Carvalho Chehab 
21359a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21369a0bf528SMauro Carvalho Chehab 
21379a0bf528SMauro Carvalho Chehab 	/* Control selective inversion of output bits */
2138cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2139cd7a67a4SMauro Carvalho Chehab 	if (state->m_invert_data == true)
2140cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= invert_data_mask;
2141cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2142cd7a67a4SMauro Carvalho Chehab 	if (state->m_invert_err == true)
2143cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2144cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2145cd7a67a4SMauro Carvalho Chehab 	if (state->m_invert_str == true)
2146cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2147cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2148cd7a67a4SMauro Carvalho Chehab 	if (state->m_invert_val == true)
2149cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2150cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2151cd7a67a4SMauro Carvalho Chehab 	if (state->m_invert_clk == true)
2152cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
21539a0bf528SMauro Carvalho Chehab 
2154cd7a67a4SMauro Carvalho Chehab 	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
21559a0bf528SMauro Carvalho Chehab }
21569a0bf528SMauro Carvalho Chehab 
21579a0bf528SMauro Carvalho Chehab #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
21589a0bf528SMauro Carvalho Chehab 
2159cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state,
2160cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
21619a0bf528SMauro Carvalho Chehab {
21629a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
21639a0bf528SMauro Carvalho Chehab 	u16 data = 0;
2164cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_if_agc_settings;
21659a0bf528SMauro Carvalho Chehab 
21669a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21679a0bf528SMauro Carvalho Chehab 
2168cd7a67a4SMauro Carvalho Chehab 	if (p_agc_cfg == NULL)
21699a0bf528SMauro Carvalho Chehab 		goto error;
21709a0bf528SMauro Carvalho Chehab 
2171cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
21729a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
21739a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
21749a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
21759a0bf528SMauro Carvalho Chehab 		if (status < 0)
21769a0bf528SMauro Carvalho Chehab 			goto error;
21779a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
21789a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
21799a0bf528SMauro Carvalho Chehab 		if (status < 0)
21809a0bf528SMauro Carvalho Chehab 			goto error;
21819a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
21829a0bf528SMauro Carvalho Chehab 		if (status < 0)
21839a0bf528SMauro Carvalho Chehab 			goto error;
21849a0bf528SMauro Carvalho Chehab 
21859a0bf528SMauro Carvalho Chehab 		/* Enable SCU RF AGC loop */
21869a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
21879a0bf528SMauro Carvalho Chehab 
21889a0bf528SMauro Carvalho Chehab 		/* Polarity */
2189cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
21909a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21919a0bf528SMauro Carvalho Chehab 		else
21929a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21939a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
21949a0bf528SMauro Carvalho Chehab 		if (status < 0)
21959a0bf528SMauro Carvalho Chehab 			goto error;
21969a0bf528SMauro Carvalho Chehab 
21979a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
21989a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
21999a0bf528SMauro Carvalho Chehab 		if (status < 0)
22009a0bf528SMauro Carvalho Chehab 			goto error;
22019a0bf528SMauro Carvalho Chehab 
22029a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2203cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
22049a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
22059a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
22069a0bf528SMauro Carvalho Chehab 
22079a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
22089a0bf528SMauro Carvalho Chehab 		if (status < 0)
22099a0bf528SMauro Carvalho Chehab 			goto error;
22109a0bf528SMauro Carvalho Chehab 
2211cd7a67a4SMauro Carvalho Chehab 		if (is_dvbt(state))
2212cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2213cd7a67a4SMauro Carvalho Chehab 		else if (is_qam(state))
2214cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_qam_if_agc_cfg;
22159a0bf528SMauro Carvalho Chehab 		else
2216cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_atv_if_agc_cfg;
2217cd7a67a4SMauro Carvalho Chehab 		if (p_if_agc_settings == NULL) {
22189a0bf528SMauro Carvalho Chehab 			status = -EINVAL;
22199a0bf528SMauro Carvalho Chehab 			goto error;
22209a0bf528SMauro Carvalho Chehab 		}
22219a0bf528SMauro Carvalho Chehab 
22229a0bf528SMauro Carvalho Chehab 		/* Set TOP, only if IF-AGC is in AUTO mode */
2223cd7a67a4SMauro Carvalho Chehab 		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
2224ab5060cdSMauro Carvalho Chehab 			status = write16(state,
2225ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2226ab5060cdSMauro Carvalho Chehab 					 p_agc_cfg->top);
22279a0bf528SMauro Carvalho Chehab 			if (status < 0)
22289a0bf528SMauro Carvalho Chehab 				goto error;
22299a0bf528SMauro Carvalho Chehab 
22309a0bf528SMauro Carvalho Chehab 		/* Cut-Off current */
2231ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2232ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->cut_off_current);
22339a0bf528SMauro Carvalho Chehab 		if (status < 0)
22349a0bf528SMauro Carvalho Chehab 			goto error;
22359a0bf528SMauro Carvalho Chehab 
22369a0bf528SMauro Carvalho Chehab 		/* Max. output level */
2237ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2238ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->max_output_level);
22399a0bf528SMauro Carvalho Chehab 		if (status < 0)
22409a0bf528SMauro Carvalho Chehab 			goto error;
22419a0bf528SMauro Carvalho Chehab 
22429a0bf528SMauro Carvalho Chehab 		break;
22439a0bf528SMauro Carvalho Chehab 
22449a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
22459a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
22469a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22479a0bf528SMauro Carvalho Chehab 		if (status < 0)
22489a0bf528SMauro Carvalho Chehab 			goto error;
22499a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22509a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22519a0bf528SMauro Carvalho Chehab 		if (status < 0)
22529a0bf528SMauro Carvalho Chehab 			goto error;
22539a0bf528SMauro Carvalho Chehab 
22549a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22559a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22569a0bf528SMauro Carvalho Chehab 		if (status < 0)
22579a0bf528SMauro Carvalho Chehab 			goto error;
22589a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2259cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
22609a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22619a0bf528SMauro Carvalho Chehab 		else
22629a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22639a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22649a0bf528SMauro Carvalho Chehab 		if (status < 0)
22659a0bf528SMauro Carvalho Chehab 			goto error;
22669a0bf528SMauro Carvalho Chehab 
22679a0bf528SMauro Carvalho Chehab 		/* SCU c.o.c. to 0, enabling full control range */
22689a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
22699a0bf528SMauro Carvalho Chehab 		if (status < 0)
22709a0bf528SMauro Carvalho Chehab 			goto error;
22719a0bf528SMauro Carvalho Chehab 
22729a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2273ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2274ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
22759a0bf528SMauro Carvalho Chehab 		if (status < 0)
22769a0bf528SMauro Carvalho Chehab 			goto error;
22779a0bf528SMauro Carvalho Chehab 		break;
22789a0bf528SMauro Carvalho Chehab 
22799a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
22809a0bf528SMauro Carvalho Chehab 		/* Disable RF AGC DAC */
22819a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22829a0bf528SMauro Carvalho Chehab 		if (status < 0)
22839a0bf528SMauro Carvalho Chehab 			goto error;
22849a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22859a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22869a0bf528SMauro Carvalho Chehab 		if (status < 0)
22879a0bf528SMauro Carvalho Chehab 			goto error;
22889a0bf528SMauro Carvalho Chehab 
22899a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
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 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22949a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22959a0bf528SMauro Carvalho Chehab 		if (status < 0)
22969a0bf528SMauro Carvalho Chehab 			goto error;
22979a0bf528SMauro Carvalho Chehab 		break;
22989a0bf528SMauro Carvalho Chehab 
22999a0bf528SMauro Carvalho Chehab 	default:
23009a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
23019a0bf528SMauro Carvalho Chehab 
23029a0bf528SMauro Carvalho Chehab 	}
23039a0bf528SMauro Carvalho Chehab error:
23049a0bf528SMauro Carvalho Chehab 	if (status < 0)
23053a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
23069a0bf528SMauro Carvalho Chehab 	return status;
23079a0bf528SMauro Carvalho Chehab }
23089a0bf528SMauro Carvalho Chehab 
23099a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
23109a0bf528SMauro Carvalho Chehab 
2311cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state,
2312cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
23139a0bf528SMauro Carvalho Chehab {
23149a0bf528SMauro Carvalho Chehab 	u16 data = 0;
23159a0bf528SMauro Carvalho Chehab 	int status = 0;
2316cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_rf_agc_settings;
23179a0bf528SMauro Carvalho Chehab 
23189a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
23199a0bf528SMauro Carvalho Chehab 
2320cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
23219a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
23229a0bf528SMauro Carvalho Chehab 
23239a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23249a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23259a0bf528SMauro Carvalho Chehab 		if (status < 0)
23269a0bf528SMauro Carvalho Chehab 			goto error;
23279a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23289a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23299a0bf528SMauro Carvalho Chehab 		if (status < 0)
23309a0bf528SMauro Carvalho Chehab 			goto error;
23319a0bf528SMauro Carvalho Chehab 
23329a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23339a0bf528SMauro Carvalho Chehab 		if (status < 0)
23349a0bf528SMauro Carvalho Chehab 			goto error;
23359a0bf528SMauro Carvalho Chehab 
23369a0bf528SMauro Carvalho Chehab 		/* Enable SCU IF AGC loop */
23379a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23389a0bf528SMauro Carvalho Chehab 
23399a0bf528SMauro Carvalho Chehab 		/* Polarity */
2340cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23419a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23429a0bf528SMauro Carvalho Chehab 		else
23439a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23449a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23459a0bf528SMauro Carvalho Chehab 		if (status < 0)
23469a0bf528SMauro Carvalho Chehab 			goto error;
23479a0bf528SMauro Carvalho Chehab 
23489a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
23499a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
23509a0bf528SMauro Carvalho Chehab 		if (status < 0)
23519a0bf528SMauro Carvalho Chehab 			goto error;
23529a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2353cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
23549a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
23559a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
23569a0bf528SMauro Carvalho Chehab 
23579a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
23589a0bf528SMauro Carvalho Chehab 		if (status < 0)
23599a0bf528SMauro Carvalho Chehab 			goto error;
23609a0bf528SMauro Carvalho Chehab 
2361cd7a67a4SMauro Carvalho Chehab 		if (is_qam(state))
2362cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
23639a0bf528SMauro Carvalho Chehab 		else
2364cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2365cd7a67a4SMauro Carvalho Chehab 		if (p_rf_agc_settings == NULL)
23669a0bf528SMauro Carvalho Chehab 			return -1;
23679a0bf528SMauro Carvalho Chehab 		/* Restore TOP */
2368ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2369ab5060cdSMauro Carvalho Chehab 				 p_rf_agc_settings->top);
23709a0bf528SMauro Carvalho Chehab 		if (status < 0)
23719a0bf528SMauro Carvalho Chehab 			goto error;
23729a0bf528SMauro Carvalho Chehab 		break;
23739a0bf528SMauro Carvalho Chehab 
23749a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
23759a0bf528SMauro Carvalho Chehab 
23769a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23779a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23789a0bf528SMauro Carvalho Chehab 		if (status < 0)
23799a0bf528SMauro Carvalho Chehab 			goto error;
23809a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23819a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23829a0bf528SMauro Carvalho Chehab 		if (status < 0)
23839a0bf528SMauro Carvalho Chehab 			goto error;
23849a0bf528SMauro Carvalho Chehab 
23859a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23869a0bf528SMauro Carvalho Chehab 		if (status < 0)
23879a0bf528SMauro Carvalho Chehab 			goto error;
23889a0bf528SMauro Carvalho Chehab 
23899a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23909a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23919a0bf528SMauro Carvalho Chehab 
23929a0bf528SMauro Carvalho Chehab 		/* Polarity */
2393cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23949a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23959a0bf528SMauro Carvalho Chehab 		else
23969a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23979a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23989a0bf528SMauro Carvalho Chehab 		if (status < 0)
23999a0bf528SMauro Carvalho Chehab 			goto error;
24009a0bf528SMauro Carvalho Chehab 
24019a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2402ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2403ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
24049a0bf528SMauro Carvalho Chehab 		if (status < 0)
24059a0bf528SMauro Carvalho Chehab 			goto error;
24069a0bf528SMauro Carvalho Chehab 		break;
24079a0bf528SMauro Carvalho Chehab 
24089a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
24099a0bf528SMauro Carvalho Chehab 
24109a0bf528SMauro Carvalho Chehab 		/* Disable If AGC DAC */
24119a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
24129a0bf528SMauro Carvalho Chehab 		if (status < 0)
24139a0bf528SMauro Carvalho Chehab 			goto error;
24149a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
24159a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
24169a0bf528SMauro Carvalho Chehab 		if (status < 0)
24179a0bf528SMauro Carvalho Chehab 			goto error;
24189a0bf528SMauro Carvalho Chehab 
24199a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
24209a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
24219a0bf528SMauro Carvalho Chehab 		if (status < 0)
24229a0bf528SMauro Carvalho Chehab 			goto error;
24239a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24249a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24259a0bf528SMauro Carvalho Chehab 		if (status < 0)
24269a0bf528SMauro Carvalho Chehab 			goto error;
24279a0bf528SMauro Carvalho Chehab 		break;
2428cd7a67a4SMauro Carvalho Chehab 	}		/* switch (agcSettingsIf->ctrl_mode) */
24299a0bf528SMauro Carvalho Chehab 
24309a0bf528SMauro Carvalho Chehab 	/* always set the top to support
24319a0bf528SMauro Carvalho Chehab 		configurations without if-loop */
2432cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
24339a0bf528SMauro Carvalho Chehab error:
24349a0bf528SMauro Carvalho Chehab 	if (status < 0)
24353a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24369a0bf528SMauro Carvalho Chehab 	return status;
24379a0bf528SMauro Carvalho Chehab }
24389a0bf528SMauro Carvalho Chehab 
2439cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state,
2440cd7a67a4SMauro Carvalho Chehab 			       s32 *p_signal_to_noise)
24419a0bf528SMauro Carvalho Chehab {
24429a0bf528SMauro Carvalho Chehab 	int status = 0;
2443cd7a67a4SMauro Carvalho Chehab 	u16 qam_sl_err_power = 0;	/* accum. error between
24449a0bf528SMauro Carvalho Chehab 					raw and sliced symbols */
2445cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
24469a0bf528SMauro Carvalho Chehab 					QAM modulation */
2447cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_mer = 0;	/* QAM MER */
24489a0bf528SMauro Carvalho Chehab 
24499a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24509a0bf528SMauro Carvalho Chehab 
24519a0bf528SMauro Carvalho Chehab 	/* MER calculation */
24529a0bf528SMauro Carvalho Chehab 
24539a0bf528SMauro Carvalho Chehab 	/* get the register value needed for MER */
2454cd7a67a4SMauro Carvalho Chehab 	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
24559a0bf528SMauro Carvalho Chehab 	if (status < 0) {
24563a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24579a0bf528SMauro Carvalho Chehab 		return -EINVAL;
24589a0bf528SMauro Carvalho Chehab 	}
24599a0bf528SMauro Carvalho Chehab 
24609a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
24619a0bf528SMauro Carvalho Chehab 	case QAM_16:
2462cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
24639a0bf528SMauro Carvalho Chehab 		break;
24649a0bf528SMauro Carvalho Chehab 	case QAM_32:
2465cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
24669a0bf528SMauro Carvalho Chehab 		break;
24679a0bf528SMauro Carvalho Chehab 	case QAM_64:
2468cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
24699a0bf528SMauro Carvalho Chehab 		break;
24709a0bf528SMauro Carvalho Chehab 	case QAM_128:
2471cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
24729a0bf528SMauro Carvalho Chehab 		break;
24739a0bf528SMauro Carvalho Chehab 	default:
24749a0bf528SMauro Carvalho Chehab 	case QAM_256:
2475cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
24769a0bf528SMauro Carvalho Chehab 		break;
24779a0bf528SMauro Carvalho Chehab 	}
24789a0bf528SMauro Carvalho Chehab 
2479cd7a67a4SMauro Carvalho Chehab 	if (qam_sl_err_power > 0) {
2480cd7a67a4SMauro Carvalho Chehab 		qam_sl_mer = log10times100(qam_sl_sig_power) -
2481cd7a67a4SMauro Carvalho Chehab 			log10times100((u32) qam_sl_err_power);
24829a0bf528SMauro Carvalho Chehab 	}
2483cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = qam_sl_mer;
24849a0bf528SMauro Carvalho Chehab 
24859a0bf528SMauro Carvalho Chehab 	return status;
24869a0bf528SMauro Carvalho Chehab }
24879a0bf528SMauro Carvalho Chehab 
2488cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state,
2489cd7a67a4SMauro Carvalho Chehab 				s32 *p_signal_to_noise)
24909a0bf528SMauro Carvalho Chehab {
24919a0bf528SMauro Carvalho Chehab 	int status;
2492cd7a67a4SMauro Carvalho Chehab 	u16 reg_data = 0;
2493cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_i = 0;
2494cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_q = 0;
2495cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_sqr_err_exp = 0;
2496cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_tps_pwr_ofs = 0;
2497cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_req_smb_cnt = 0;
2498cd7a67a4SMauro Carvalho Chehab 	u32 tps_cnt = 0;
2499cd7a67a4SMauro Carvalho Chehab 	u32 sqr_err_iq = 0;
25009a0bf528SMauro Carvalho Chehab 	u32 a = 0;
25019a0bf528SMauro Carvalho Chehab 	u32 b = 0;
25029a0bf528SMauro Carvalho Chehab 	u32 c = 0;
2503cd7a67a4SMauro Carvalho Chehab 	u32 i_mer = 0;
2504cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
25059a0bf528SMauro Carvalho Chehab 
25069a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25079a0bf528SMauro Carvalho Chehab 
2508ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2509ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_tps_pwr_ofs);
25109a0bf528SMauro Carvalho Chehab 	if (status < 0)
25119a0bf528SMauro Carvalho Chehab 		goto error;
2512ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2513ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_req_smb_cnt);
25149a0bf528SMauro Carvalho Chehab 	if (status < 0)
25159a0bf528SMauro Carvalho Chehab 		goto error;
2516ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2517ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_sqr_err_exp);
25189a0bf528SMauro Carvalho Chehab 	if (status < 0)
25199a0bf528SMauro Carvalho Chehab 		goto error;
2520ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2521ab5060cdSMauro Carvalho Chehab 			&reg_data);
25229a0bf528SMauro Carvalho Chehab 	if (status < 0)
25239a0bf528SMauro Carvalho Chehab 		goto error;
25249a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_I operational range */
2525cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_i = (u32) reg_data;
2526cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2527cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2528cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_i += 0x00010000UL;
25299a0bf528SMauro Carvalho Chehab 	}
2530cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
25319a0bf528SMauro Carvalho Chehab 	if (status < 0)
25329a0bf528SMauro Carvalho Chehab 		goto error;
25339a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_Q operational range */
2534cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_q = (u32) reg_data;
2535cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2536cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
2537cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_q += 0x00010000UL;
25389a0bf528SMauro Carvalho Chehab 
2539ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2540ab5060cdSMauro Carvalho Chehab 			&transmission_params);
25419a0bf528SMauro Carvalho Chehab 	if (status < 0)
25429a0bf528SMauro Carvalho Chehab 		goto error;
25439a0bf528SMauro Carvalho Chehab 
25449a0bf528SMauro Carvalho Chehab 	/* Check input data for MER */
25459a0bf528SMauro Carvalho Chehab 
25469a0bf528SMauro Carvalho Chehab 	/* MER calculation (in 0.1 dB) without math.h */
2547cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2548cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
2549cd7a67a4SMauro Carvalho Chehab 	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
25509a0bf528SMauro Carvalho Chehab 		/* No error at all, this must be the HW reset value
25519a0bf528SMauro Carvalho Chehab 			* Apparently no first measurement yet
25529a0bf528SMauro Carvalho Chehab 			* Set MER to 0.0 */
2553cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
25549a0bf528SMauro Carvalho Chehab 	} else {
2555cd7a67a4SMauro Carvalho Chehab 		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2556cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_sqr_err_exp;
2557cd7a67a4SMauro Carvalho Chehab 		if ((transmission_params &
25589a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
25599a0bf528SMauro Carvalho Chehab 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2560cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 17;
25619a0bf528SMauro Carvalho Chehab 		else
2562cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 68;
25639a0bf528SMauro Carvalho Chehab 
25649a0bf528SMauro Carvalho Chehab 		/* IMER = 100 * log10 (x)
2565cd7a67a4SMauro Carvalho Chehab 			where x = (eq_reg_td_tps_pwr_ofs^2 *
2566cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
25679a0bf528SMauro Carvalho Chehab 
25689a0bf528SMauro Carvalho Chehab 			=> IMER = a + b -c
2569cd7a67a4SMauro Carvalho Chehab 			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2570cd7a67a4SMauro Carvalho Chehab 			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2571cd7a67a4SMauro Carvalho Chehab 			c = 100 * log10 (sqr_err_iq)
25729a0bf528SMauro Carvalho Chehab 			*/
25739a0bf528SMauro Carvalho Chehab 
25749a0bf528SMauro Carvalho Chehab 		/* log(x) x = 9bits * 9bits->18 bits  */
2575cd7a67a4SMauro Carvalho Chehab 		a = log10times100(eq_reg_td_tps_pwr_ofs *
2576cd7a67a4SMauro Carvalho Chehab 					eq_reg_td_tps_pwr_ofs);
25779a0bf528SMauro Carvalho Chehab 		/* log(x) x = 16bits * 7bits->23 bits  */
2578cd7a67a4SMauro Carvalho Chehab 		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
25799a0bf528SMauro Carvalho Chehab 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
2580cd7a67a4SMauro Carvalho Chehab 		c = log10times100(sqr_err_iq);
25819a0bf528SMauro Carvalho Chehab 
2582cd7a67a4SMauro Carvalho Chehab 		i_mer = a + b - c;
25839a0bf528SMauro Carvalho Chehab 	}
2584cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = i_mer;
25859a0bf528SMauro Carvalho Chehab 
25869a0bf528SMauro Carvalho Chehab error:
25879a0bf528SMauro Carvalho Chehab 	if (status < 0)
25883a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
25899a0bf528SMauro Carvalho Chehab 	return status;
25909a0bf528SMauro Carvalho Chehab }
25919a0bf528SMauro Carvalho Chehab 
2592cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
25939a0bf528SMauro Carvalho Chehab {
25949a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25959a0bf528SMauro Carvalho Chehab 
2596cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = 0;
2597cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
25989a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2599cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
26009a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
26019a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2602cd7a67a4SMauro Carvalho Chehab 		return get_qam_signal_to_noise(state, p_signal_to_noise);
26039a0bf528SMauro Carvalho Chehab 	default:
26049a0bf528SMauro Carvalho Chehab 		break;
26059a0bf528SMauro Carvalho Chehab 	}
26069a0bf528SMauro Carvalho Chehab 	return 0;
26079a0bf528SMauro Carvalho Chehab }
26089a0bf528SMauro Carvalho Chehab 
26099a0bf528SMauro Carvalho Chehab #if 0
2610cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
26119a0bf528SMauro Carvalho Chehab {
26129a0bf528SMauro Carvalho Chehab 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
26139a0bf528SMauro Carvalho Chehab 	int status = 0;
26149a0bf528SMauro Carvalho Chehab 
26159a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26169a0bf528SMauro Carvalho Chehab 
26179a0bf528SMauro Carvalho Chehab 	static s32 QE_SN[] = {
26189a0bf528SMauro Carvalho Chehab 		51,		/* QPSK 1/2 */
26199a0bf528SMauro Carvalho Chehab 		69,		/* QPSK 2/3 */
26209a0bf528SMauro Carvalho Chehab 		79,		/* QPSK 3/4 */
26219a0bf528SMauro Carvalho Chehab 		89,		/* QPSK 5/6 */
26229a0bf528SMauro Carvalho Chehab 		97,		/* QPSK 7/8 */
26239a0bf528SMauro Carvalho Chehab 		108,		/* 16-QAM 1/2 */
26249a0bf528SMauro Carvalho Chehab 		131,		/* 16-QAM 2/3 */
26259a0bf528SMauro Carvalho Chehab 		146,		/* 16-QAM 3/4 */
26269a0bf528SMauro Carvalho Chehab 		156,		/* 16-QAM 5/6 */
26279a0bf528SMauro Carvalho Chehab 		160,		/* 16-QAM 7/8 */
26289a0bf528SMauro Carvalho Chehab 		165,		/* 64-QAM 1/2 */
26299a0bf528SMauro Carvalho Chehab 		187,		/* 64-QAM 2/3 */
26309a0bf528SMauro Carvalho Chehab 		202,		/* 64-QAM 3/4 */
26319a0bf528SMauro Carvalho Chehab 		216,		/* 64-QAM 5/6 */
26329a0bf528SMauro Carvalho Chehab 		225,		/* 64-QAM 7/8 */
26339a0bf528SMauro Carvalho Chehab 	};
26349a0bf528SMauro Carvalho Chehab 
2635cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26369a0bf528SMauro Carvalho Chehab 
26379a0bf528SMauro Carvalho Chehab 	do {
2638cd7a67a4SMauro Carvalho Chehab 		s32 signal_to_noise = 0;
2639cd7a67a4SMauro Carvalho Chehab 		u16 constellation = 0;
2640cd7a67a4SMauro Carvalho Chehab 		u16 code_rate = 0;
2641cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel;
2642cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality;
26439a0bf528SMauro Carvalho Chehab 
2644cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
26459a0bf528SMauro Carvalho Chehab 		if (status < 0)
26469a0bf528SMauro Carvalho Chehab 			break;
2647ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2648ab5060cdSMauro Carvalho Chehab 				&constellation);
26499a0bf528SMauro Carvalho Chehab 		if (status < 0)
26509a0bf528SMauro Carvalho Chehab 			break;
2651cd7a67a4SMauro Carvalho Chehab 		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
26529a0bf528SMauro Carvalho Chehab 
2653ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2654ab5060cdSMauro Carvalho Chehab 				&code_rate);
26559a0bf528SMauro Carvalho Chehab 		if (status < 0)
26569a0bf528SMauro Carvalho Chehab 			break;
2657cd7a67a4SMauro Carvalho Chehab 		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
26589a0bf528SMauro Carvalho Chehab 
2659cd7a67a4SMauro Carvalho Chehab 		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2660cd7a67a4SMauro Carvalho Chehab 		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
26619a0bf528SMauro Carvalho Chehab 			break;
2662cd7a67a4SMauro Carvalho Chehab 		signal_to_noise_rel = signal_to_noise -
2663cd7a67a4SMauro Carvalho Chehab 		    QE_SN[constellation * 5 + code_rate];
2664cd7a67a4SMauro Carvalho Chehab 		ber_quality = 100;
26659a0bf528SMauro Carvalho Chehab 
2666cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2667cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2668cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2669cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2670cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26719a0bf528SMauro Carvalho Chehab 		else
2672cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26739a0bf528SMauro Carvalho Chehab 	} while (0);
26749a0bf528SMauro Carvalho Chehab 	return 0;
26759a0bf528SMauro Carvalho Chehab };
26769a0bf528SMauro Carvalho Chehab 
2677cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
26789a0bf528SMauro Carvalho Chehab {
26799a0bf528SMauro Carvalho Chehab 	int status = 0;
2680cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26819a0bf528SMauro Carvalho Chehab 
26829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26839a0bf528SMauro Carvalho Chehab 
26849a0bf528SMauro Carvalho Chehab 	do {
2685cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise = 0;
2686cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality = 100;
2687cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel = 0;
26889a0bf528SMauro Carvalho Chehab 
2689cd7a67a4SMauro Carvalho Chehab 		status = get_qam_signal_to_noise(state, &signal_to_noise);
26909a0bf528SMauro Carvalho Chehab 		if (status < 0)
26919a0bf528SMauro Carvalho Chehab 			break;
26929a0bf528SMauro Carvalho Chehab 
26939a0bf528SMauro Carvalho Chehab 		switch (state->props.modulation) {
26949a0bf528SMauro Carvalho Chehab 		case QAM_16:
2695cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 200;
26969a0bf528SMauro Carvalho Chehab 			break;
26979a0bf528SMauro Carvalho Chehab 		case QAM_32:
2698cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 230;
26999a0bf528SMauro Carvalho Chehab 			break;	/* Not in NorDig */
27009a0bf528SMauro Carvalho Chehab 		case QAM_64:
2701cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 260;
27029a0bf528SMauro Carvalho Chehab 			break;
27039a0bf528SMauro Carvalho Chehab 		case QAM_128:
2704cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 290;
27059a0bf528SMauro Carvalho Chehab 			break;
27069a0bf528SMauro Carvalho Chehab 		default:
27079a0bf528SMauro Carvalho Chehab 		case QAM_256:
2708cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 320;
27099a0bf528SMauro Carvalho Chehab 			break;
27109a0bf528SMauro Carvalho Chehab 		}
27119a0bf528SMauro Carvalho Chehab 
2712cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2713cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2714cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2715cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2716cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
27179a0bf528SMauro Carvalho Chehab 		else
2718cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
27199a0bf528SMauro Carvalho Chehab 	} while (0);
27209a0bf528SMauro Carvalho Chehab 
27219a0bf528SMauro Carvalho Chehab 	return status;
27229a0bf528SMauro Carvalho Chehab }
27239a0bf528SMauro Carvalho Chehab 
2724cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality)
27259a0bf528SMauro Carvalho Chehab {
27269a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27279a0bf528SMauro Carvalho Chehab 
2728cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
27299a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2730cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_quality(state, p_quality);
27319a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
2732cd7a67a4SMauro Carvalho Chehab 		return get_dvbc_quality(state, p_quality);
27339a0bf528SMauro Carvalho Chehab 	default:
27349a0bf528SMauro Carvalho Chehab 		break;
27359a0bf528SMauro Carvalho Chehab 	}
27369a0bf528SMauro Carvalho Chehab 
27379a0bf528SMauro Carvalho Chehab 	return 0;
27389a0bf528SMauro Carvalho Chehab }
27399a0bf528SMauro Carvalho Chehab #endif
27409a0bf528SMauro Carvalho Chehab 
27419a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
27429a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
27439a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A   0x420060
27449a0bf528SMauro Carvalho Chehab 
27459a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
27469a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
27479a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
27489a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
27499a0bf528SMauro Carvalho Chehab 
27509a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
27519a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
27529a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
27539a0bf528SMauro Carvalho Chehab 
2754cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
27559a0bf528SMauro Carvalho Chehab {
27569a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27579a0bf528SMauro Carvalho Chehab 
27589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27599a0bf528SMauro Carvalho Chehab 
2760cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
27619a0bf528SMauro Carvalho Chehab 		return 0;
2762cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_POWERED_DOWN)
27639a0bf528SMauro Carvalho Chehab 		goto error;
27649a0bf528SMauro Carvalho Chehab 
27659a0bf528SMauro Carvalho Chehab 	if (state->no_i2c_bridge)
27669a0bf528SMauro Carvalho Chehab 		return 0;
27679a0bf528SMauro Carvalho Chehab 
2768ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2769ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
27709a0bf528SMauro Carvalho Chehab 	if (status < 0)
27719a0bf528SMauro Carvalho Chehab 		goto error;
2772cd7a67a4SMauro Carvalho Chehab 	if (b_enable_bridge) {
2773ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2774ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
27759a0bf528SMauro Carvalho Chehab 		if (status < 0)
27769a0bf528SMauro Carvalho Chehab 			goto error;
27779a0bf528SMauro Carvalho Chehab 	} else {
2778ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2779ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
27809a0bf528SMauro Carvalho Chehab 		if (status < 0)
27819a0bf528SMauro Carvalho Chehab 			goto error;
27829a0bf528SMauro Carvalho Chehab 	}
27839a0bf528SMauro Carvalho Chehab 
2784b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
27859a0bf528SMauro Carvalho Chehab 
27869a0bf528SMauro Carvalho Chehab error:
27879a0bf528SMauro Carvalho Chehab 	if (status < 0)
27883a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27899a0bf528SMauro Carvalho Chehab 	return status;
27909a0bf528SMauro Carvalho Chehab }
27919a0bf528SMauro Carvalho Chehab 
2792cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state,
2793cd7a67a4SMauro Carvalho Chehab 		     struct s_cfg_pre_saw *p_pre_saw_cfg)
27949a0bf528SMauro Carvalho Chehab {
27959a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27969a0bf528SMauro Carvalho Chehab 
27979a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27989a0bf528SMauro Carvalho Chehab 
2799cd7a67a4SMauro Carvalho Chehab 	if ((p_pre_saw_cfg == NULL)
2800cd7a67a4SMauro Carvalho Chehab 	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
28019a0bf528SMauro Carvalho Chehab 		goto error;
28029a0bf528SMauro Carvalho Chehab 
2803cd7a67a4SMauro Carvalho Chehab 	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
28049a0bf528SMauro Carvalho Chehab error:
28059a0bf528SMauro Carvalho Chehab 	if (status < 0)
28063a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28079a0bf528SMauro Carvalho Chehab 	return status;
28089a0bf528SMauro Carvalho Chehab }
28099a0bf528SMauro Carvalho Chehab 
2810cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2811cd7a67a4SMauro Carvalho Chehab 		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
28129a0bf528SMauro Carvalho Chehab {
2813cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
2814cd7a67a4SMauro Carvalho Chehab 	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2815cd7a67a4SMauro Carvalho Chehab 	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
28169a0bf528SMauro Carvalho Chehab 	int status;
28179a0bf528SMauro Carvalho Chehab 	unsigned long end;
28189a0bf528SMauro Carvalho Chehab 
28199a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28209a0bf528SMauro Carvalho Chehab 
28219a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
28229a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
28239a0bf528SMauro Carvalho Chehab 	if (status < 0)
28249a0bf528SMauro Carvalho Chehab 		goto error;
28259a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
28269a0bf528SMauro Carvalho Chehab 	if (status < 0)
28279a0bf528SMauro Carvalho Chehab 		goto error;
28289a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
28299a0bf528SMauro Carvalho Chehab 	if (status < 0)
28309a0bf528SMauro Carvalho Chehab 		goto error;
2831cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
28329a0bf528SMauro Carvalho Chehab 	if (status < 0)
28339a0bf528SMauro Carvalho Chehab 		goto error;
2834cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
28359a0bf528SMauro Carvalho Chehab 	if (status < 0)
28369a0bf528SMauro Carvalho Chehab 		goto error;
28379a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
28389a0bf528SMauro Carvalho Chehab 	if (status < 0)
28399a0bf528SMauro Carvalho Chehab 		goto error;
28409a0bf528SMauro Carvalho Chehab 
2841cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
28429a0bf528SMauro Carvalho Chehab 	do {
2843cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
28449a0bf528SMauro Carvalho Chehab 		if (status < 0)
28459a0bf528SMauro Carvalho Chehab 			goto error;
2846cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
2847cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
28483a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
28499a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
28509a0bf528SMauro Carvalho Chehab 		goto error2;
28519a0bf528SMauro Carvalho Chehab 	}
28529a0bf528SMauro Carvalho Chehab error:
28539a0bf528SMauro Carvalho Chehab 	if (status < 0)
28543a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28559a0bf528SMauro Carvalho Chehab error2:
28569a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
28579a0bf528SMauro Carvalho Chehab 	return status;
28589a0bf528SMauro Carvalho Chehab 
28599a0bf528SMauro Carvalho Chehab }
28609a0bf528SMauro Carvalho Chehab 
2861cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count)
28629a0bf528SMauro Carvalho Chehab {
28639a0bf528SMauro Carvalho Chehab 	u16 data = 0;
28649a0bf528SMauro Carvalho Chehab 	int status;
28659a0bf528SMauro Carvalho Chehab 
28669a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28679a0bf528SMauro Carvalho Chehab 
2868cd7a67a4SMauro Carvalho Chehab 	/* start measurement */
28699a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
28709a0bf528SMauro Carvalho Chehab 	if (status < 0)
28719a0bf528SMauro Carvalho Chehab 		goto error;
28729a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 1);
28739a0bf528SMauro Carvalho Chehab 	if (status < 0)
28749a0bf528SMauro Carvalho Chehab 		goto error;
28759a0bf528SMauro Carvalho Chehab 
28769a0bf528SMauro Carvalho Chehab 	*count = 0;
28779a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE0__A, &data);
28789a0bf528SMauro Carvalho Chehab 	if (status < 0)
28799a0bf528SMauro Carvalho Chehab 		goto error;
28809a0bf528SMauro Carvalho Chehab 	if (data == 127)
28819a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28829a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE1__A, &data);
28839a0bf528SMauro Carvalho Chehab 	if (status < 0)
28849a0bf528SMauro Carvalho Chehab 		goto error;
28859a0bf528SMauro Carvalho Chehab 	if (data == 127)
28869a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28879a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE2__A, &data);
28889a0bf528SMauro Carvalho Chehab 	if (status < 0)
28899a0bf528SMauro Carvalho Chehab 		goto error;
28909a0bf528SMauro Carvalho Chehab 	if (data == 127)
28919a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28929a0bf528SMauro Carvalho Chehab 
28939a0bf528SMauro Carvalho Chehab error:
28949a0bf528SMauro Carvalho Chehab 	if (status < 0)
28953a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28969a0bf528SMauro Carvalho Chehab 	return status;
28979a0bf528SMauro Carvalho Chehab }
28989a0bf528SMauro Carvalho Chehab 
2899cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state)
29009a0bf528SMauro Carvalho Chehab {
29019a0bf528SMauro Carvalho Chehab 	u16 count = 0;
29029a0bf528SMauro Carvalho Chehab 	int status;
29039a0bf528SMauro Carvalho Chehab 
29049a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29059a0bf528SMauro Carvalho Chehab 
2906cd7a67a4SMauro Carvalho Chehab 	status = adc_sync_measurement(state, &count);
29079a0bf528SMauro Carvalho Chehab 	if (status < 0)
29089a0bf528SMauro Carvalho Chehab 		goto error;
29099a0bf528SMauro Carvalho Chehab 
29109a0bf528SMauro Carvalho Chehab 	if (count == 1) {
29119a0bf528SMauro Carvalho Chehab 		/* Try sampling on a diffrent edge */
2912cd7a67a4SMauro Carvalho Chehab 		u16 clk_neg = 0;
29139a0bf528SMauro Carvalho Chehab 
2914cd7a67a4SMauro Carvalho Chehab 		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
29159a0bf528SMauro Carvalho Chehab 		if (status < 0)
29169a0bf528SMauro Carvalho Chehab 			goto error;
2917cd7a67a4SMauro Carvalho Chehab 		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
29189a0bf528SMauro Carvalho Chehab 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2919cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2920cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
29219a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
29229a0bf528SMauro Carvalho Chehab 		} else {
2923cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2924cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
29259a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
29269a0bf528SMauro Carvalho Chehab 		}
2927cd7a67a4SMauro Carvalho Chehab 		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
29289a0bf528SMauro Carvalho Chehab 		if (status < 0)
29299a0bf528SMauro Carvalho Chehab 			goto error;
2930cd7a67a4SMauro Carvalho Chehab 		status = adc_sync_measurement(state, &count);
29319a0bf528SMauro Carvalho Chehab 		if (status < 0)
29329a0bf528SMauro Carvalho Chehab 			goto error;
29339a0bf528SMauro Carvalho Chehab 	}
29349a0bf528SMauro Carvalho Chehab 
29359a0bf528SMauro Carvalho Chehab 	if (count < 2)
29369a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
29379a0bf528SMauro Carvalho Chehab error:
29389a0bf528SMauro Carvalho Chehab 	if (status < 0)
29393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
29409a0bf528SMauro Carvalho Chehab 	return status;
29419a0bf528SMauro Carvalho Chehab }
29429a0bf528SMauro Carvalho Chehab 
2943cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state,
2944cd7a67a4SMauro Carvalho Chehab 			       u16 intermediate_freqk_hz,
2945cd7a67a4SMauro Carvalho Chehab 			       s32 tuner_freq_offset, bool is_dtv)
29469a0bf528SMauro Carvalho Chehab {
2947cd7a67a4SMauro Carvalho Chehab 	bool select_pos_image = false;
2948cd7a67a4SMauro Carvalho Chehab 	u32 rf_freq_residual = tuner_freq_offset;
2949cd7a67a4SMauro Carvalho Chehab 	u32 fm_frequency_shift = 0;
2950cd7a67a4SMauro Carvalho Chehab 	bool tuner_mirror = !state->m_b_mirror_freq_spect;
2951cd7a67a4SMauro Carvalho Chehab 	u32 adc_freq;
2952cd7a67a4SMauro Carvalho Chehab 	bool adc_flip;
29539a0bf528SMauro Carvalho Chehab 	int status;
2954cd7a67a4SMauro Carvalho Chehab 	u32 if_freq_actual;
2955cd7a67a4SMauro Carvalho Chehab 	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2956cd7a67a4SMauro Carvalho Chehab 	u32 frequency_shift;
2957cd7a67a4SMauro Carvalho Chehab 	bool image_to_select;
29589a0bf528SMauro Carvalho Chehab 
29599a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29609a0bf528SMauro Carvalho Chehab 
29619a0bf528SMauro Carvalho Chehab 	/*
29629a0bf528SMauro Carvalho Chehab 	   Program frequency shifter
29639a0bf528SMauro Carvalho Chehab 	   No need to account for mirroring on RF
29649a0bf528SMauro Carvalho Chehab 	 */
2965cd7a67a4SMauro Carvalho Chehab 	if (is_dtv) {
2966cd7a67a4SMauro Carvalho Chehab 		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2967cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_QAM_ITU_C) ||
2968cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_DVBT))
2969cd7a67a4SMauro Carvalho Chehab 			select_pos_image = true;
29709a0bf528SMauro Carvalho Chehab 		else
2971cd7a67a4SMauro Carvalho Chehab 			select_pos_image = false;
29729a0bf528SMauro Carvalho Chehab 	}
2973cd7a67a4SMauro Carvalho Chehab 	if (tuner_mirror)
29749a0bf528SMauro Carvalho Chehab 		/* tuner doesn't mirror */
2975cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz +
2976cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual + fm_frequency_shift;
29779a0bf528SMauro Carvalho Chehab 	else
29789a0bf528SMauro Carvalho Chehab 		/* tuner mirrors */
2979cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz -
2980cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual - fm_frequency_shift;
2981cd7a67a4SMauro Carvalho Chehab 	if (if_freq_actual > sampling_frequency / 2) {
29829a0bf528SMauro Carvalho Chehab 		/* adc mirrors */
2983cd7a67a4SMauro Carvalho Chehab 		adc_freq = sampling_frequency - if_freq_actual;
2984cd7a67a4SMauro Carvalho Chehab 		adc_flip = true;
29859a0bf528SMauro Carvalho Chehab 	} else {
29869a0bf528SMauro Carvalho Chehab 		/* adc doesn't mirror */
2987cd7a67a4SMauro Carvalho Chehab 		adc_freq = if_freq_actual;
2988cd7a67a4SMauro Carvalho Chehab 		adc_flip = false;
29899a0bf528SMauro Carvalho Chehab 	}
29909a0bf528SMauro Carvalho Chehab 
2991cd7a67a4SMauro Carvalho Chehab 	frequency_shift = adc_freq;
2992cd7a67a4SMauro Carvalho Chehab 	image_to_select = state->m_rfmirror ^ tuner_mirror ^
2993cd7a67a4SMauro Carvalho Chehab 	    adc_flip ^ select_pos_image;
2994cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_fs_rate_ofs =
2995cd7a67a4SMauro Carvalho Chehab 	    Frac28a((frequency_shift), sampling_frequency);
29969a0bf528SMauro Carvalho Chehab 
2997cd7a67a4SMauro Carvalho Chehab 	if (image_to_select)
2998cd7a67a4SMauro Carvalho Chehab 		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
29999a0bf528SMauro Carvalho Chehab 
30009a0bf528SMauro Carvalho Chehab 	/* Program frequency shifter with tuner offset compensation */
3001cd7a67a4SMauro Carvalho Chehab 	/* frequency_shift += tuner_freq_offset; TODO */
30029a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
3003cd7a67a4SMauro Carvalho Chehab 			 state->m_iqm_fs_rate_ofs);
30049a0bf528SMauro Carvalho Chehab 	if (status < 0)
30053a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
30069a0bf528SMauro Carvalho Chehab 	return status;
30079a0bf528SMauro Carvalho Chehab }
30089a0bf528SMauro Carvalho Chehab 
3009cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv)
30109a0bf528SMauro Carvalho Chehab {
3011cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt = 0;
3012cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_min = 0;
3013cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_max = 0;
3014cd7a67a4SMauro Carvalho Chehab 	u16 clp_cyclen = 0;
3015cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_min = 0;
3016cd7a67a4SMauro Carvalho Chehab 	u16 clp_dir_to = 0;
3017cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_min = 0;
3018cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_max = 0;
3019cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_max = 0;
3020cd7a67a4SMauro Carvalho Chehab 	u16 sns_dir_to = 0;
3021cd7a67a4SMauro Carvalho Chehab 	u16 ki_innergain_min = 0;
3022cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt = 0;
3023cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_min = 0;
3024cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_max = 0;
30259a0bf528SMauro Carvalho Chehab 	u16 data = 0;
3026cd7a67a4SMauro Carvalho Chehab 	u16 fast_clp_ctrl_delay = 0;
3027cd7a67a4SMauro Carvalho Chehab 	u16 clp_ctrl_mode = 0;
30289a0bf528SMauro Carvalho Chehab 	int status = 0;
30299a0bf528SMauro Carvalho Chehab 
30309a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
30319a0bf528SMauro Carvalho Chehab 
30329a0bf528SMauro Carvalho Chehab 	/* Common settings */
3033cd7a67a4SMauro Carvalho Chehab 	sns_sum_max = 1023;
3034cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_min = 2047;
3035cd7a67a4SMauro Carvalho Chehab 	clp_cyclen = 500;
3036cd7a67a4SMauro Carvalho Chehab 	clp_sum_max = 1023;
30379a0bf528SMauro Carvalho Chehab 
30389a0bf528SMauro Carvalho Chehab 	/* AGCInit() not available for DVBT; init done in microcode */
3039cd7a67a4SMauro Carvalho Chehab 	if (!is_qam(state)) {
30403a4398f5SMauro Carvalho Chehab 		pr_err("%s: mode %d is not DVB-C\n",
30413a4398f5SMauro Carvalho Chehab 		       __func__, state->m_operation_mode);
30429a0bf528SMauro Carvalho Chehab 		return -EINVAL;
30439a0bf528SMauro Carvalho Chehab 	}
30449a0bf528SMauro Carvalho Chehab 
30459a0bf528SMauro Carvalho Chehab 	/* FIXME: Analog TV AGC require different settings */
30469a0bf528SMauro Carvalho Chehab 
30479a0bf528SMauro Carvalho Chehab 	/* Standard specific settings */
3048cd7a67a4SMauro Carvalho Chehab 	clp_sum_min = 8;
3049cd7a67a4SMauro Carvalho Chehab 	clp_dir_to = (u16) -9;
3050cd7a67a4SMauro Carvalho Chehab 	clp_ctrl_mode = 0;
3051cd7a67a4SMauro Carvalho Chehab 	sns_sum_min = 8;
3052cd7a67a4SMauro Carvalho Chehab 	sns_dir_to = (u16) -9;
3053cd7a67a4SMauro Carvalho Chehab 	ki_innergain_min = (u16) -1030;
3054cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_max = 0x2380;
3055cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt = 0x2380;
3056cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_min = 0x0511;
3057cd7a67a4SMauro Carvalho Chehab 	ingain_tgt = 0x0511;
3058cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_max = 5119;
3059cd7a67a4SMauro Carvalho Chehab 	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
30609a0bf528SMauro Carvalho Chehab 
3061ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3062ab5060cdSMauro Carvalho Chehab 			 fast_clp_ctrl_delay);
30639a0bf528SMauro Carvalho Chehab 	if (status < 0)
30649a0bf528SMauro Carvalho Chehab 		goto error;
30659a0bf528SMauro Carvalho Chehab 
3066cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
30679a0bf528SMauro Carvalho Chehab 	if (status < 0)
30689a0bf528SMauro Carvalho Chehab 		goto error;
3069cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
30709a0bf528SMauro Carvalho Chehab 	if (status < 0)
30719a0bf528SMauro Carvalho Chehab 		goto error;
3072cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
30739a0bf528SMauro Carvalho Chehab 	if (status < 0)
30749a0bf528SMauro Carvalho Chehab 		goto error;
3075cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
30769a0bf528SMauro Carvalho Chehab 	if (status < 0)
30779a0bf528SMauro Carvalho Chehab 		goto error;
3078ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3079ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_min);
30809a0bf528SMauro Carvalho Chehab 	if (status < 0)
30819a0bf528SMauro Carvalho Chehab 		goto error;
3082ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3083ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_max);
30849a0bf528SMauro Carvalho Chehab 	if (status < 0)
30859a0bf528SMauro Carvalho Chehab 		goto error;
30869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
30879a0bf528SMauro Carvalho Chehab 	if (status < 0)
30889a0bf528SMauro Carvalho Chehab 		goto error;
30899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
30909a0bf528SMauro Carvalho Chehab 	if (status < 0)
30919a0bf528SMauro Carvalho Chehab 		goto error;
30929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
30939a0bf528SMauro Carvalho Chehab 	if (status < 0)
30949a0bf528SMauro Carvalho Chehab 		goto error;
30959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
30969a0bf528SMauro Carvalho Chehab 	if (status < 0)
30979a0bf528SMauro Carvalho Chehab 		goto error;
3098cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
30999a0bf528SMauro Carvalho Chehab 	if (status < 0)
31009a0bf528SMauro Carvalho Chehab 		goto error;
3101cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
31029a0bf528SMauro Carvalho Chehab 	if (status < 0)
31039a0bf528SMauro Carvalho Chehab 		goto error;
31049a0bf528SMauro Carvalho Chehab 
3105ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3106ab5060cdSMauro Carvalho Chehab 			 ki_innergain_min);
31079a0bf528SMauro Carvalho Chehab 	if (status < 0)
31089a0bf528SMauro Carvalho Chehab 		goto error;
3109ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3110ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt);
31119a0bf528SMauro Carvalho Chehab 	if (status < 0)
31129a0bf528SMauro Carvalho Chehab 		goto error;
3113cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
31149a0bf528SMauro Carvalho Chehab 	if (status < 0)
31159a0bf528SMauro Carvalho Chehab 		goto error;
31169a0bf528SMauro Carvalho Chehab 
31179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
31189a0bf528SMauro Carvalho Chehab 	if (status < 0)
31199a0bf528SMauro Carvalho Chehab 		goto error;
31209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
31219a0bf528SMauro Carvalho Chehab 	if (status < 0)
31229a0bf528SMauro Carvalho Chehab 		goto error;
31239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
31249a0bf528SMauro Carvalho Chehab 	if (status < 0)
31259a0bf528SMauro Carvalho Chehab 		goto error;
31269a0bf528SMauro Carvalho Chehab 
31279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
31289a0bf528SMauro Carvalho Chehab 	if (status < 0)
31299a0bf528SMauro Carvalho Chehab 		goto error;
3130cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
31319a0bf528SMauro Carvalho Chehab 	if (status < 0)
31329a0bf528SMauro Carvalho Chehab 		goto error;
3133cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
31349a0bf528SMauro Carvalho Chehab 	if (status < 0)
31359a0bf528SMauro Carvalho Chehab 		goto error;
3136cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
31379a0bf528SMauro Carvalho Chehab 	if (status < 0)
31389a0bf528SMauro Carvalho Chehab 		goto error;
3139cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
31409a0bf528SMauro Carvalho Chehab 	if (status < 0)
31419a0bf528SMauro Carvalho Chehab 		goto error;
31429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
31439a0bf528SMauro Carvalho Chehab 	if (status < 0)
31449a0bf528SMauro Carvalho Chehab 		goto error;
31459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
31469a0bf528SMauro Carvalho Chehab 	if (status < 0)
31479a0bf528SMauro Carvalho Chehab 		goto error;
31489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
31499a0bf528SMauro Carvalho Chehab 	if (status < 0)
31509a0bf528SMauro Carvalho Chehab 		goto error;
31519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
31529a0bf528SMauro Carvalho Chehab 	if (status < 0)
31539a0bf528SMauro Carvalho Chehab 		goto error;
31549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
31559a0bf528SMauro Carvalho Chehab 	if (status < 0)
31569a0bf528SMauro Carvalho Chehab 		goto error;
31579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
31589a0bf528SMauro Carvalho Chehab 	if (status < 0)
31599a0bf528SMauro Carvalho Chehab 		goto error;
31609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
31619a0bf528SMauro Carvalho Chehab 	if (status < 0)
31629a0bf528SMauro Carvalho Chehab 		goto error;
31639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
31649a0bf528SMauro Carvalho Chehab 	if (status < 0)
31659a0bf528SMauro Carvalho Chehab 		goto error;
31669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
31679a0bf528SMauro Carvalho Chehab 	if (status < 0)
31689a0bf528SMauro Carvalho Chehab 		goto error;
31699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
31709a0bf528SMauro Carvalho Chehab 	if (status < 0)
31719a0bf528SMauro Carvalho Chehab 		goto error;
31729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
31739a0bf528SMauro Carvalho Chehab 	if (status < 0)
31749a0bf528SMauro Carvalho Chehab 		goto error;
31759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
31769a0bf528SMauro Carvalho Chehab 	if (status < 0)
31779a0bf528SMauro Carvalho Chehab 		goto error;
31789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
31799a0bf528SMauro Carvalho Chehab 	if (status < 0)
31809a0bf528SMauro Carvalho Chehab 		goto error;
31819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
31829a0bf528SMauro Carvalho Chehab 	if (status < 0)
31839a0bf528SMauro Carvalho Chehab 		goto error;
31849a0bf528SMauro Carvalho Chehab 
31859a0bf528SMauro Carvalho Chehab 	/* Initialize inner-loop KI gain factors */
31869a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_AGC_KI__A, &data);
31879a0bf528SMauro Carvalho Chehab 	if (status < 0)
31889a0bf528SMauro Carvalho Chehab 		goto error;
31899a0bf528SMauro Carvalho Chehab 
31909a0bf528SMauro Carvalho Chehab 	data = 0x0657;
31919a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_RF__M;
31929a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
31939a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_IF__M;
31949a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
31959a0bf528SMauro Carvalho Chehab 
31969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI__A, data);
31979a0bf528SMauro Carvalho Chehab error:
31989a0bf528SMauro Carvalho Chehab 	if (status < 0)
31993a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
32009a0bf528SMauro Carvalho Chehab 	return status;
32019a0bf528SMauro Carvalho Chehab }
32029a0bf528SMauro Carvalho Chehab 
3203cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
32049a0bf528SMauro Carvalho Chehab {
32059a0bf528SMauro Carvalho Chehab 	int status;
32069a0bf528SMauro Carvalho Chehab 
32079a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3208cd7a67a4SMauro Carvalho Chehab 	if (packet_err == NULL)
32099a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
32109a0bf528SMauro Carvalho Chehab 	else
3211ab5060cdSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3212ab5060cdSMauro Carvalho Chehab 				packet_err);
32139a0bf528SMauro Carvalho Chehab 	if (status < 0)
32143a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
32159a0bf528SMauro Carvalho Chehab 	return status;
32169a0bf528SMauro Carvalho Chehab }
32179a0bf528SMauro Carvalho Chehab 
3218cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state,
32199a0bf528SMauro Carvalho Chehab 			 u16 cmd, u16 subcmd,
32209a0bf528SMauro Carvalho Chehab 			 u16 param0, u16 param1, u16 param2,
32219a0bf528SMauro Carvalho Chehab 			 u16 param3, u16 param4)
32229a0bf528SMauro Carvalho Chehab {
3223cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
3224cd7a67a4SMauro Carvalho Chehab 	u16 err_code = 0;
3225cd7a67a4SMauro Carvalho Chehab 	u16 retry_cnt = 0;
3226cd7a67a4SMauro Carvalho Chehab 	u16 sc_exec = 0;
32279a0bf528SMauro Carvalho Chehab 	int status;
32289a0bf528SMauro Carvalho Chehab 
32299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3230cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3231cd7a67a4SMauro Carvalho Chehab 	if (sc_exec != 1) {
32329a0bf528SMauro Carvalho Chehab 		/* SC is not running */
32339a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32349a0bf528SMauro Carvalho Chehab 	}
32359a0bf528SMauro Carvalho Chehab 	if (status < 0)
32369a0bf528SMauro Carvalho Chehab 		goto error;
32379a0bf528SMauro Carvalho Chehab 
32389a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready to receive command */
3239cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32409a0bf528SMauro Carvalho Chehab 	do {
3241b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3242cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3243cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3244cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3245cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32469a0bf528SMauro Carvalho Chehab 		goto error;
32479a0bf528SMauro Carvalho Chehab 
32489a0bf528SMauro Carvalho Chehab 	/* Write sub-command */
32499a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32509a0bf528SMauro Carvalho Chehab 		/* All commands using sub-cmd */
32519a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32529a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32539a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32549a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
32559a0bf528SMauro Carvalho Chehab 		if (status < 0)
32569a0bf528SMauro Carvalho Chehab 			goto error;
32579a0bf528SMauro Carvalho Chehab 		break;
32589a0bf528SMauro Carvalho Chehab 	default:
32599a0bf528SMauro Carvalho Chehab 		/* Do nothing */
32609a0bf528SMauro Carvalho Chehab 		break;
32619a0bf528SMauro Carvalho Chehab 	}
32629a0bf528SMauro Carvalho Chehab 
32639a0bf528SMauro Carvalho Chehab 	/* Write needed parameters and the command */
32649a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32659a0bf528SMauro Carvalho Chehab 		/* All commands using 5 parameters */
32669a0bf528SMauro Carvalho Chehab 		/* All commands using 4 parameters */
32679a0bf528SMauro Carvalho Chehab 		/* All commands using 3 parameters */
32689a0bf528SMauro Carvalho Chehab 		/* All commands using 2 parameters */
32699a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32709a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32719a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32729a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
32739a0bf528SMauro Carvalho Chehab 		/* All commands using 1 parameters */
32749a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32759a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32769a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
32779a0bf528SMauro Carvalho Chehab 		/* All commands using 0 parameters */
32789a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32799a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
32809a0bf528SMauro Carvalho Chehab 		/* Write command */
32819a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
32829a0bf528SMauro Carvalho Chehab 		break;
32839a0bf528SMauro Carvalho Chehab 	default:
32849a0bf528SMauro Carvalho Chehab 		/* Unknown command */
32859a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32869a0bf528SMauro Carvalho Chehab 	}
32879a0bf528SMauro Carvalho Chehab 	if (status < 0)
32889a0bf528SMauro Carvalho Chehab 		goto error;
32899a0bf528SMauro Carvalho Chehab 
32909a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready processing command */
3291cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32929a0bf528SMauro Carvalho Chehab 	do {
3293b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3294cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3295cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3296cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3297cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32989a0bf528SMauro Carvalho Chehab 		goto error;
32999a0bf528SMauro Carvalho Chehab 
33009a0bf528SMauro Carvalho Chehab 	/* Check for illegal cmd */
3301cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3302cd7a67a4SMauro Carvalho Chehab 	if (err_code == 0xFFFF) {
33039a0bf528SMauro Carvalho Chehab 		/* illegal command */
33049a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33059a0bf528SMauro Carvalho Chehab 	}
33069a0bf528SMauro Carvalho Chehab 	if (status < 0)
33079a0bf528SMauro Carvalho Chehab 		goto error;
33089a0bf528SMauro Carvalho Chehab 
33099a0bf528SMauro Carvalho Chehab 	/* Retreive results parameters from SC */
33109a0bf528SMauro Carvalho Chehab 	switch (cmd) {
33119a0bf528SMauro Carvalho Chehab 		/* All commands yielding 5 results */
33129a0bf528SMauro Carvalho Chehab 		/* All commands yielding 4 results */
33139a0bf528SMauro Carvalho Chehab 		/* All commands yielding 3 results */
33149a0bf528SMauro Carvalho Chehab 		/* All commands yielding 2 results */
33159a0bf528SMauro Carvalho Chehab 		/* All commands yielding 1 result */
33169a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
33179a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
33189a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
33199a0bf528SMauro Carvalho Chehab 		/* All commands yielding 0 results */
33209a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
33219a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_TIMER:
33229a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
33239a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
33249a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
33259a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
33269a0bf528SMauro Carvalho Chehab 		break;
33279a0bf528SMauro Carvalho Chehab 	default:
33289a0bf528SMauro Carvalho Chehab 		/* Unknown command */
33299a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33309a0bf528SMauro Carvalho Chehab 		break;
33319a0bf528SMauro Carvalho Chehab 	}			/* switch (cmd->cmd) */
33329a0bf528SMauro Carvalho Chehab error:
33339a0bf528SMauro Carvalho Chehab 	if (status < 0)
33343a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33359a0bf528SMauro Carvalho Chehab 	return status;
33369a0bf528SMauro Carvalho Chehab }
33379a0bf528SMauro Carvalho Chehab 
3338cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state)
33399a0bf528SMauro Carvalho Chehab {
3340cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRX_POWER_UP;
33419a0bf528SMauro Carvalho Chehab 	int status;
33429a0bf528SMauro Carvalho Chehab 
33439a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3344cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
33459a0bf528SMauro Carvalho Chehab 	if (status < 0)
33463a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33479a0bf528SMauro Carvalho Chehab 	return status;
33489a0bf528SMauro Carvalho Chehab }
33499a0bf528SMauro Carvalho Chehab 
3350cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
33519a0bf528SMauro Carvalho Chehab {
33529a0bf528SMauro Carvalho Chehab 	int status;
33539a0bf528SMauro Carvalho Chehab 
33549a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33559a0bf528SMauro Carvalho Chehab 	if (*enabled == true)
33569a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
33579a0bf528SMauro Carvalho Chehab 	else
33589a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
33599a0bf528SMauro Carvalho Chehab 	if (status < 0)
33603a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33619a0bf528SMauro Carvalho Chehab 	return status;
33629a0bf528SMauro Carvalho Chehab }
33639a0bf528SMauro Carvalho Chehab 
33649a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K     4000
3365cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
33669a0bf528SMauro Carvalho Chehab {
33679a0bf528SMauro Carvalho Chehab 
33689a0bf528SMauro Carvalho Chehab 	int status;
33699a0bf528SMauro Carvalho Chehab 
33709a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33719a0bf528SMauro Carvalho Chehab 	if (*enabled == true) {
33729a0bf528SMauro Carvalho Chehab 		/* write mask to 1 */
33739a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
33749a0bf528SMauro Carvalho Chehab 				   DEFAULT_FR_THRES_8K);
33759a0bf528SMauro Carvalho Chehab 	} else {
33769a0bf528SMauro Carvalho Chehab 		/* write mask to 0 */
33779a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
33789a0bf528SMauro Carvalho Chehab 	}
33799a0bf528SMauro Carvalho Chehab 	if (status < 0)
33803a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33819a0bf528SMauro Carvalho Chehab 
33829a0bf528SMauro Carvalho Chehab 	return status;
33839a0bf528SMauro Carvalho Chehab }
33849a0bf528SMauro Carvalho Chehab 
3385cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3386cd7a67a4SMauro Carvalho Chehab 				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
33879a0bf528SMauro Carvalho Chehab {
33889a0bf528SMauro Carvalho Chehab 	u16 data = 0;
33899a0bf528SMauro Carvalho Chehab 	int status;
33909a0bf528SMauro Carvalho Chehab 
33919a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33929a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
33939a0bf528SMauro Carvalho Chehab 	if (status < 0)
33949a0bf528SMauro Carvalho Chehab 		goto error;
33959a0bf528SMauro Carvalho Chehab 
3396cd7a67a4SMauro Carvalho Chehab 	switch (echo_thres->fft_mode) {
33979a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_2K:
33989a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3399cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
34009a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
34019a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
34029a0bf528SMauro Carvalho Chehab 		break;
34039a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_8K:
34049a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3405cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
34069a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
34079a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
34089a0bf528SMauro Carvalho Chehab 		break;
34099a0bf528SMauro Carvalho Chehab 	default:
34109a0bf528SMauro Carvalho Chehab 		return -EINVAL;
34119a0bf528SMauro Carvalho Chehab 	}
34129a0bf528SMauro Carvalho Chehab 
34139a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
34149a0bf528SMauro Carvalho Chehab error:
34159a0bf528SMauro Carvalho Chehab 	if (status < 0)
34163a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34179a0bf528SMauro Carvalho Chehab 	return status;
34189a0bf528SMauro Carvalho Chehab }
34199a0bf528SMauro Carvalho Chehab 
3420cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3421cd7a67a4SMauro Carvalho Chehab 			       enum drxk_cfg_dvbt_sqi_speed *speed)
34229a0bf528SMauro Carvalho Chehab {
34239a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
34249a0bf528SMauro Carvalho Chehab 
34259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34269a0bf528SMauro Carvalho Chehab 
34279a0bf528SMauro Carvalho Chehab 	switch (*speed) {
34289a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_FAST:
34299a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_MEDIUM:
34309a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_SLOW:
34319a0bf528SMauro Carvalho Chehab 		break;
34329a0bf528SMauro Carvalho Chehab 	default:
34339a0bf528SMauro Carvalho Chehab 		goto error;
34349a0bf528SMauro Carvalho Chehab 	}
34359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
34369a0bf528SMauro Carvalho Chehab 			   (u16) *speed);
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 
34459a0bf528SMauro Carvalho Chehab /**
34469a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
34479a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34489a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34499a0bf528SMauro Carvalho Chehab *
34509a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
34519a0bf528SMauro Carvalho Chehab *
34529a0bf528SMauro Carvalho Chehab */
3453cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state)
34549a0bf528SMauro Carvalho Chehab {
34559a0bf528SMauro Carvalho Chehab 	int status;
34569a0bf528SMauro Carvalho Chehab 	bool setincenable = false;
34579a0bf528SMauro Carvalho Chehab 	bool setfrenable = true;
34589a0bf528SMauro Carvalho Chehab 
3459cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3460cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
34619a0bf528SMauro Carvalho Chehab 
34629a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3463cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
34649a0bf528SMauro Carvalho Chehab 	if (status < 0)
34659a0bf528SMauro Carvalho Chehab 		goto error;
3466cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
34679a0bf528SMauro Carvalho Chehab 	if (status < 0)
34689a0bf528SMauro Carvalho Chehab 		goto error;
3469cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
34709a0bf528SMauro Carvalho Chehab 	if (status < 0)
34719a0bf528SMauro Carvalho Chehab 		goto error;
3472cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
34739a0bf528SMauro Carvalho Chehab 	if (status < 0)
34749a0bf528SMauro Carvalho Chehab 		goto error;
3475ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3476ab5060cdSMauro Carvalho Chehab 			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
34779a0bf528SMauro Carvalho Chehab error:
34789a0bf528SMauro Carvalho Chehab 	if (status < 0)
34793a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34809a0bf528SMauro Carvalho Chehab 	return status;
34819a0bf528SMauro Carvalho Chehab }
34829a0bf528SMauro Carvalho Chehab 
34839a0bf528SMauro Carvalho Chehab /*============================================================================*/
34849a0bf528SMauro Carvalho Chehab 
34859a0bf528SMauro Carvalho Chehab /**
34869a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
34879a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34889a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34899a0bf528SMauro Carvalho Chehab *
34909a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
34919a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
34929a0bf528SMauro Carvalho Chehab */
3493cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
3494cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode)
34959a0bf528SMauro Carvalho Chehab {
3496cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
34979a0bf528SMauro Carvalho Chehab 	u16 data = 0;
34989a0bf528SMauro Carvalho Chehab 	int status;
34999a0bf528SMauro Carvalho Chehab 
35009a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
35019a0bf528SMauro Carvalho Chehab 
3502cd7a67a4SMauro Carvalho Chehab 	power_up_dvbt(state);
35039a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
3504cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_dvbt(state);
35059a0bf528SMauro Carvalho Chehab 	/* send OFDM reset command */
3506ab5060cdSMauro Carvalho Chehab 	status = scu_command(state,
3507ab5060cdSMauro Carvalho Chehab 			     SCU_RAM_COMMAND_STANDARD_OFDM
3508ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3509ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
35109a0bf528SMauro Carvalho Chehab 	if (status < 0)
35119a0bf528SMauro Carvalho Chehab 		goto error;
35129a0bf528SMauro Carvalho Chehab 
35139a0bf528SMauro Carvalho Chehab 	/* send OFDM setenv command */
3514ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3515ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3516ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
35179a0bf528SMauro Carvalho Chehab 	if (status < 0)
35189a0bf528SMauro Carvalho Chehab 		goto error;
35199a0bf528SMauro Carvalho Chehab 
35209a0bf528SMauro Carvalho Chehab 	/* reset datapath for OFDM, processors first */
35219a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
35229a0bf528SMauro Carvalho Chehab 	if (status < 0)
35239a0bf528SMauro Carvalho Chehab 		goto error;
35249a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
35259a0bf528SMauro Carvalho Chehab 	if (status < 0)
35269a0bf528SMauro Carvalho Chehab 		goto error;
35279a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
35289a0bf528SMauro Carvalho Chehab 	if (status < 0)
35299a0bf528SMauro Carvalho Chehab 		goto error;
35309a0bf528SMauro Carvalho Chehab 
35319a0bf528SMauro Carvalho Chehab 	/* IQM setup */
35329a0bf528SMauro Carvalho Chehab 	/* synchronize on ofdstate->m_festart */
35339a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 1);
35349a0bf528SMauro Carvalho Chehab 	if (status < 0)
35359a0bf528SMauro Carvalho Chehab 		goto error;
35369a0bf528SMauro Carvalho Chehab 	/* window size for clipping ADC detection */
35379a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
35389a0bf528SMauro Carvalho Chehab 	if (status < 0)
35399a0bf528SMauro Carvalho Chehab 		goto error;
35409a0bf528SMauro Carvalho Chehab 	/* window size for for sense pre-SAW detection */
35419a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
35429a0bf528SMauro Carvalho Chehab 	if (status < 0)
35439a0bf528SMauro Carvalho Chehab 		goto error;
35449a0bf528SMauro Carvalho Chehab 	/* sense threshold for sense pre-SAW detection */
35459a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
35469a0bf528SMauro Carvalho Chehab 	if (status < 0)
35479a0bf528SMauro Carvalho Chehab 		goto error;
3548cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
35499a0bf528SMauro Carvalho Chehab 	if (status < 0)
35509a0bf528SMauro Carvalho Chehab 		goto error;
35519a0bf528SMauro Carvalho Chehab 
35529a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AGC_RF__A, 0);
35539a0bf528SMauro Carvalho Chehab 	if (status < 0)
35549a0bf528SMauro Carvalho Chehab 		goto error;
35559a0bf528SMauro Carvalho Chehab 
35569a0bf528SMauro Carvalho Chehab 	/* Impulse noise cruncher setup */
35579a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_LCT__A, 0);	/* crunch in IQM_CF */
35589a0bf528SMauro Carvalho Chehab 	if (status < 0)
35599a0bf528SMauro Carvalho Chehab 		goto error;
35609a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);	/* detect in IQM_CF */
35619a0bf528SMauro Carvalho Chehab 	if (status < 0)
35629a0bf528SMauro Carvalho Chehab 		goto error;
35639a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 3);	/* peak detector window length */
35649a0bf528SMauro Carvalho Chehab 	if (status < 0)
35659a0bf528SMauro Carvalho Chehab 		goto error;
35669a0bf528SMauro Carvalho Chehab 
35679a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 16);
35689a0bf528SMauro Carvalho Chehab 	if (status < 0)
35699a0bf528SMauro Carvalho Chehab 		goto error;
35709a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
35719a0bf528SMauro Carvalho Chehab 	if (status < 0)
35729a0bf528SMauro Carvalho Chehab 		goto error;
35739a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
35749a0bf528SMauro Carvalho Chehab 	if (status < 0)
35759a0bf528SMauro Carvalho Chehab 		goto error;
35769a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE__A, 1600);
35779a0bf528SMauro Carvalho Chehab 	if (status < 0)
35789a0bf528SMauro Carvalho Chehab 		goto error;
35799a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, 0);
35809a0bf528SMauro Carvalho Chehab 	if (status < 0)
35819a0bf528SMauro Carvalho Chehab 		goto error;
35829a0bf528SMauro Carvalho Chehab 
35839a0bf528SMauro Carvalho Chehab 	/* virtual clipping threshold for clipping ADC detection */
35849a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
35859a0bf528SMauro Carvalho Chehab 	if (status < 0)
35869a0bf528SMauro Carvalho Chehab 		goto error;
35879a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 495);	/* crunching threshold */
35889a0bf528SMauro Carvalho Chehab 	if (status < 0)
35899a0bf528SMauro Carvalho Chehab 		goto error;
35909a0bf528SMauro Carvalho Chehab 
3591ab5060cdSMauro Carvalho Chehab 	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3592ab5060cdSMauro Carvalho Chehab 			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
35939a0bf528SMauro Carvalho Chehab 	if (status < 0)
35949a0bf528SMauro Carvalho Chehab 		goto error;
35959a0bf528SMauro Carvalho Chehab 
35969a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 2);	/* peak detector threshold */
35979a0bf528SMauro Carvalho Chehab 	if (status < 0)
35989a0bf528SMauro Carvalho Chehab 		goto error;
35999a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
36009a0bf528SMauro Carvalho Chehab 	if (status < 0)
36019a0bf528SMauro Carvalho Chehab 		goto error;
36029a0bf528SMauro Carvalho Chehab 	/* enable power measurement interrupt */
36039a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
36049a0bf528SMauro Carvalho Chehab 	if (status < 0)
36059a0bf528SMauro Carvalho Chehab 		goto error;
36069a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
36079a0bf528SMauro Carvalho Chehab 	if (status < 0)
36089a0bf528SMauro Carvalho Chehab 		goto error;
36099a0bf528SMauro Carvalho Chehab 
36109a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
3611cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
36129a0bf528SMauro Carvalho Chehab 	if (status < 0)
36139a0bf528SMauro Carvalho Chehab 		goto error;
3614cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
36159a0bf528SMauro Carvalho Chehab 	if (status < 0)
36169a0bf528SMauro Carvalho Chehab 		goto error;
36179a0bf528SMauro Carvalho Chehab 
36189a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
36199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
36209a0bf528SMauro Carvalho Chehab 	if (status < 0)
36219a0bf528SMauro Carvalho Chehab 		goto error;
36229a0bf528SMauro Carvalho Chehab 
3623cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
36249a0bf528SMauro Carvalho Chehab 	if (status < 0)
36259a0bf528SMauro Carvalho Chehab 		goto error;
3626cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
36279a0bf528SMauro Carvalho Chehab 	if (status < 0)
36289a0bf528SMauro Carvalho Chehab 		goto error;
36299a0bf528SMauro Carvalho Chehab 
36309a0bf528SMauro Carvalho Chehab 	/* Set Noise Estimation notch width and enable DC fix */
36319a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
36329a0bf528SMauro Carvalho Chehab 	if (status < 0)
36339a0bf528SMauro Carvalho Chehab 		goto error;
36349a0bf528SMauro Carvalho Chehab 	data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
36359a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
36369a0bf528SMauro Carvalho Chehab 	if (status < 0)
36379a0bf528SMauro Carvalho Chehab 		goto error;
36389a0bf528SMauro Carvalho Chehab 
36399a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
36409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
36419a0bf528SMauro Carvalho Chehab 	if (status < 0)
36429a0bf528SMauro Carvalho Chehab 		goto error;
36439a0bf528SMauro Carvalho Chehab 
3644cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code) {
3645cd7a67a4SMauro Carvalho Chehab 		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
3646ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3647ab5060cdSMauro Carvalho Chehab 				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
36489a0bf528SMauro Carvalho Chehab 		if (status < 0)
36499a0bf528SMauro Carvalho Chehab 			goto error;
36509a0bf528SMauro Carvalho Chehab 	}
36519a0bf528SMauro Carvalho Chehab 
36529a0bf528SMauro Carvalho Chehab 	/* OFDM_SC setup */
36539a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36549a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
36559a0bf528SMauro Carvalho Chehab 	if (status < 0)
36569a0bf528SMauro Carvalho Chehab 		goto error;
36579a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
36589a0bf528SMauro Carvalho Chehab 	if (status < 0)
36599a0bf528SMauro Carvalho Chehab 		goto error;
36609a0bf528SMauro Carvalho Chehab #endif
36619a0bf528SMauro Carvalho Chehab 
36629a0bf528SMauro Carvalho Chehab 	/* FEC setup */
36639a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_INPUT_CTL__A, 1);	/* OFDM input */
36649a0bf528SMauro Carvalho Chehab 	if (status < 0)
36659a0bf528SMauro Carvalho Chehab 		goto error;
36669a0bf528SMauro Carvalho Chehab 
36679a0bf528SMauro Carvalho Chehab 
36689a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36699a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
36709a0bf528SMauro Carvalho Chehab 	if (status < 0)
36719a0bf528SMauro Carvalho Chehab 		goto error;
36729a0bf528SMauro Carvalho Chehab #else
36739a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
36749a0bf528SMauro Carvalho Chehab 	if (status < 0)
36759a0bf528SMauro Carvalho Chehab 		goto error;
36769a0bf528SMauro Carvalho Chehab #endif
36779a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
36789a0bf528SMauro Carvalho Chehab 	if (status < 0)
36799a0bf528SMauro Carvalho Chehab 		goto error;
36809a0bf528SMauro Carvalho Chehab 
36819a0bf528SMauro Carvalho Chehab 	/* Setup MPEG bus */
3682cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, OM_DVBT);
36839a0bf528SMauro Carvalho Chehab 	if (status < 0)
36849a0bf528SMauro Carvalho Chehab 		goto error;
36859a0bf528SMauro Carvalho Chehab 	/* Set DVBT Presets */
3686cd7a67a4SMauro Carvalho Chehab 	status = dvbt_activate_presets(state);
36879a0bf528SMauro Carvalho Chehab 	if (status < 0)
36889a0bf528SMauro Carvalho Chehab 		goto error;
36899a0bf528SMauro Carvalho Chehab 
36909a0bf528SMauro Carvalho Chehab error:
36919a0bf528SMauro Carvalho Chehab 	if (status < 0)
36923a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
36939a0bf528SMauro Carvalho Chehab 	return status;
36949a0bf528SMauro Carvalho Chehab }
36959a0bf528SMauro Carvalho Chehab 
36969a0bf528SMauro Carvalho Chehab /*============================================================================*/
36979a0bf528SMauro Carvalho Chehab /**
3698cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel.
36999a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37009a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37019a0bf528SMauro Carvalho Chehab */
3702cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state)
37039a0bf528SMauro Carvalho Chehab {
37049a0bf528SMauro Carvalho Chehab 	u16 param1;
37059a0bf528SMauro Carvalho Chehab 	int status;
3706cd7a67a4SMauro Carvalho Chehab 	/* drxk_ofdm_sc_cmd_t scCmd; */
37079a0bf528SMauro Carvalho Chehab 
37089a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3709cd7a67a4SMauro Carvalho Chehab 	/* start correct processes to get in lock */
37109a0bf528SMauro Carvalho Chehab 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
37119a0bf528SMauro Carvalho Chehab 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3712ab5060cdSMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3713ab5060cdSMauro Carvalho Chehab 				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3714ab5060cdSMauro Carvalho Chehab 				 0, 0, 0);
37159a0bf528SMauro Carvalho Chehab 	if (status < 0)
37169a0bf528SMauro Carvalho Chehab 		goto error;
3717cd7a67a4SMauro Carvalho Chehab 	/* start FEC OC */
3718cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
37199a0bf528SMauro Carvalho Chehab 	if (status < 0)
37209a0bf528SMauro Carvalho Chehab 		goto error;
37219a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
37229a0bf528SMauro Carvalho Chehab 	if (status < 0)
37239a0bf528SMauro Carvalho Chehab 		goto error;
37249a0bf528SMauro Carvalho Chehab error:
37259a0bf528SMauro Carvalho Chehab 	if (status < 0)
37263a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
37279a0bf528SMauro Carvalho Chehab 	return status;
37289a0bf528SMauro Carvalho Chehab }
37299a0bf528SMauro Carvalho Chehab 
37309a0bf528SMauro Carvalho Chehab 
37319a0bf528SMauro Carvalho Chehab /*============================================================================*/
37329a0bf528SMauro Carvalho Chehab 
37339a0bf528SMauro Carvalho Chehab /**
37349a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
37359a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37369a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37379a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
37389a0bf528SMauro Carvalho Chehab */
3739cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3740cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset)
37419a0bf528SMauro Carvalho Chehab {
3742cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
3743cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
3744cd7a67a4SMauro Carvalho Chehab 	u16 operation_mode = 0;
3745cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate_ofs = 0;
37469a0bf528SMauro Carvalho Chehab 	u32 bandwidth = 0;
37479a0bf528SMauro Carvalho Chehab 	u16 param1;
37489a0bf528SMauro Carvalho Chehab 	int status;
37499a0bf528SMauro Carvalho Chehab 
3750ab5060cdSMauro Carvalho Chehab 	dprintk(1, "IF =%d, TFO = %d\n",
3751ab5060cdSMauro Carvalho Chehab 		intermediate_freqk_hz, tuner_freq_offset);
37529a0bf528SMauro Carvalho Chehab 
3753ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3754ab5060cdSMauro Carvalho Chehab 			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3755ab5060cdSMauro Carvalho Chehab 			    0, NULL, 1, &cmd_result);
37569a0bf528SMauro Carvalho Chehab 	if (status < 0)
37579a0bf528SMauro Carvalho Chehab 		goto error;
37589a0bf528SMauro Carvalho Chehab 
37599a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
37609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
37619a0bf528SMauro Carvalho Chehab 	if (status < 0)
37629a0bf528SMauro Carvalho Chehab 		goto error;
37639a0bf528SMauro Carvalho Chehab 
37649a0bf528SMauro Carvalho Chehab 	/* Stop processors */
37659a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
37669a0bf528SMauro Carvalho Chehab 	if (status < 0)
37679a0bf528SMauro Carvalho Chehab 		goto error;
37689a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
37699a0bf528SMauro Carvalho Chehab 	if (status < 0)
37709a0bf528SMauro Carvalho Chehab 		goto error;
37719a0bf528SMauro Carvalho Chehab 
37729a0bf528SMauro Carvalho Chehab 	/* Mandatory fix, always stop CP, required to set spl offset back to
37739a0bf528SMauro Carvalho Chehab 		hardware default (is set to 0 by ucode during pilot detection */
37749a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
37759a0bf528SMauro Carvalho Chehab 	if (status < 0)
37769a0bf528SMauro Carvalho Chehab 		goto error;
37779a0bf528SMauro Carvalho Chehab 
3778ab5060cdSMauro Carvalho Chehab 	/*== Write channel settings to device ================================*/
37799a0bf528SMauro Carvalho Chehab 
37809a0bf528SMauro Carvalho Chehab 	/* mode */
37819a0bf528SMauro Carvalho Chehab 	switch (state->props.transmission_mode) {
37829a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_AUTO:
37839a0bf528SMauro Carvalho Chehab 	default:
3784cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
37859a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_FFTMODE_8K */
37869a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_8K:
3787cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
37889a0bf528SMauro Carvalho Chehab 		break;
37899a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_2K:
3790cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
37919a0bf528SMauro Carvalho Chehab 		break;
37929a0bf528SMauro Carvalho Chehab 	}
37939a0bf528SMauro Carvalho Chehab 
37949a0bf528SMauro Carvalho Chehab 	/* guard */
37959a0bf528SMauro Carvalho Chehab 	switch (state->props.guard_interval) {
37969a0bf528SMauro Carvalho Chehab 	default:
37979a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_AUTO:
3798cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
37999a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_GUARD_1DIV4 */
38009a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_4:
3801cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
38029a0bf528SMauro Carvalho Chehab 		break;
38039a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_32:
3804cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
38059a0bf528SMauro Carvalho Chehab 		break;
38069a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_16:
3807cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
38089a0bf528SMauro Carvalho Chehab 		break;
38099a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_8:
3810cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
38119a0bf528SMauro Carvalho Chehab 		break;
38129a0bf528SMauro Carvalho Chehab 	}
38139a0bf528SMauro Carvalho Chehab 
38149a0bf528SMauro Carvalho Chehab 	/* hierarchy */
38159a0bf528SMauro Carvalho Chehab 	switch (state->props.hierarchy) {
38169a0bf528SMauro Carvalho Chehab 	case HIERARCHY_AUTO:
38179a0bf528SMauro Carvalho Chehab 	case HIERARCHY_NONE:
38189a0bf528SMauro Carvalho Chehab 	default:
3819cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
38209a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3821cd7a67a4SMauro Carvalho Chehab 		/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
38229a0bf528SMauro Carvalho Chehab 		/* break; */
38239a0bf528SMauro Carvalho Chehab 	case HIERARCHY_1:
3824cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
38259a0bf528SMauro Carvalho Chehab 		break;
38269a0bf528SMauro Carvalho Chehab 	case HIERARCHY_2:
3827cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
38289a0bf528SMauro Carvalho Chehab 		break;
38299a0bf528SMauro Carvalho Chehab 	case HIERARCHY_4:
3830cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
38319a0bf528SMauro Carvalho Chehab 		break;
38329a0bf528SMauro Carvalho Chehab 	}
38339a0bf528SMauro Carvalho Chehab 
38349a0bf528SMauro Carvalho Chehab 
38359a0bf528SMauro Carvalho Chehab 	/* modulation */
38369a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
38379a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
38389a0bf528SMauro Carvalho Chehab 	default:
3839cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
38409a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
38419a0bf528SMauro Carvalho Chehab 	case QAM_64:
3842cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
38439a0bf528SMauro Carvalho Chehab 		break;
38449a0bf528SMauro Carvalho Chehab 	case QPSK:
3845cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
38469a0bf528SMauro Carvalho Chehab 		break;
38479a0bf528SMauro Carvalho Chehab 	case QAM_16:
3848cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
38499a0bf528SMauro Carvalho Chehab 		break;
38509a0bf528SMauro Carvalho Chehab 	}
38519a0bf528SMauro Carvalho Chehab #if 0
38529a0bf528SMauro Carvalho Chehab 	/* No hierachical channels support in BDA */
38539a0bf528SMauro Carvalho Chehab 	/* Priority (only for hierarchical channels) */
38549a0bf528SMauro Carvalho Chehab 	switch (channel->priority) {
38559a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_LOW:
3856cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3857cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38589a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_LO);
38599a0bf528SMauro Carvalho Chehab 		break;
38609a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_HIGH:
3861cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3862cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38639a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_HI));
38649a0bf528SMauro Carvalho Chehab 		break;
38659a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_UNKNOWN:	/* fall through */
38669a0bf528SMauro Carvalho Chehab 	default:
38679a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
38689a0bf528SMauro Carvalho Chehab 		goto error;
38699a0bf528SMauro Carvalho Chehab 	}
38709a0bf528SMauro Carvalho Chehab #else
38719a0bf528SMauro Carvalho Chehab 	/* Set Priorty high */
3872cd7a67a4SMauro Carvalho Chehab 	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
38739a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
38749a0bf528SMauro Carvalho Chehab 	if (status < 0)
38759a0bf528SMauro Carvalho Chehab 		goto error;
38769a0bf528SMauro Carvalho Chehab #endif
38779a0bf528SMauro Carvalho Chehab 
38789a0bf528SMauro Carvalho Chehab 	/* coderate */
38799a0bf528SMauro Carvalho Chehab 	switch (state->props.code_rate_HP) {
38809a0bf528SMauro Carvalho Chehab 	case FEC_AUTO:
38819a0bf528SMauro Carvalho Chehab 	default:
3882cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
38839a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_CODERATE_2DIV3 */
38849a0bf528SMauro Carvalho Chehab 	case FEC_2_3:
3885cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
38869a0bf528SMauro Carvalho Chehab 		break;
38879a0bf528SMauro Carvalho Chehab 	case FEC_1_2:
3888cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
38899a0bf528SMauro Carvalho Chehab 		break;
38909a0bf528SMauro Carvalho Chehab 	case FEC_3_4:
3891cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
38929a0bf528SMauro Carvalho Chehab 		break;
38939a0bf528SMauro Carvalho Chehab 	case FEC_5_6:
3894cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
38959a0bf528SMauro Carvalho Chehab 		break;
38969a0bf528SMauro Carvalho Chehab 	case FEC_7_8:
3897cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
38989a0bf528SMauro Carvalho Chehab 		break;
38999a0bf528SMauro Carvalho Chehab 	}
39009a0bf528SMauro Carvalho Chehab 
3901ab5060cdSMauro Carvalho Chehab 	/*
3902ab5060cdSMauro Carvalho Chehab 	 * SAW filter selection: normaly not necesarry, but if wanted
3903ab5060cdSMauro Carvalho Chehab 	 * the application can select a SAW filter via the driver by
3904ab5060cdSMauro Carvalho Chehab 	 * using UIOs
3905ab5060cdSMauro Carvalho Chehab 	 */
3906ab5060cdSMauro Carvalho Chehab 
39079a0bf528SMauro Carvalho Chehab 	/* First determine real bandwidth (Hz) */
39089a0bf528SMauro Carvalho Chehab 	/* Also set delay for impulse noise cruncher */
3909ab5060cdSMauro Carvalho Chehab 	/*
3910ab5060cdSMauro Carvalho Chehab 	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3911ab5060cdSMauro Carvalho Chehab 	 * changed by SC for fix for some 8K,1/8 guard but is restored by
3912ab5060cdSMauro Carvalho Chehab 	 * InitEC and ResetEC functions
3913ab5060cdSMauro Carvalho Chehab 	 */
39149a0bf528SMauro Carvalho Chehab 	switch (state->props.bandwidth_hz) {
39159a0bf528SMauro Carvalho Chehab 	case 0:
39169a0bf528SMauro Carvalho Chehab 		state->props.bandwidth_hz = 8000000;
39179a0bf528SMauro Carvalho Chehab 		/* fall though */
39189a0bf528SMauro Carvalho Chehab 	case 8000000:
39199a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3920ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3921ab5060cdSMauro Carvalho Chehab 				 3052);
39229a0bf528SMauro Carvalho Chehab 		if (status < 0)
39239a0bf528SMauro Carvalho Chehab 			goto error;
39249a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 8 MHz */
3925ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3926ab5060cdSMauro Carvalho Chehab 				 7);
39279a0bf528SMauro Carvalho Chehab 		if (status < 0)
39289a0bf528SMauro Carvalho Chehab 			goto error;
3929ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3930ab5060cdSMauro Carvalho Chehab 				 7);
39319a0bf528SMauro Carvalho Chehab 		if (status < 0)
39329a0bf528SMauro Carvalho Chehab 			goto error;
3933ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3934ab5060cdSMauro Carvalho Chehab 				 7);
39359a0bf528SMauro Carvalho Chehab 		if (status < 0)
39369a0bf528SMauro Carvalho Chehab 			goto error;
3937ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3938ab5060cdSMauro Carvalho Chehab 				 1);
39399a0bf528SMauro Carvalho Chehab 		if (status < 0)
39409a0bf528SMauro Carvalho Chehab 			goto error;
39419a0bf528SMauro Carvalho Chehab 		break;
39429a0bf528SMauro Carvalho Chehab 	case 7000000:
39439a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3944ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3945ab5060cdSMauro Carvalho Chehab 				 3491);
39469a0bf528SMauro Carvalho Chehab 		if (status < 0)
39479a0bf528SMauro Carvalho Chehab 			goto error;
39489a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 7 MHz */
3949ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3950ab5060cdSMauro Carvalho Chehab 				 8);
39519a0bf528SMauro Carvalho Chehab 		if (status < 0)
39529a0bf528SMauro Carvalho Chehab 			goto error;
3953ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3954ab5060cdSMauro Carvalho Chehab 				 8);
39559a0bf528SMauro Carvalho Chehab 		if (status < 0)
39569a0bf528SMauro Carvalho Chehab 			goto error;
3957ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3958ab5060cdSMauro Carvalho Chehab 				 4);
39599a0bf528SMauro Carvalho Chehab 		if (status < 0)
39609a0bf528SMauro Carvalho Chehab 			goto error;
3961ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3962ab5060cdSMauro Carvalho Chehab 				 1);
39639a0bf528SMauro Carvalho Chehab 		if (status < 0)
39649a0bf528SMauro Carvalho Chehab 			goto error;
39659a0bf528SMauro Carvalho Chehab 		break;
39669a0bf528SMauro Carvalho Chehab 	case 6000000:
39679a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3968ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3969ab5060cdSMauro Carvalho Chehab 				 4073);
39709a0bf528SMauro Carvalho Chehab 		if (status < 0)
39719a0bf528SMauro Carvalho Chehab 			goto error;
39729a0bf528SMauro Carvalho Chehab 		/* cochannel protection for NTSC 6 MHz */
3973ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3974ab5060cdSMauro Carvalho Chehab 				 19);
39759a0bf528SMauro Carvalho Chehab 		if (status < 0)
39769a0bf528SMauro Carvalho Chehab 			goto error;
3977ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3978ab5060cdSMauro Carvalho Chehab 				 19);
39799a0bf528SMauro Carvalho Chehab 		if (status < 0)
39809a0bf528SMauro Carvalho Chehab 			goto error;
3981ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3982ab5060cdSMauro Carvalho Chehab 				 14);
39839a0bf528SMauro Carvalho Chehab 		if (status < 0)
39849a0bf528SMauro Carvalho Chehab 			goto error;
3985ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3986ab5060cdSMauro Carvalho Chehab 				 1);
39879a0bf528SMauro Carvalho Chehab 		if (status < 0)
39889a0bf528SMauro Carvalho Chehab 			goto error;
39899a0bf528SMauro Carvalho Chehab 		break;
39909a0bf528SMauro Carvalho Chehab 	default:
39919a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
39929a0bf528SMauro Carvalho Chehab 		goto error;
39939a0bf528SMauro Carvalho Chehab 	}
39949a0bf528SMauro Carvalho Chehab 
3995cd7a67a4SMauro Carvalho Chehab 	if (iqm_rc_rate_ofs == 0) {
39969a0bf528SMauro Carvalho Chehab 		/* Now compute IQM_RC_RATE_OFS
39979a0bf528SMauro Carvalho Chehab 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
39989a0bf528SMauro Carvalho Chehab 			=>
39999a0bf528SMauro Carvalho Chehab 			((SysFreq / BandWidth) * (2^21)) - (2^23)
40009a0bf528SMauro Carvalho Chehab 			*/
40019a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^28)  */
4002ab5060cdSMauro Carvalho Chehab 		/*
4003ab5060cdSMauro Carvalho Chehab 		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
4004ab5060cdSMauro Carvalho Chehab 		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
4005ab5060cdSMauro Carvalho Chehab 		 *	=> assert(109714272 > 48000000) = true
4006ab5060cdSMauro Carvalho Chehab 		 * so Frac 28 can be used
4007ab5060cdSMauro Carvalho Chehab 		 */
4008cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = Frac28a((u32)
4009cd7a67a4SMauro Carvalho Chehab 					((state->m_sys_clock_freq *
40109a0bf528SMauro Carvalho Chehab 						1000) / 3), bandwidth);
40119a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4012cd7a67a4SMauro Carvalho Chehab 		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
4013cd7a67a4SMauro Carvalho Chehab 			iqm_rc_rate_ofs += 0x80L;
4014cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
40159a0bf528SMauro Carvalho Chehab 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
4016cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
40179a0bf528SMauro Carvalho Chehab 	}
40189a0bf528SMauro Carvalho Chehab 
4019cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate_ofs &=
40209a0bf528SMauro Carvalho Chehab 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
40219a0bf528SMauro Carvalho Chehab 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4022cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
40239a0bf528SMauro Carvalho Chehab 	if (status < 0)
40249a0bf528SMauro Carvalho Chehab 		goto error;
40259a0bf528SMauro Carvalho Chehab 
40269a0bf528SMauro Carvalho Chehab 	/* Bandwidth setting done */
40279a0bf528SMauro Carvalho Chehab 
40289a0bf528SMauro Carvalho Chehab #if 0
4029cd7a67a4SMauro Carvalho Chehab 	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
40309a0bf528SMauro Carvalho Chehab 	if (status < 0)
40319a0bf528SMauro Carvalho Chehab 		goto error;
40329a0bf528SMauro Carvalho Chehab #endif
4033ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
4034ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
40359a0bf528SMauro Carvalho Chehab 	if (status < 0)
40369a0bf528SMauro Carvalho Chehab 		goto error;
40379a0bf528SMauro Carvalho Chehab 
4038ab5060cdSMauro Carvalho Chehab 	/*== start SC, write channel settings to SC ==========================*/
40399a0bf528SMauro Carvalho Chehab 
40409a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
40419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
40429a0bf528SMauro Carvalho Chehab 	if (status < 0)
40439a0bf528SMauro Carvalho Chehab 		goto error;
40449a0bf528SMauro Carvalho Chehab 
40459a0bf528SMauro Carvalho Chehab 	/* Enable SC after setting all other parameters */
40469a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_STATE__A, 0);
40479a0bf528SMauro Carvalho Chehab 	if (status < 0)
40489a0bf528SMauro Carvalho Chehab 		goto error;
40499a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
40509a0bf528SMauro Carvalho Chehab 	if (status < 0)
40519a0bf528SMauro Carvalho Chehab 		goto error;
40529a0bf528SMauro Carvalho Chehab 
40539a0bf528SMauro Carvalho Chehab 
4054ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4055ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
4056ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
40579a0bf528SMauro Carvalho Chehab 	if (status < 0)
40589a0bf528SMauro Carvalho Chehab 		goto error;
40599a0bf528SMauro Carvalho Chehab 
40609a0bf528SMauro Carvalho Chehab 	/* Write SC parameter registers, set all AUTO flags in operation mode */
40619a0bf528SMauro Carvalho Chehab 	param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
40629a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
40639a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
40649a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
40659a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4066cd7a67a4SMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4067cd7a67a4SMauro Carvalho Chehab 				0, transmission_params, param1, 0, 0, 0);
40689a0bf528SMauro Carvalho Chehab 	if (status < 0)
40699a0bf528SMauro Carvalho Chehab 		goto error;
40709a0bf528SMauro Carvalho Chehab 
4071cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code)
4072cd7a67a4SMauro Carvalho Chehab 		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
40739a0bf528SMauro Carvalho Chehab error:
40749a0bf528SMauro Carvalho Chehab 	if (status < 0)
40753a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40769a0bf528SMauro Carvalho Chehab 
40779a0bf528SMauro Carvalho Chehab 	return status;
40789a0bf528SMauro Carvalho Chehab }
40799a0bf528SMauro Carvalho Chehab 
40809a0bf528SMauro Carvalho Chehab 
40819a0bf528SMauro Carvalho Chehab /*============================================================================*/
40829a0bf528SMauro Carvalho Chehab 
40839a0bf528SMauro Carvalho Chehab /**
40849a0bf528SMauro Carvalho Chehab * \brief Retreive lock status .
40859a0bf528SMauro Carvalho Chehab * \param demod    Pointer to demodulator instance.
40869a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
40879a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
40889a0bf528SMauro Carvalho Chehab *
40899a0bf528SMauro Carvalho Chehab */
4090cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
40919a0bf528SMauro Carvalho Chehab {
40929a0bf528SMauro Carvalho Chehab 	int status;
40939a0bf528SMauro Carvalho Chehab 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
40949a0bf528SMauro Carvalho Chehab 				    OFDM_SC_RA_RAM_LOCK_FEC__M);
40959a0bf528SMauro Carvalho Chehab 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
40969a0bf528SMauro Carvalho Chehab 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
40979a0bf528SMauro Carvalho Chehab 
4098cd7a67a4SMauro Carvalho Chehab 	u16 sc_ra_ram_lock = 0;
4099cd7a67a4SMauro Carvalho Chehab 	u16 sc_comm_exec = 0;
41009a0bf528SMauro Carvalho Chehab 
41019a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41029a0bf528SMauro Carvalho Chehab 
4103cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
41049a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
41059a0bf528SMauro Carvalho Chehab 	/* Check if SC is running */
4106cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
41079a0bf528SMauro Carvalho Chehab 	if (status < 0)
41089a0bf528SMauro Carvalho Chehab 		goto end;
4109cd7a67a4SMauro Carvalho Chehab 	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
41109a0bf528SMauro Carvalho Chehab 		goto end;
41119a0bf528SMauro Carvalho Chehab 
4112cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
41139a0bf528SMauro Carvalho Chehab 	if (status < 0)
41149a0bf528SMauro Carvalho Chehab 		goto end;
41159a0bf528SMauro Carvalho Chehab 
4116cd7a67a4SMauro Carvalho Chehab 	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4117cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
4118cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4119cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = FEC_LOCK;
4120cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4121cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
4122cd7a67a4SMauro Carvalho Chehab 	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4123cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
41249a0bf528SMauro Carvalho Chehab end:
41259a0bf528SMauro Carvalho Chehab 	if (status < 0)
41263a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41279a0bf528SMauro Carvalho Chehab 
41289a0bf528SMauro Carvalho Chehab 	return status;
41299a0bf528SMauro Carvalho Chehab }
41309a0bf528SMauro Carvalho Chehab 
4131cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state)
41329a0bf528SMauro Carvalho Chehab {
4133cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
41349a0bf528SMauro Carvalho Chehab 	int status;
41359a0bf528SMauro Carvalho Chehab 
41369a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4137cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
41389a0bf528SMauro Carvalho Chehab 	if (status < 0)
41393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41409a0bf528SMauro Carvalho Chehab 
41419a0bf528SMauro Carvalho Chehab 	return status;
41429a0bf528SMauro Carvalho Chehab }
41439a0bf528SMauro Carvalho Chehab 
41449a0bf528SMauro Carvalho Chehab 
41459a0bf528SMauro Carvalho Chehab /** Power Down QAM */
4146cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state)
41479a0bf528SMauro Carvalho Chehab {
41489a0bf528SMauro Carvalho Chehab 	u16 data = 0;
4149cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
41509a0bf528SMauro Carvalho Chehab 	int status = 0;
41519a0bf528SMauro Carvalho Chehab 
41529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41539a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
41549a0bf528SMauro Carvalho Chehab 	if (status < 0)
41559a0bf528SMauro Carvalho Chehab 		goto error;
41569a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
41579a0bf528SMauro Carvalho Chehab 		/*
41589a0bf528SMauro Carvalho Chehab 			STOP demodulator
41599a0bf528SMauro Carvalho Chehab 			QAM and HW blocks
41609a0bf528SMauro Carvalho Chehab 			*/
41619a0bf528SMauro Carvalho Chehab 		/* stop all comstate->m_exec */
41629a0bf528SMauro Carvalho Chehab 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
41639a0bf528SMauro Carvalho Chehab 		if (status < 0)
41649a0bf528SMauro Carvalho Chehab 			goto error;
4165ab5060cdSMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4166ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4167ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
41689a0bf528SMauro Carvalho Chehab 		if (status < 0)
41699a0bf528SMauro Carvalho Chehab 			goto error;
41709a0bf528SMauro Carvalho Chehab 	}
41719a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
4172cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
41739a0bf528SMauro Carvalho Chehab 
41749a0bf528SMauro Carvalho Chehab error:
41759a0bf528SMauro Carvalho Chehab 	if (status < 0)
41763a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41779a0bf528SMauro Carvalho Chehab 
41789a0bf528SMauro Carvalho Chehab 	return status;
41799a0bf528SMauro Carvalho Chehab }
41809a0bf528SMauro Carvalho Chehab 
41819a0bf528SMauro Carvalho Chehab /*============================================================================*/
41829a0bf528SMauro Carvalho Chehab 
41839a0bf528SMauro Carvalho Chehab /**
41849a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
41859a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
41869a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
41879a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41889a0bf528SMauro Carvalho Chehab *
41899a0bf528SMauro Carvalho Chehab *  NOTE:
41909a0bf528SMauro Carvalho Chehab *  Take into account that for certain settings the errorcounters can overflow.
41919a0bf528SMauro Carvalho Chehab *  The implementation does not check this.
41929a0bf528SMauro Carvalho Chehab *
41939a0bf528SMauro Carvalho Chehab */
4194cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state,
4195cd7a67a4SMauro Carvalho Chehab 			     enum e_drxk_constellation modulation,
4196cd7a67a4SMauro Carvalho Chehab 			     u32 symbol_rate)
41979a0bf528SMauro Carvalho Chehab {
4198cd7a67a4SMauro Carvalho Chehab 	u32 fec_bits_desired = 0;	/* BER accounting period */
4199cd7a67a4SMauro Carvalho Chehab 	u32 fec_rs_period_total = 0;	/* Total period */
4200cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
4201cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
42029a0bf528SMauro Carvalho Chehab 	int status = 0;
42039a0bf528SMauro Carvalho Chehab 
42049a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42059a0bf528SMauro Carvalho Chehab 
4206cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1;
4207cd7a67a4SMauro Carvalho Chehab 	/* fec_bits_desired = symbol_rate [kHz] *
42089a0bf528SMauro Carvalho Chehab 		FrameLenght [ms] *
42099a0bf528SMauro Carvalho Chehab 		(modulation + 1) *
42109a0bf528SMauro Carvalho Chehab 		SyncLoss (== 1) *
42119a0bf528SMauro Carvalho Chehab 		ViterbiLoss (==1)
42129a0bf528SMauro Carvalho Chehab 		*/
42139a0bf528SMauro Carvalho Chehab 	switch (modulation) {
42149a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM16:
4215cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 4 * symbol_rate;
42169a0bf528SMauro Carvalho Chehab 		break;
42179a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM32:
4218cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 5 * symbol_rate;
42199a0bf528SMauro Carvalho Chehab 		break;
42209a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM64:
4221cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 6 * symbol_rate;
42229a0bf528SMauro Carvalho Chehab 		break;
42239a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM128:
4224cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 7 * symbol_rate;
42259a0bf528SMauro Carvalho Chehab 		break;
42269a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM256:
4227cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 8 * symbol_rate;
42289a0bf528SMauro Carvalho Chehab 		break;
42299a0bf528SMauro Carvalho Chehab 	default:
42309a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42319a0bf528SMauro Carvalho Chehab 	}
42329a0bf528SMauro Carvalho Chehab 	if (status < 0)
42339a0bf528SMauro Carvalho Chehab 		goto error;
42349a0bf528SMauro Carvalho Chehab 
4235cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
4236cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired *= 500;	/* meas. period [ms] */
42379a0bf528SMauro Carvalho Chehab 
42389a0bf528SMauro Carvalho Chehab 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4239cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total = fec_bits_desired / 1632 */
4240cd7a67a4SMauro Carvalho Chehab 	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
42419a0bf528SMauro Carvalho Chehab 
4242cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
4243cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4244cd7a67a4SMauro Carvalho Chehab 	if (fec_rs_prescale == 0) {
42459a0bf528SMauro Carvalho Chehab 		/* Divide by zero (though impossible) */
42469a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42479a0bf528SMauro Carvalho Chehab 		if (status < 0)
42489a0bf528SMauro Carvalho Chehab 			goto error;
42499a0bf528SMauro Carvalho Chehab 	}
4250cd7a67a4SMauro Carvalho Chehab 	fec_rs_period =
4251cd7a67a4SMauro Carvalho Chehab 		((u16) fec_rs_period_total +
4252cd7a67a4SMauro Carvalho Chehab 		(fec_rs_prescale >> 1)) / fec_rs_prescale;
42539a0bf528SMauro Carvalho Chehab 
42549a0bf528SMauro Carvalho Chehab 	/* write corresponding registers */
4255cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
42569a0bf528SMauro Carvalho Chehab 	if (status < 0)
42579a0bf528SMauro Carvalho Chehab 		goto error;
4258ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4259ab5060cdSMauro Carvalho Chehab 			 fec_rs_prescale);
42609a0bf528SMauro Carvalho Chehab 	if (status < 0)
42619a0bf528SMauro Carvalho Chehab 		goto error;
4262cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
42639a0bf528SMauro Carvalho Chehab error:
42649a0bf528SMauro Carvalho Chehab 	if (status < 0)
42653a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
42669a0bf528SMauro Carvalho Chehab 	return status;
42679a0bf528SMauro Carvalho Chehab }
42689a0bf528SMauro Carvalho Chehab 
4269cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state)
42709a0bf528SMauro Carvalho Chehab {
42719a0bf528SMauro Carvalho Chehab 	int status = 0;
42729a0bf528SMauro Carvalho Chehab 
42739a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42749a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
42759a0bf528SMauro Carvalho Chehab 	/* Equalizer */
42769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
42779a0bf528SMauro Carvalho Chehab 	if (status < 0)
42789a0bf528SMauro Carvalho Chehab 		goto error;
42799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
42809a0bf528SMauro Carvalho Chehab 	if (status < 0)
42819a0bf528SMauro Carvalho Chehab 		goto error;
42829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
42839a0bf528SMauro Carvalho Chehab 	if (status < 0)
42849a0bf528SMauro Carvalho Chehab 		goto error;
42859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
42869a0bf528SMauro Carvalho Chehab 	if (status < 0)
42879a0bf528SMauro Carvalho Chehab 		goto error;
42889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
42899a0bf528SMauro Carvalho Chehab 	if (status < 0)
42909a0bf528SMauro Carvalho Chehab 		goto error;
42919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
42929a0bf528SMauro Carvalho Chehab 	if (status < 0)
42939a0bf528SMauro Carvalho Chehab 		goto error;
42949a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
42959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
42969a0bf528SMauro Carvalho Chehab 	if (status < 0)
42979a0bf528SMauro Carvalho Chehab 		goto error;
42989a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
42999a0bf528SMauro Carvalho Chehab 	if (status < 0)
43009a0bf528SMauro Carvalho Chehab 		goto error;
43019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
43029a0bf528SMauro Carvalho Chehab 	if (status < 0)
43039a0bf528SMauro Carvalho Chehab 		goto error;
43049a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
43059a0bf528SMauro Carvalho Chehab 	if (status < 0)
43069a0bf528SMauro Carvalho Chehab 		goto error;
43079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
43089a0bf528SMauro Carvalho Chehab 	if (status < 0)
43099a0bf528SMauro Carvalho Chehab 		goto error;
43109a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
43119a0bf528SMauro Carvalho Chehab 	if (status < 0)
43129a0bf528SMauro Carvalho Chehab 		goto error;
43139a0bf528SMauro Carvalho Chehab 
43149a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
43159a0bf528SMauro Carvalho Chehab 	if (status < 0)
43169a0bf528SMauro Carvalho Chehab 		goto error;
43179a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
43189a0bf528SMauro Carvalho Chehab 	if (status < 0)
43199a0bf528SMauro Carvalho Chehab 		goto error;
43209a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
43219a0bf528SMauro Carvalho Chehab 	if (status < 0)
43229a0bf528SMauro Carvalho Chehab 		goto error;
43239a0bf528SMauro Carvalho Chehab 
43249a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4325ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4326ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM16);
43279a0bf528SMauro Carvalho Chehab 	if (status < 0)
43289a0bf528SMauro Carvalho Chehab 		goto error;
43299a0bf528SMauro Carvalho Chehab 
43309a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
43319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
43329a0bf528SMauro Carvalho Chehab 	if (status < 0)
43339a0bf528SMauro Carvalho Chehab 		goto error;
43349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
43359a0bf528SMauro Carvalho Chehab 	if (status < 0)
43369a0bf528SMauro Carvalho Chehab 		goto error;
43379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
43389a0bf528SMauro Carvalho Chehab 	if (status < 0)
43399a0bf528SMauro Carvalho Chehab 		goto error;
43409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
43419a0bf528SMauro Carvalho Chehab 	if (status < 0)
43429a0bf528SMauro Carvalho Chehab 		goto error;
43439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
43449a0bf528SMauro Carvalho Chehab 	if (status < 0)
43459a0bf528SMauro Carvalho Chehab 		goto error;
43469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
43479a0bf528SMauro Carvalho Chehab 	if (status < 0)
43489a0bf528SMauro Carvalho Chehab 		goto error;
43499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
43509a0bf528SMauro Carvalho Chehab 	if (status < 0)
43519a0bf528SMauro Carvalho Chehab 		goto error;
43529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43539a0bf528SMauro Carvalho Chehab 	if (status < 0)
43549a0bf528SMauro Carvalho Chehab 		goto error;
43559a0bf528SMauro Carvalho Chehab 
43569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43579a0bf528SMauro Carvalho Chehab 	if (status < 0)
43589a0bf528SMauro Carvalho Chehab 		goto error;
43599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43609a0bf528SMauro Carvalho Chehab 	if (status < 0)
43619a0bf528SMauro Carvalho Chehab 		goto error;
43629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
43639a0bf528SMauro Carvalho Chehab 	if (status < 0)
43649a0bf528SMauro Carvalho Chehab 		goto error;
43659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
43669a0bf528SMauro Carvalho Chehab 	if (status < 0)
43679a0bf528SMauro Carvalho Chehab 		goto error;
43689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
43699a0bf528SMauro Carvalho Chehab 	if (status < 0)
43709a0bf528SMauro Carvalho Chehab 		goto error;
43719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
43729a0bf528SMauro Carvalho Chehab 	if (status < 0)
43739a0bf528SMauro Carvalho Chehab 		goto error;
43749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
43759a0bf528SMauro Carvalho Chehab 	if (status < 0)
43769a0bf528SMauro Carvalho Chehab 		goto error;
43779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
43789a0bf528SMauro Carvalho Chehab 	if (status < 0)
43799a0bf528SMauro Carvalho Chehab 		goto error;
43809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
43819a0bf528SMauro Carvalho Chehab 	if (status < 0)
43829a0bf528SMauro Carvalho Chehab 		goto error;
43839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
43849a0bf528SMauro Carvalho Chehab 	if (status < 0)
43859a0bf528SMauro Carvalho Chehab 		goto error;
43869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
43879a0bf528SMauro Carvalho Chehab 	if (status < 0)
43889a0bf528SMauro Carvalho Chehab 		goto error;
43899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
43909a0bf528SMauro Carvalho Chehab 	if (status < 0)
43919a0bf528SMauro Carvalho Chehab 		goto error;
43929a0bf528SMauro Carvalho Chehab 
43939a0bf528SMauro Carvalho Chehab 
43949a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
43959a0bf528SMauro Carvalho Chehab 
43969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
43979a0bf528SMauro Carvalho Chehab 	if (status < 0)
43989a0bf528SMauro Carvalho Chehab 		goto error;
43999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
44009a0bf528SMauro Carvalho Chehab 	if (status < 0)
44019a0bf528SMauro Carvalho Chehab 		goto error;
44029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
44039a0bf528SMauro Carvalho Chehab 	if (status < 0)
44049a0bf528SMauro Carvalho Chehab 		goto error;
44059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
44069a0bf528SMauro Carvalho Chehab 	if (status < 0)
44079a0bf528SMauro Carvalho Chehab 		goto error;
44089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
44099a0bf528SMauro Carvalho Chehab 	if (status < 0)
44109a0bf528SMauro Carvalho Chehab 		goto error;
44119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
44129a0bf528SMauro Carvalho Chehab 	if (status < 0)
44139a0bf528SMauro Carvalho Chehab 		goto error;
44149a0bf528SMauro Carvalho Chehab 
44159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
44169a0bf528SMauro Carvalho Chehab 	if (status < 0)
44179a0bf528SMauro Carvalho Chehab 		goto error;
44189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
44199a0bf528SMauro Carvalho Chehab 	if (status < 0)
44209a0bf528SMauro Carvalho Chehab 		goto error;
44219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
44229a0bf528SMauro Carvalho Chehab 	if (status < 0)
44239a0bf528SMauro Carvalho Chehab 		goto error;
44249a0bf528SMauro Carvalho Chehab 
44259a0bf528SMauro Carvalho Chehab 
44269a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
44279a0bf528SMauro Carvalho Chehab 
44289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
44299a0bf528SMauro Carvalho Chehab 	if (status < 0)
44309a0bf528SMauro Carvalho Chehab 		goto error;
44319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
44329a0bf528SMauro Carvalho Chehab 	if (status < 0)
44339a0bf528SMauro Carvalho Chehab 		goto error;
44349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
44359a0bf528SMauro Carvalho Chehab 	if (status < 0)
44369a0bf528SMauro Carvalho Chehab 		goto error;
44379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
44389a0bf528SMauro Carvalho Chehab 	if (status < 0)
44399a0bf528SMauro Carvalho Chehab 		goto error;
44409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
44419a0bf528SMauro Carvalho Chehab 	if (status < 0)
44429a0bf528SMauro Carvalho Chehab 		goto error;
44439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
44449a0bf528SMauro Carvalho Chehab 	if (status < 0)
44459a0bf528SMauro Carvalho Chehab 		goto error;
44469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
44479a0bf528SMauro Carvalho Chehab 	if (status < 0)
44489a0bf528SMauro Carvalho Chehab 		goto error;
44499a0bf528SMauro Carvalho Chehab 
44509a0bf528SMauro Carvalho Chehab error:
44519a0bf528SMauro Carvalho Chehab 	if (status < 0)
44523a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
44539a0bf528SMauro Carvalho Chehab 	return status;
44549a0bf528SMauro Carvalho Chehab }
44559a0bf528SMauro Carvalho Chehab 
44569a0bf528SMauro Carvalho Chehab /*============================================================================*/
44579a0bf528SMauro Carvalho Chehab 
44589a0bf528SMauro Carvalho Chehab /**
44599a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44609a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
44619a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
44629a0bf528SMauro Carvalho Chehab */
4463cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state)
44649a0bf528SMauro Carvalho Chehab {
44659a0bf528SMauro Carvalho Chehab 	int status = 0;
44669a0bf528SMauro Carvalho Chehab 
44679a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
44689a0bf528SMauro Carvalho Chehab 
44699a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
44709a0bf528SMauro Carvalho Chehab 	/* Equalizer */
44719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
44729a0bf528SMauro Carvalho Chehab 	if (status < 0)
44739a0bf528SMauro Carvalho Chehab 		goto error;
44749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
44759a0bf528SMauro Carvalho Chehab 	if (status < 0)
44769a0bf528SMauro Carvalho Chehab 		goto error;
44779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
44789a0bf528SMauro Carvalho Chehab 	if (status < 0)
44799a0bf528SMauro Carvalho Chehab 		goto error;
44809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
44819a0bf528SMauro Carvalho Chehab 	if (status < 0)
44829a0bf528SMauro Carvalho Chehab 		goto error;
44839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
44849a0bf528SMauro Carvalho Chehab 	if (status < 0)
44859a0bf528SMauro Carvalho Chehab 		goto error;
44869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
44879a0bf528SMauro Carvalho Chehab 	if (status < 0)
44889a0bf528SMauro Carvalho Chehab 		goto error;
44899a0bf528SMauro Carvalho Chehab 
44909a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
44919a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
44929a0bf528SMauro Carvalho Chehab 	if (status < 0)
44939a0bf528SMauro Carvalho Chehab 		goto error;
44949a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
44959a0bf528SMauro Carvalho Chehab 	if (status < 0)
44969a0bf528SMauro Carvalho Chehab 		goto error;
44979a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
44989a0bf528SMauro Carvalho Chehab 	if (status < 0)
44999a0bf528SMauro Carvalho Chehab 		goto error;
45009a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
45019a0bf528SMauro Carvalho Chehab 	if (status < 0)
45029a0bf528SMauro Carvalho Chehab 		goto error;
45039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
45049a0bf528SMauro Carvalho Chehab 	if (status < 0)
45059a0bf528SMauro Carvalho Chehab 		goto error;
45069a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
45079a0bf528SMauro Carvalho Chehab 	if (status < 0)
45089a0bf528SMauro Carvalho Chehab 		goto error;
45099a0bf528SMauro Carvalho Chehab 
45109a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
45119a0bf528SMauro Carvalho Chehab 	if (status < 0)
45129a0bf528SMauro Carvalho Chehab 		goto error;
45139a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
45149a0bf528SMauro Carvalho Chehab 	if (status < 0)
45159a0bf528SMauro Carvalho Chehab 		goto error;
45169a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
45179a0bf528SMauro Carvalho Chehab 	if (status < 0)
45189a0bf528SMauro Carvalho Chehab 		goto error;
45199a0bf528SMauro Carvalho Chehab 
45209a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
45219a0bf528SMauro Carvalho Chehab 
4522ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4523ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM32);
45249a0bf528SMauro Carvalho Chehab 	if (status < 0)
45259a0bf528SMauro Carvalho Chehab 		goto error;
45269a0bf528SMauro Carvalho Chehab 
45279a0bf528SMauro Carvalho Chehab 
45289a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
45299a0bf528SMauro Carvalho Chehab 
45309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
45319a0bf528SMauro Carvalho Chehab 	if (status < 0)
45329a0bf528SMauro Carvalho Chehab 		goto error;
45339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
45349a0bf528SMauro Carvalho Chehab 	if (status < 0)
45359a0bf528SMauro Carvalho Chehab 		goto error;
45369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
45379a0bf528SMauro Carvalho Chehab 	if (status < 0)
45389a0bf528SMauro Carvalho Chehab 		goto error;
45399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
45409a0bf528SMauro Carvalho Chehab 	if (status < 0)
45419a0bf528SMauro Carvalho Chehab 		goto error;
45429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
45439a0bf528SMauro Carvalho Chehab 	if (status < 0)
45449a0bf528SMauro Carvalho Chehab 		goto error;
45459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
45469a0bf528SMauro Carvalho Chehab 	if (status < 0)
45479a0bf528SMauro Carvalho Chehab 		goto error;
45489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
45499a0bf528SMauro Carvalho Chehab 	if (status < 0)
45509a0bf528SMauro Carvalho Chehab 		goto error;
45519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
45529a0bf528SMauro Carvalho Chehab 	if (status < 0)
45539a0bf528SMauro Carvalho Chehab 		goto error;
45549a0bf528SMauro Carvalho Chehab 
45559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45569a0bf528SMauro Carvalho Chehab 	if (status < 0)
45579a0bf528SMauro Carvalho Chehab 		goto error;
45589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45599a0bf528SMauro Carvalho Chehab 	if (status < 0)
45609a0bf528SMauro Carvalho Chehab 		goto error;
45619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
45629a0bf528SMauro Carvalho Chehab 	if (status < 0)
45639a0bf528SMauro Carvalho Chehab 		goto error;
45649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
45659a0bf528SMauro Carvalho Chehab 	if (status < 0)
45669a0bf528SMauro Carvalho Chehab 		goto error;
45679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
45689a0bf528SMauro Carvalho Chehab 	if (status < 0)
45699a0bf528SMauro Carvalho Chehab 		goto error;
45709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
45719a0bf528SMauro Carvalho Chehab 	if (status < 0)
45729a0bf528SMauro Carvalho Chehab 		goto error;
45739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
45749a0bf528SMauro Carvalho Chehab 	if (status < 0)
45759a0bf528SMauro Carvalho Chehab 		goto error;
45769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
45779a0bf528SMauro Carvalho Chehab 	if (status < 0)
45789a0bf528SMauro Carvalho Chehab 		goto error;
45799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
45809a0bf528SMauro Carvalho Chehab 	if (status < 0)
45819a0bf528SMauro Carvalho Chehab 		goto error;
45829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
45839a0bf528SMauro Carvalho Chehab 	if (status < 0)
45849a0bf528SMauro Carvalho Chehab 		goto error;
45859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
45869a0bf528SMauro Carvalho Chehab 	if (status < 0)
45879a0bf528SMauro Carvalho Chehab 		goto error;
45889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
45899a0bf528SMauro Carvalho Chehab 	if (status < 0)
45909a0bf528SMauro Carvalho Chehab 		goto error;
45919a0bf528SMauro Carvalho Chehab 
45929a0bf528SMauro Carvalho Chehab 
45939a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
45949a0bf528SMauro Carvalho Chehab 
45959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
45969a0bf528SMauro Carvalho Chehab 	if (status < 0)
45979a0bf528SMauro Carvalho Chehab 		goto error;
45989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
45999a0bf528SMauro Carvalho Chehab 	if (status < 0)
46009a0bf528SMauro Carvalho Chehab 		goto error;
46019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
46029a0bf528SMauro Carvalho Chehab 	if (status < 0)
46039a0bf528SMauro Carvalho Chehab 		goto error;
46049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
46059a0bf528SMauro Carvalho Chehab 	if (status < 0)
46069a0bf528SMauro Carvalho Chehab 		goto error;
46079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
46089a0bf528SMauro Carvalho Chehab 	if (status < 0)
46099a0bf528SMauro Carvalho Chehab 		goto error;
46109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
46119a0bf528SMauro Carvalho Chehab 	if (status < 0)
46129a0bf528SMauro Carvalho Chehab 		goto error;
46139a0bf528SMauro Carvalho Chehab 
46149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
46159a0bf528SMauro Carvalho Chehab 	if (status < 0)
46169a0bf528SMauro Carvalho Chehab 		goto error;
46179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
46189a0bf528SMauro Carvalho Chehab 	if (status < 0)
46199a0bf528SMauro Carvalho Chehab 		goto error;
46209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
46219a0bf528SMauro Carvalho Chehab 	if (status < 0)
46229a0bf528SMauro Carvalho Chehab 		goto error;
46239a0bf528SMauro Carvalho Chehab 
46249a0bf528SMauro Carvalho Chehab 
46259a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
46269a0bf528SMauro Carvalho Chehab 
46279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
46289a0bf528SMauro Carvalho Chehab 	if (status < 0)
46299a0bf528SMauro Carvalho Chehab 		goto error;
46309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
46319a0bf528SMauro Carvalho Chehab 	if (status < 0)
46329a0bf528SMauro Carvalho Chehab 		goto error;
46339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
46349a0bf528SMauro Carvalho Chehab 	if (status < 0)
46359a0bf528SMauro Carvalho Chehab 		goto error;
46369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
46379a0bf528SMauro Carvalho Chehab 	if (status < 0)
46389a0bf528SMauro Carvalho Chehab 		goto error;
46399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
46409a0bf528SMauro Carvalho Chehab 	if (status < 0)
46419a0bf528SMauro Carvalho Chehab 		goto error;
46429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
46439a0bf528SMauro Carvalho Chehab 	if (status < 0)
46449a0bf528SMauro Carvalho Chehab 		goto error;
46459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
46469a0bf528SMauro Carvalho Chehab error:
46479a0bf528SMauro Carvalho Chehab 	if (status < 0)
46483a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
46499a0bf528SMauro Carvalho Chehab 	return status;
46509a0bf528SMauro Carvalho Chehab }
46519a0bf528SMauro Carvalho Chehab 
46529a0bf528SMauro Carvalho Chehab /*============================================================================*/
46539a0bf528SMauro Carvalho Chehab 
46549a0bf528SMauro Carvalho Chehab /**
46559a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46569a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46579a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46589a0bf528SMauro Carvalho Chehab */
4659cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state)
46609a0bf528SMauro Carvalho Chehab {
46619a0bf528SMauro Carvalho Chehab 	int status = 0;
46629a0bf528SMauro Carvalho Chehab 
46639a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
46649a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
46659a0bf528SMauro Carvalho Chehab 	/* Equalizer */
46669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
46679a0bf528SMauro Carvalho Chehab 	if (status < 0)
46689a0bf528SMauro Carvalho Chehab 		goto error;
46699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
46709a0bf528SMauro Carvalho Chehab 	if (status < 0)
46719a0bf528SMauro Carvalho Chehab 		goto error;
46729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
46739a0bf528SMauro Carvalho Chehab 	if (status < 0)
46749a0bf528SMauro Carvalho Chehab 		goto error;
46759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
46769a0bf528SMauro Carvalho Chehab 	if (status < 0)
46779a0bf528SMauro Carvalho Chehab 		goto error;
46789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
46799a0bf528SMauro Carvalho Chehab 	if (status < 0)
46809a0bf528SMauro Carvalho Chehab 		goto error;
46819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
46829a0bf528SMauro Carvalho Chehab 	if (status < 0)
46839a0bf528SMauro Carvalho Chehab 		goto error;
46849a0bf528SMauro Carvalho Chehab 
46859a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
46869a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
46879a0bf528SMauro Carvalho Chehab 	if (status < 0)
46889a0bf528SMauro Carvalho Chehab 		goto error;
46899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
46909a0bf528SMauro Carvalho Chehab 	if (status < 0)
46919a0bf528SMauro Carvalho Chehab 		goto error;
46929a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
46939a0bf528SMauro Carvalho Chehab 	if (status < 0)
46949a0bf528SMauro Carvalho Chehab 		goto error;
46959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
46969a0bf528SMauro Carvalho Chehab 	if (status < 0)
46979a0bf528SMauro Carvalho Chehab 		goto error;
46989a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
46999a0bf528SMauro Carvalho Chehab 	if (status < 0)
47009a0bf528SMauro Carvalho Chehab 		goto error;
47019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
47029a0bf528SMauro Carvalho Chehab 	if (status < 0)
47039a0bf528SMauro Carvalho Chehab 		goto error;
47049a0bf528SMauro Carvalho Chehab 
47059a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
47069a0bf528SMauro Carvalho Chehab 	if (status < 0)
47079a0bf528SMauro Carvalho Chehab 		goto error;
47089a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
47099a0bf528SMauro Carvalho Chehab 	if (status < 0)
47109a0bf528SMauro Carvalho Chehab 		goto error;
47119a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
47129a0bf528SMauro Carvalho Chehab 	if (status < 0)
47139a0bf528SMauro Carvalho Chehab 		goto error;
47149a0bf528SMauro Carvalho Chehab 
47159a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4716ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4717ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM64);
47189a0bf528SMauro Carvalho Chehab 	if (status < 0)
47199a0bf528SMauro Carvalho Chehab 		goto error;
47209a0bf528SMauro Carvalho Chehab 
47219a0bf528SMauro Carvalho Chehab 
47229a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
47239a0bf528SMauro Carvalho Chehab 
47249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
47259a0bf528SMauro Carvalho Chehab 	if (status < 0)
47269a0bf528SMauro Carvalho Chehab 		goto error;
47279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
47289a0bf528SMauro Carvalho Chehab 	if (status < 0)
47299a0bf528SMauro Carvalho Chehab 		goto error;
47309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
47319a0bf528SMauro Carvalho Chehab 	if (status < 0)
47329a0bf528SMauro Carvalho Chehab 		goto error;
47339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
47349a0bf528SMauro Carvalho Chehab 	if (status < 0)
47359a0bf528SMauro Carvalho Chehab 		goto error;
47369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
47379a0bf528SMauro Carvalho Chehab 	if (status < 0)
47389a0bf528SMauro Carvalho Chehab 		goto error;
47399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
47409a0bf528SMauro Carvalho Chehab 	if (status < 0)
47419a0bf528SMauro Carvalho Chehab 		goto error;
47429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
47439a0bf528SMauro Carvalho Chehab 	if (status < 0)
47449a0bf528SMauro Carvalho Chehab 		goto error;
47459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
47469a0bf528SMauro Carvalho Chehab 	if (status < 0)
47479a0bf528SMauro Carvalho Chehab 		goto error;
47489a0bf528SMauro Carvalho Chehab 
47499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
47509a0bf528SMauro Carvalho Chehab 	if (status < 0)
47519a0bf528SMauro Carvalho Chehab 		goto error;
47529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47539a0bf528SMauro Carvalho Chehab 	if (status < 0)
47549a0bf528SMauro Carvalho Chehab 		goto error;
47559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47569a0bf528SMauro Carvalho Chehab 	if (status < 0)
47579a0bf528SMauro Carvalho Chehab 		goto error;
47589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47599a0bf528SMauro Carvalho Chehab 	if (status < 0)
47609a0bf528SMauro Carvalho Chehab 		goto error;
47619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47629a0bf528SMauro Carvalho Chehab 	if (status < 0)
47639a0bf528SMauro Carvalho Chehab 		goto error;
47649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
47659a0bf528SMauro Carvalho Chehab 	if (status < 0)
47669a0bf528SMauro Carvalho Chehab 		goto error;
47679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
47689a0bf528SMauro Carvalho Chehab 	if (status < 0)
47699a0bf528SMauro Carvalho Chehab 		goto error;
47709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
47719a0bf528SMauro Carvalho Chehab 	if (status < 0)
47729a0bf528SMauro Carvalho Chehab 		goto error;
47739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
47749a0bf528SMauro Carvalho Chehab 	if (status < 0)
47759a0bf528SMauro Carvalho Chehab 		goto error;
47769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
47779a0bf528SMauro Carvalho Chehab 	if (status < 0)
47789a0bf528SMauro Carvalho Chehab 		goto error;
47799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
47809a0bf528SMauro Carvalho Chehab 	if (status < 0)
47819a0bf528SMauro Carvalho Chehab 		goto error;
47829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
47839a0bf528SMauro Carvalho Chehab 	if (status < 0)
47849a0bf528SMauro Carvalho Chehab 		goto error;
47859a0bf528SMauro Carvalho Chehab 
47869a0bf528SMauro Carvalho Chehab 
47879a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
47889a0bf528SMauro Carvalho Chehab 
47899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
47909a0bf528SMauro Carvalho Chehab 	if (status < 0)
47919a0bf528SMauro Carvalho Chehab 		goto error;
47929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
47939a0bf528SMauro Carvalho Chehab 	if (status < 0)
47949a0bf528SMauro Carvalho Chehab 		goto error;
47959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
47969a0bf528SMauro Carvalho Chehab 	if (status < 0)
47979a0bf528SMauro Carvalho Chehab 		goto error;
47989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
47999a0bf528SMauro Carvalho Chehab 	if (status < 0)
48009a0bf528SMauro Carvalho Chehab 		goto error;
48019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
48029a0bf528SMauro Carvalho Chehab 	if (status < 0)
48039a0bf528SMauro Carvalho Chehab 		goto error;
48049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
48059a0bf528SMauro Carvalho Chehab 	if (status < 0)
48069a0bf528SMauro Carvalho Chehab 		goto error;
48079a0bf528SMauro Carvalho Chehab 
48089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
48099a0bf528SMauro Carvalho Chehab 	if (status < 0)
48109a0bf528SMauro Carvalho Chehab 		goto error;
48119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
48129a0bf528SMauro Carvalho Chehab 	if (status < 0)
48139a0bf528SMauro Carvalho Chehab 		goto error;
48149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
48159a0bf528SMauro Carvalho Chehab 	if (status < 0)
48169a0bf528SMauro Carvalho Chehab 		goto error;
48179a0bf528SMauro Carvalho Chehab 
48189a0bf528SMauro Carvalho Chehab 
48199a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
48209a0bf528SMauro Carvalho Chehab 
48219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
48229a0bf528SMauro Carvalho Chehab 	if (status < 0)
48239a0bf528SMauro Carvalho Chehab 		goto error;
48249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
48259a0bf528SMauro Carvalho Chehab 	if (status < 0)
48269a0bf528SMauro Carvalho Chehab 		goto error;
48279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
48289a0bf528SMauro Carvalho Chehab 	if (status < 0)
48299a0bf528SMauro Carvalho Chehab 		goto error;
48309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
48319a0bf528SMauro Carvalho Chehab 	if (status < 0)
48329a0bf528SMauro Carvalho Chehab 		goto error;
48339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
48349a0bf528SMauro Carvalho Chehab 	if (status < 0)
48359a0bf528SMauro Carvalho Chehab 		goto error;
48369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
48379a0bf528SMauro Carvalho Chehab 	if (status < 0)
48389a0bf528SMauro Carvalho Chehab 		goto error;
48399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
48409a0bf528SMauro Carvalho Chehab error:
48419a0bf528SMauro Carvalho Chehab 	if (status < 0)
48423a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
48439a0bf528SMauro Carvalho Chehab 
48449a0bf528SMauro Carvalho Chehab 	return status;
48459a0bf528SMauro Carvalho Chehab }
48469a0bf528SMauro Carvalho Chehab 
48479a0bf528SMauro Carvalho Chehab /*============================================================================*/
48489a0bf528SMauro Carvalho Chehab 
48499a0bf528SMauro Carvalho Chehab /**
48509a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
48519a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
48529a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48539a0bf528SMauro Carvalho Chehab */
4854cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state)
48559a0bf528SMauro Carvalho Chehab {
48569a0bf528SMauro Carvalho Chehab 	int status = 0;
48579a0bf528SMauro Carvalho Chehab 
48589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
48599a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
48609a0bf528SMauro Carvalho Chehab 	/* Equalizer */
48619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48629a0bf528SMauro Carvalho Chehab 	if (status < 0)
48639a0bf528SMauro Carvalho Chehab 		goto error;
48649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
48659a0bf528SMauro Carvalho Chehab 	if (status < 0)
48669a0bf528SMauro Carvalho Chehab 		goto error;
48679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
48689a0bf528SMauro Carvalho Chehab 	if (status < 0)
48699a0bf528SMauro Carvalho Chehab 		goto error;
48709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
48719a0bf528SMauro Carvalho Chehab 	if (status < 0)
48729a0bf528SMauro Carvalho Chehab 		goto error;
48739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
48749a0bf528SMauro Carvalho Chehab 	if (status < 0)
48759a0bf528SMauro Carvalho Chehab 		goto error;
48769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
48779a0bf528SMauro Carvalho Chehab 	if (status < 0)
48789a0bf528SMauro Carvalho Chehab 		goto error;
48799a0bf528SMauro Carvalho Chehab 
48809a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
48819a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
48829a0bf528SMauro Carvalho Chehab 	if (status < 0)
48839a0bf528SMauro Carvalho Chehab 		goto error;
48849a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
48859a0bf528SMauro Carvalho Chehab 	if (status < 0)
48869a0bf528SMauro Carvalho Chehab 		goto error;
48879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
48889a0bf528SMauro Carvalho Chehab 	if (status < 0)
48899a0bf528SMauro Carvalho Chehab 		goto error;
48909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
48919a0bf528SMauro Carvalho Chehab 	if (status < 0)
48929a0bf528SMauro Carvalho Chehab 		goto error;
48939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
48949a0bf528SMauro Carvalho Chehab 	if (status < 0)
48959a0bf528SMauro Carvalho Chehab 		goto error;
48969a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
48979a0bf528SMauro Carvalho Chehab 	if (status < 0)
48989a0bf528SMauro Carvalho Chehab 		goto error;
48999a0bf528SMauro Carvalho Chehab 
49009a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
49019a0bf528SMauro Carvalho Chehab 	if (status < 0)
49029a0bf528SMauro Carvalho Chehab 		goto error;
49039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
49049a0bf528SMauro Carvalho Chehab 	if (status < 0)
49059a0bf528SMauro Carvalho Chehab 		goto error;
49069a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
49079a0bf528SMauro Carvalho Chehab 	if (status < 0)
49089a0bf528SMauro Carvalho Chehab 		goto error;
49099a0bf528SMauro Carvalho Chehab 
49109a0bf528SMauro Carvalho Chehab 
49119a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
49129a0bf528SMauro Carvalho Chehab 
4913ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4914ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM128);
49159a0bf528SMauro Carvalho Chehab 	if (status < 0)
49169a0bf528SMauro Carvalho Chehab 		goto error;
49179a0bf528SMauro Carvalho Chehab 
49189a0bf528SMauro Carvalho Chehab 
49199a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
49209a0bf528SMauro Carvalho Chehab 
49219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
49229a0bf528SMauro Carvalho Chehab 	if (status < 0)
49239a0bf528SMauro Carvalho Chehab 		goto error;
49249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
49259a0bf528SMauro Carvalho Chehab 	if (status < 0)
49269a0bf528SMauro Carvalho Chehab 		goto error;
49279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
49289a0bf528SMauro Carvalho Chehab 	if (status < 0)
49299a0bf528SMauro Carvalho Chehab 		goto error;
49309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
49319a0bf528SMauro Carvalho Chehab 	if (status < 0)
49329a0bf528SMauro Carvalho Chehab 		goto error;
49339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
49349a0bf528SMauro Carvalho Chehab 	if (status < 0)
49359a0bf528SMauro Carvalho Chehab 		goto error;
49369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
49379a0bf528SMauro Carvalho Chehab 	if (status < 0)
49389a0bf528SMauro Carvalho Chehab 		goto error;
49399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
49409a0bf528SMauro Carvalho Chehab 	if (status < 0)
49419a0bf528SMauro Carvalho Chehab 		goto error;
49429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
49439a0bf528SMauro Carvalho Chehab 	if (status < 0)
49449a0bf528SMauro Carvalho Chehab 		goto error;
49459a0bf528SMauro Carvalho Chehab 
49469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
49479a0bf528SMauro Carvalho Chehab 	if (status < 0)
49489a0bf528SMauro Carvalho Chehab 		goto error;
49499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
49509a0bf528SMauro Carvalho Chehab 	if (status < 0)
49519a0bf528SMauro Carvalho Chehab 		goto error;
49529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49539a0bf528SMauro Carvalho Chehab 	if (status < 0)
49549a0bf528SMauro Carvalho Chehab 		goto error;
49559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49569a0bf528SMauro Carvalho Chehab 	if (status < 0)
49579a0bf528SMauro Carvalho Chehab 		goto error;
49589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49599a0bf528SMauro Carvalho Chehab 	if (status < 0)
49609a0bf528SMauro Carvalho Chehab 		goto error;
49619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49629a0bf528SMauro Carvalho Chehab 	if (status < 0)
49639a0bf528SMauro Carvalho Chehab 		goto error;
49649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
49659a0bf528SMauro Carvalho Chehab 	if (status < 0)
49669a0bf528SMauro Carvalho Chehab 		goto error;
49679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
49689a0bf528SMauro Carvalho Chehab 	if (status < 0)
49699a0bf528SMauro Carvalho Chehab 		goto error;
49709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
49719a0bf528SMauro Carvalho Chehab 	if (status < 0)
49729a0bf528SMauro Carvalho Chehab 		goto error;
49739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
49749a0bf528SMauro Carvalho Chehab 	if (status < 0)
49759a0bf528SMauro Carvalho Chehab 		goto error;
49769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
49779a0bf528SMauro Carvalho Chehab 	if (status < 0)
49789a0bf528SMauro Carvalho Chehab 		goto error;
49799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
49809a0bf528SMauro Carvalho Chehab 	if (status < 0)
49819a0bf528SMauro Carvalho Chehab 		goto error;
49829a0bf528SMauro Carvalho Chehab 
49839a0bf528SMauro Carvalho Chehab 
49849a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
49859a0bf528SMauro Carvalho Chehab 
49869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
49879a0bf528SMauro Carvalho Chehab 	if (status < 0)
49889a0bf528SMauro Carvalho Chehab 		goto error;
49899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
49909a0bf528SMauro Carvalho Chehab 	if (status < 0)
49919a0bf528SMauro Carvalho Chehab 		goto error;
49929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
49939a0bf528SMauro Carvalho Chehab 	if (status < 0)
49949a0bf528SMauro Carvalho Chehab 		goto error;
49959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
49969a0bf528SMauro Carvalho Chehab 	if (status < 0)
49979a0bf528SMauro Carvalho Chehab 		goto error;
49989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
49999a0bf528SMauro Carvalho Chehab 	if (status < 0)
50009a0bf528SMauro Carvalho Chehab 		goto error;
50019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
50029a0bf528SMauro Carvalho Chehab 	if (status < 0)
50039a0bf528SMauro Carvalho Chehab 		goto error;
50049a0bf528SMauro Carvalho Chehab 
50059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
50069a0bf528SMauro Carvalho Chehab 	if (status < 0)
50079a0bf528SMauro Carvalho Chehab 		goto error;
50089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
50099a0bf528SMauro Carvalho Chehab 	if (status < 0)
50109a0bf528SMauro Carvalho Chehab 		goto error;
50119a0bf528SMauro Carvalho Chehab 
50129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
50139a0bf528SMauro Carvalho Chehab 	if (status < 0)
50149a0bf528SMauro Carvalho Chehab 		goto error;
50159a0bf528SMauro Carvalho Chehab 
50169a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
50179a0bf528SMauro Carvalho Chehab 
50189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
50199a0bf528SMauro Carvalho Chehab 	if (status < 0)
50209a0bf528SMauro Carvalho Chehab 		goto error;
50219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
50229a0bf528SMauro Carvalho Chehab 	if (status < 0)
50239a0bf528SMauro Carvalho Chehab 		goto error;
50249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
50259a0bf528SMauro Carvalho Chehab 	if (status < 0)
50269a0bf528SMauro Carvalho Chehab 		goto error;
50279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
50289a0bf528SMauro Carvalho Chehab 	if (status < 0)
50299a0bf528SMauro Carvalho Chehab 		goto error;
50309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
50319a0bf528SMauro Carvalho Chehab 	if (status < 0)
50329a0bf528SMauro Carvalho Chehab 		goto error;
50339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
50349a0bf528SMauro Carvalho Chehab 	if (status < 0)
50359a0bf528SMauro Carvalho Chehab 		goto error;
50369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
50379a0bf528SMauro Carvalho Chehab error:
50389a0bf528SMauro Carvalho Chehab 	if (status < 0)
50393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
50409a0bf528SMauro Carvalho Chehab 
50419a0bf528SMauro Carvalho Chehab 	return status;
50429a0bf528SMauro Carvalho Chehab }
50439a0bf528SMauro Carvalho Chehab 
50449a0bf528SMauro Carvalho Chehab /*============================================================================*/
50459a0bf528SMauro Carvalho Chehab 
50469a0bf528SMauro Carvalho Chehab /**
50479a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
50489a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
50499a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
50509a0bf528SMauro Carvalho Chehab */
5051cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state)
50529a0bf528SMauro Carvalho Chehab {
50539a0bf528SMauro Carvalho Chehab 	int status = 0;
50549a0bf528SMauro Carvalho Chehab 
50559a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
50569a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
50579a0bf528SMauro Carvalho Chehab 	/* Equalizer */
50589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50599a0bf528SMauro Carvalho Chehab 	if (status < 0)
50609a0bf528SMauro Carvalho Chehab 		goto error;
50619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50629a0bf528SMauro Carvalho Chehab 	if (status < 0)
50639a0bf528SMauro Carvalho Chehab 		goto error;
50649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
50659a0bf528SMauro Carvalho Chehab 	if (status < 0)
50669a0bf528SMauro Carvalho Chehab 		goto error;
50679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
50689a0bf528SMauro Carvalho Chehab 	if (status < 0)
50699a0bf528SMauro Carvalho Chehab 		goto error;
50709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
50719a0bf528SMauro Carvalho Chehab 	if (status < 0)
50729a0bf528SMauro Carvalho Chehab 		goto error;
50739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
50749a0bf528SMauro Carvalho Chehab 	if (status < 0)
50759a0bf528SMauro Carvalho Chehab 		goto error;
50769a0bf528SMauro Carvalho Chehab 
50779a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
50789a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
50799a0bf528SMauro Carvalho Chehab 	if (status < 0)
50809a0bf528SMauro Carvalho Chehab 		goto error;
50819a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
50829a0bf528SMauro Carvalho Chehab 	if (status < 0)
50839a0bf528SMauro Carvalho Chehab 		goto error;
50849a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
50859a0bf528SMauro Carvalho Chehab 	if (status < 0)
50869a0bf528SMauro Carvalho Chehab 		goto error;
50879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
50889a0bf528SMauro Carvalho Chehab 	if (status < 0)
50899a0bf528SMauro Carvalho Chehab 		goto error;
50909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
50919a0bf528SMauro Carvalho Chehab 	if (status < 0)
50929a0bf528SMauro Carvalho Chehab 		goto error;
50939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
50949a0bf528SMauro Carvalho Chehab 	if (status < 0)
50959a0bf528SMauro Carvalho Chehab 		goto error;
50969a0bf528SMauro Carvalho Chehab 
50979a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
50989a0bf528SMauro Carvalho Chehab 	if (status < 0)
50999a0bf528SMauro Carvalho Chehab 		goto error;
51009a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
51019a0bf528SMauro Carvalho Chehab 	if (status < 0)
51029a0bf528SMauro Carvalho Chehab 		goto error;
51039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
51049a0bf528SMauro Carvalho Chehab 	if (status < 0)
51059a0bf528SMauro Carvalho Chehab 		goto error;
51069a0bf528SMauro Carvalho Chehab 
51079a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
51089a0bf528SMauro Carvalho Chehab 
5109ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5110ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM256);
51119a0bf528SMauro Carvalho Chehab 	if (status < 0)
51129a0bf528SMauro Carvalho Chehab 		goto error;
51139a0bf528SMauro Carvalho Chehab 
51149a0bf528SMauro Carvalho Chehab 
51159a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
51169a0bf528SMauro Carvalho Chehab 
51179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
51189a0bf528SMauro Carvalho Chehab 	if (status < 0)
51199a0bf528SMauro Carvalho Chehab 		goto error;
51209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
51219a0bf528SMauro Carvalho Chehab 	if (status < 0)
51229a0bf528SMauro Carvalho Chehab 		goto error;
51239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
51249a0bf528SMauro Carvalho Chehab 	if (status < 0)
51259a0bf528SMauro Carvalho Chehab 		goto error;
51269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
51279a0bf528SMauro Carvalho Chehab 	if (status < 0)
51289a0bf528SMauro Carvalho Chehab 		goto error;
51299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
51309a0bf528SMauro Carvalho Chehab 	if (status < 0)
51319a0bf528SMauro Carvalho Chehab 		goto error;
51329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
51339a0bf528SMauro Carvalho Chehab 	if (status < 0)
51349a0bf528SMauro Carvalho Chehab 		goto error;
51359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
51369a0bf528SMauro Carvalho Chehab 	if (status < 0)
51379a0bf528SMauro Carvalho Chehab 		goto error;
51389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
51399a0bf528SMauro Carvalho Chehab 	if (status < 0)
51409a0bf528SMauro Carvalho Chehab 		goto error;
51419a0bf528SMauro Carvalho Chehab 
51429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
51439a0bf528SMauro Carvalho Chehab 	if (status < 0)
51449a0bf528SMauro Carvalho Chehab 		goto error;
51459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
51469a0bf528SMauro Carvalho Chehab 	if (status < 0)
51479a0bf528SMauro Carvalho Chehab 		goto error;
51489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
51499a0bf528SMauro Carvalho Chehab 	if (status < 0)
51509a0bf528SMauro Carvalho Chehab 		goto error;
51519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
51529a0bf528SMauro Carvalho Chehab 	if (status < 0)
51539a0bf528SMauro Carvalho Chehab 		goto error;
51549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51559a0bf528SMauro Carvalho Chehab 	if (status < 0)
51569a0bf528SMauro Carvalho Chehab 		goto error;
51579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51589a0bf528SMauro Carvalho Chehab 	if (status < 0)
51599a0bf528SMauro Carvalho Chehab 		goto error;
51609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51619a0bf528SMauro Carvalho Chehab 	if (status < 0)
51629a0bf528SMauro Carvalho Chehab 		goto error;
51639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51649a0bf528SMauro Carvalho Chehab 	if (status < 0)
51659a0bf528SMauro Carvalho Chehab 		goto error;
51669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
51679a0bf528SMauro Carvalho Chehab 	if (status < 0)
51689a0bf528SMauro Carvalho Chehab 		goto error;
51699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
51709a0bf528SMauro Carvalho Chehab 	if (status < 0)
51719a0bf528SMauro Carvalho Chehab 		goto error;
51729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
51739a0bf528SMauro Carvalho Chehab 	if (status < 0)
51749a0bf528SMauro Carvalho Chehab 		goto error;
51759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
51769a0bf528SMauro Carvalho Chehab 	if (status < 0)
51779a0bf528SMauro Carvalho Chehab 		goto error;
51789a0bf528SMauro Carvalho Chehab 
51799a0bf528SMauro Carvalho Chehab 
51809a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
51819a0bf528SMauro Carvalho Chehab 
51829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
51839a0bf528SMauro Carvalho Chehab 	if (status < 0)
51849a0bf528SMauro Carvalho Chehab 		goto error;
51859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
51869a0bf528SMauro Carvalho Chehab 	if (status < 0)
51879a0bf528SMauro Carvalho Chehab 		goto error;
51889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
51899a0bf528SMauro Carvalho Chehab 	if (status < 0)
51909a0bf528SMauro Carvalho Chehab 		goto error;
51919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
51929a0bf528SMauro Carvalho Chehab 	if (status < 0)
51939a0bf528SMauro Carvalho Chehab 		goto error;
51949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
51959a0bf528SMauro Carvalho Chehab 	if (status < 0)
51969a0bf528SMauro Carvalho Chehab 		goto error;
51979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
51989a0bf528SMauro Carvalho Chehab 	if (status < 0)
51999a0bf528SMauro Carvalho Chehab 		goto error;
52009a0bf528SMauro Carvalho Chehab 
52019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
52029a0bf528SMauro Carvalho Chehab 	if (status < 0)
52039a0bf528SMauro Carvalho Chehab 		goto error;
52049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
52059a0bf528SMauro Carvalho Chehab 	if (status < 0)
52069a0bf528SMauro Carvalho Chehab 		goto error;
52079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
52089a0bf528SMauro Carvalho Chehab 	if (status < 0)
52099a0bf528SMauro Carvalho Chehab 		goto error;
52109a0bf528SMauro Carvalho Chehab 
52119a0bf528SMauro Carvalho Chehab 
52129a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
52139a0bf528SMauro Carvalho Chehab 
52149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
52159a0bf528SMauro Carvalho Chehab 	if (status < 0)
52169a0bf528SMauro Carvalho Chehab 		goto error;
52179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
52189a0bf528SMauro Carvalho Chehab 	if (status < 0)
52199a0bf528SMauro Carvalho Chehab 		goto error;
52209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
52219a0bf528SMauro Carvalho Chehab 	if (status < 0)
52229a0bf528SMauro Carvalho Chehab 		goto error;
52239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
52249a0bf528SMauro Carvalho Chehab 	if (status < 0)
52259a0bf528SMauro Carvalho Chehab 		goto error;
52269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
52279a0bf528SMauro Carvalho Chehab 	if (status < 0)
52289a0bf528SMauro Carvalho Chehab 		goto error;
52299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
52309a0bf528SMauro Carvalho Chehab 	if (status < 0)
52319a0bf528SMauro Carvalho Chehab 		goto error;
52329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
52339a0bf528SMauro Carvalho Chehab error:
52349a0bf528SMauro Carvalho Chehab 	if (status < 0)
52353a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52369a0bf528SMauro Carvalho Chehab 	return status;
52379a0bf528SMauro Carvalho Chehab }
52389a0bf528SMauro Carvalho Chehab 
52399a0bf528SMauro Carvalho Chehab 
52409a0bf528SMauro Carvalho Chehab /*============================================================================*/
52419a0bf528SMauro Carvalho Chehab /**
52429a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
52439a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52449a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52459a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52469a0bf528SMauro Carvalho Chehab */
5247cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state)
52489a0bf528SMauro Carvalho Chehab {
52499a0bf528SMauro Carvalho Chehab 	int status;
5250cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
52519a0bf528SMauro Carvalho Chehab 
52529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52539a0bf528SMauro Carvalho Chehab 	/* Stop QAM comstate->m_exec */
52549a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52559a0bf528SMauro Carvalho Chehab 	if (status < 0)
52569a0bf528SMauro Carvalho Chehab 		goto error;
52579a0bf528SMauro Carvalho Chehab 
5258ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5259ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5260ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
52619a0bf528SMauro Carvalho Chehab error:
52629a0bf528SMauro Carvalho Chehab 	if (status < 0)
52633a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52649a0bf528SMauro Carvalho Chehab 	return status;
52659a0bf528SMauro Carvalho Chehab }
52669a0bf528SMauro Carvalho Chehab 
52679a0bf528SMauro Carvalho Chehab /*============================================================================*/
52689a0bf528SMauro Carvalho Chehab 
52699a0bf528SMauro Carvalho Chehab /**
52709a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
52719a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52729a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52739a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52749a0bf528SMauro Carvalho Chehab */
5275cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state)
52769a0bf528SMauro Carvalho Chehab {
5277cd7a67a4SMauro Carvalho Chehab 	u32 adc_frequency = 0;
5278cd7a67a4SMauro Carvalho Chehab 	u32 symb_freq = 0;
5279cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate = 0;
52809a0bf528SMauro Carvalho Chehab 	u16 ratesel = 0;
5281cd7a67a4SMauro Carvalho Chehab 	u32 lc_symb_rate = 0;
52829a0bf528SMauro Carvalho Chehab 	int status;
52839a0bf528SMauro Carvalho Chehab 
52849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52859a0bf528SMauro Carvalho Chehab 	/* Select & calculate correct IQM rate */
5286cd7a67a4SMauro Carvalho Chehab 	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
52879a0bf528SMauro Carvalho Chehab 	ratesel = 0;
52889a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
52899a0bf528SMauro Carvalho Chehab 	if (state->props.symbol_rate <= 1188750)
52909a0bf528SMauro Carvalho Chehab 		ratesel = 3;
52919a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 2377500)
52929a0bf528SMauro Carvalho Chehab 		ratesel = 2;
52939a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 4755000)
52949a0bf528SMauro Carvalho Chehab 		ratesel = 1;
52959a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FD_RATESEL__A, ratesel);
52969a0bf528SMauro Carvalho Chehab 	if (status < 0)
52979a0bf528SMauro Carvalho Chehab 		goto error;
52989a0bf528SMauro Carvalho Chehab 
52999a0bf528SMauro Carvalho Chehab 	/*
53009a0bf528SMauro Carvalho Chehab 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
53019a0bf528SMauro Carvalho Chehab 		*/
5302cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate * (1 << ratesel);
5303cd7a67a4SMauro Carvalho Chehab 	if (symb_freq == 0) {
53049a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53059a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53069a0bf528SMauro Carvalho Chehab 		goto error;
53079a0bf528SMauro Carvalho Chehab 	}
5308cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5309cd7a67a4SMauro Carvalho Chehab 		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
53109a0bf528SMauro Carvalho Chehab 		(1 << 23);
5311cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
53129a0bf528SMauro Carvalho Chehab 	if (status < 0)
53139a0bf528SMauro Carvalho Chehab 		goto error;
5314cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_rc_rate = iqm_rc_rate;
53159a0bf528SMauro Carvalho Chehab 	/*
5316cd7a67a4SMauro Carvalho Chehab 		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
53179a0bf528SMauro Carvalho Chehab 		*/
5318cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate;
5319cd7a67a4SMauro Carvalho Chehab 	if (adc_frequency == 0) {
53209a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53219a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53229a0bf528SMauro Carvalho Chehab 		goto error;
53239a0bf528SMauro Carvalho Chehab 	}
5324cd7a67a4SMauro Carvalho Chehab 	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5325cd7a67a4SMauro Carvalho Chehab 		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
53269a0bf528SMauro Carvalho Chehab 		16);
5327cd7a67a4SMauro Carvalho Chehab 	if (lc_symb_rate > 511)
5328cd7a67a4SMauro Carvalho Chehab 		lc_symb_rate = 511;
5329cd7a67a4SMauro Carvalho Chehab 	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
53309a0bf528SMauro Carvalho Chehab 
53319a0bf528SMauro Carvalho Chehab error:
53329a0bf528SMauro Carvalho Chehab 	if (status < 0)
53333a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53349a0bf528SMauro Carvalho Chehab 	return status;
53359a0bf528SMauro Carvalho Chehab }
53369a0bf528SMauro Carvalho Chehab 
53379a0bf528SMauro Carvalho Chehab /*============================================================================*/
53389a0bf528SMauro Carvalho Chehab 
53399a0bf528SMauro Carvalho Chehab /**
53409a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
53419a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
53429a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
53439a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
53449a0bf528SMauro Carvalho Chehab */
53459a0bf528SMauro Carvalho Chehab 
5346cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
53479a0bf528SMauro Carvalho Chehab {
53489a0bf528SMauro Carvalho Chehab 	int status;
5349cd7a67a4SMauro Carvalho Chehab 	u16 result[2] = { 0, 0 };
53509a0bf528SMauro Carvalho Chehab 
53519a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5352cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
53539a0bf528SMauro Carvalho Chehab 	status = scu_command(state,
53549a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_STANDARD_QAM |
53559a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5356cd7a67a4SMauro Carvalho Chehab 			result);
53579a0bf528SMauro Carvalho Chehab 	if (status < 0)
53583a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53599a0bf528SMauro Carvalho Chehab 
5360cd7a67a4SMauro Carvalho Chehab 	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53619a0bf528SMauro Carvalho Chehab 		/* 0x0000 NOT LOCKED */
5362cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53639a0bf528SMauro Carvalho Chehab 		/* 0x4000 DEMOD LOCKED */
5364cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
5365cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53669a0bf528SMauro Carvalho Chehab 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
5367cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
53689a0bf528SMauro Carvalho Chehab 	} else {
53699a0bf528SMauro Carvalho Chehab 		/* 0xC000 NEVER LOCKED */
53709a0bf528SMauro Carvalho Chehab 		/* (system will never be able to lock to the signal) */
5371ab5060cdSMauro Carvalho Chehab 		/*
5372ab5060cdSMauro Carvalho Chehab 		 * TODO: check this, intermediate & standard specific lock
5373ab5060cdSMauro Carvalho Chehab 		 * states are not taken into account here
5374ab5060cdSMauro Carvalho Chehab 		 */
5375cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
53769a0bf528SMauro Carvalho Chehab 	}
53779a0bf528SMauro Carvalho Chehab 	return status;
53789a0bf528SMauro Carvalho Chehab }
53799a0bf528SMauro Carvalho Chehab 
53809a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M         0x03
53819a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL     0x00
53829a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED          0x01
53839a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON    0x02
53849a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M      0x10
53859a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL  0x10
53869a0bf528SMauro Carvalho Chehab 
5387cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state,
5388cd7a67a4SMauro Carvalho Chehab 				 int number_of_parameters)
53899a0bf528SMauro Carvalho Chehab {
53909a0bf528SMauro Carvalho Chehab 	int status;
5391cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5392cd7a67a4SMauro Carvalho Chehab 	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
53939a0bf528SMauro Carvalho Chehab 
5394cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[0] = state->m_constellation;	/* modulation     */
5395cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
53969a0bf528SMauro Carvalho Chehab 
5397cd7a67a4SMauro Carvalho Chehab 	if (number_of_parameters == 2) {
5398cd7a67a4SMauro Carvalho Chehab 		u16 set_env_parameters[1] = { 0 };
53999a0bf528SMauro Carvalho Chehab 
5400cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5401cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_C;
54029a0bf528SMauro Carvalho Chehab 		else
5403cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_A;
54049a0bf528SMauro Carvalho Chehab 
54059a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5406ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5407ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5408cd7a67a4SMauro Carvalho Chehab 				     1, set_env_parameters, 1, &cmd_result);
54099a0bf528SMauro Carvalho Chehab 		if (status < 0)
54109a0bf528SMauro Carvalho Chehab 			goto error;
54119a0bf528SMauro Carvalho Chehab 
54129a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5413ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5414ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5415cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5416cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
5417cd7a67a4SMauro Carvalho Chehab 	} else if (number_of_parameters == 4) {
5418cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5419cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_C;
54209a0bf528SMauro Carvalho Chehab 		else
5421cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_A;
54229a0bf528SMauro Carvalho Chehab 
5423cd7a67a4SMauro Carvalho Chehab 		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
54249a0bf528SMauro Carvalho Chehab 		/* Env parameters */
54259a0bf528SMauro Carvalho Chehab 		/* check for LOCKRANGE Extented */
5426cd7a67a4SMauro Carvalho Chehab 		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
54279a0bf528SMauro Carvalho Chehab 
54289a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5429ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5430ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5431cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5432cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
54339a0bf528SMauro Carvalho Chehab 	} else {
54343a4398f5SMauro Carvalho Chehab 		pr_warn("Unknown QAM demodulator parameter count %d\n",
54353a4398f5SMauro Carvalho Chehab 			number_of_parameters);
543694af1b63SMauro Carvalho Chehab 		status = -EINVAL;
54379a0bf528SMauro Carvalho Chehab 	}
54389a0bf528SMauro Carvalho Chehab 
54399a0bf528SMauro Carvalho Chehab error:
54409a0bf528SMauro Carvalho Chehab 	if (status < 0)
54413a4398f5SMauro Carvalho Chehab 		pr_warn("Warning %d on %s\n", status, __func__);
54429a0bf528SMauro Carvalho Chehab 	return status;
54439a0bf528SMauro Carvalho Chehab }
54449a0bf528SMauro Carvalho Chehab 
5445cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5446cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset)
54479a0bf528SMauro Carvalho Chehab {
54489a0bf528SMauro Carvalho Chehab 	int status;
5449cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5450cd7a67a4SMauro Carvalho Chehab 	int qam_demod_param_count = state->qam_demod_parameter_count;
54519a0bf528SMauro Carvalho Chehab 
54529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
54539a0bf528SMauro Carvalho Chehab 	/*
54549a0bf528SMauro Carvalho Chehab 	 * STEP 1: reset demodulator
54559a0bf528SMauro Carvalho Chehab 	 *	resets FEC DI and FEC RS
54569a0bf528SMauro Carvalho Chehab 	 *	resets QAM block
54579a0bf528SMauro Carvalho Chehab 	 *	resets SCU variables
54589a0bf528SMauro Carvalho Chehab 	 */
54599a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54609a0bf528SMauro Carvalho Chehab 	if (status < 0)
54619a0bf528SMauro Carvalho Chehab 		goto error;
54629a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54639a0bf528SMauro Carvalho Chehab 	if (status < 0)
54649a0bf528SMauro Carvalho Chehab 		goto error;
5465cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
54669a0bf528SMauro Carvalho Chehab 	if (status < 0)
54679a0bf528SMauro Carvalho Chehab 		goto error;
54689a0bf528SMauro Carvalho Chehab 
54699a0bf528SMauro Carvalho Chehab 	/*
54709a0bf528SMauro Carvalho Chehab 	 * STEP 2: configure demodulator
54719a0bf528SMauro Carvalho Chehab 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
54729a0bf528SMauro Carvalho Chehab 	 *       SCU variables
54739a0bf528SMauro Carvalho Chehab 	 */
5474cd7a67a4SMauro Carvalho Chehab 	status = qam_set_symbolrate(state);
54759a0bf528SMauro Carvalho Chehab 	if (status < 0)
54769a0bf528SMauro Carvalho Chehab 		goto error;
54779a0bf528SMauro Carvalho Chehab 
54789a0bf528SMauro Carvalho Chehab 	/* Set params */
54799a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
54809a0bf528SMauro Carvalho Chehab 	case QAM_256:
5481cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM256;
54829a0bf528SMauro Carvalho Chehab 		break;
54839a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
54849a0bf528SMauro Carvalho Chehab 	case QAM_64:
5485cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM64;
54869a0bf528SMauro Carvalho Chehab 		break;
54879a0bf528SMauro Carvalho Chehab 	case QAM_16:
5488cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM16;
54899a0bf528SMauro Carvalho Chehab 		break;
54909a0bf528SMauro Carvalho Chehab 	case QAM_32:
5491cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM32;
54929a0bf528SMauro Carvalho Chehab 		break;
54939a0bf528SMauro Carvalho Chehab 	case QAM_128:
5494cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM128;
54959a0bf528SMauro Carvalho Chehab 		break;
54969a0bf528SMauro Carvalho Chehab 	default:
54979a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
54989a0bf528SMauro Carvalho Chehab 		break;
54999a0bf528SMauro Carvalho Chehab 	}
55009a0bf528SMauro Carvalho Chehab 	if (status < 0)
55019a0bf528SMauro Carvalho Chehab 		goto error;
55029a0bf528SMauro Carvalho Chehab 
55039a0bf528SMauro Carvalho Chehab 	/* Use the 4-parameter if it's requested or we're probing for
55049a0bf528SMauro Carvalho Chehab 	 * the correct command. */
55059a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 4
55069a0bf528SMauro Carvalho Chehab 		|| !state->qam_demod_parameter_count) {
5507cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 4;
5508cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
55099a0bf528SMauro Carvalho Chehab 	}
55109a0bf528SMauro Carvalho Chehab 
55119a0bf528SMauro Carvalho Chehab 	/* Use the 2-parameter command if it was requested or if we're
55129a0bf528SMauro Carvalho Chehab 	 * probing for the correct command and the 4-parameter command
55139a0bf528SMauro Carvalho Chehab 	 * failed. */
55149a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 2
55159a0bf528SMauro Carvalho Chehab 		|| (!state->qam_demod_parameter_count && status < 0)) {
5516cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 2;
5517cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
55189a0bf528SMauro Carvalho Chehab 	}
55199a0bf528SMauro Carvalho Chehab 
55209a0bf528SMauro Carvalho Chehab 	if (status < 0) {
55210fb220f2SMauro Carvalho Chehab 		dprintk(1, "Could not set demodulator parameters.\n");
55220fb220f2SMauro Carvalho Chehab 		dprintk(1,
55230fb220f2SMauro Carvalho Chehab 			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
55249a0bf528SMauro Carvalho Chehab 			state->qam_demod_parameter_count,
55259a0bf528SMauro Carvalho Chehab 			state->microcode_name);
55269a0bf528SMauro Carvalho Chehab 		goto error;
55279a0bf528SMauro Carvalho Chehab 	} else if (!state->qam_demod_parameter_count) {
55280fb220f2SMauro Carvalho Chehab 		dprintk(1,
55290fb220f2SMauro Carvalho Chehab 			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
5530cd7a67a4SMauro Carvalho Chehab 			qam_demod_param_count);
55319a0bf528SMauro Carvalho Chehab 
55329a0bf528SMauro Carvalho Chehab 		/*
55339a0bf528SMauro Carvalho Chehab 		 * One of our commands was successful. We don't need to
55349a0bf528SMauro Carvalho Chehab 		 * auto-probe anymore, now that we got the correct command.
55359a0bf528SMauro Carvalho Chehab 		 */
5536cd7a67a4SMauro Carvalho Chehab 		state->qam_demod_parameter_count = qam_demod_param_count;
55379a0bf528SMauro Carvalho Chehab 	}
55389a0bf528SMauro Carvalho Chehab 
55399a0bf528SMauro Carvalho Chehab 	/*
55409a0bf528SMauro Carvalho Chehab 	 * STEP 3: enable the system in a mode where the ADC provides valid
55419a0bf528SMauro Carvalho Chehab 	 * signal setup modulation independent registers
55429a0bf528SMauro Carvalho Chehab 	 */
55439a0bf528SMauro Carvalho Chehab #if 0
5544cd7a67a4SMauro Carvalho Chehab 	status = set_frequency(channel, tuner_freq_offset));
55459a0bf528SMauro Carvalho Chehab 	if (status < 0)
55469a0bf528SMauro Carvalho Chehab 		goto error;
55479a0bf528SMauro Carvalho Chehab #endif
5548ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
5549ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
55509a0bf528SMauro Carvalho Chehab 	if (status < 0)
55519a0bf528SMauro Carvalho Chehab 		goto error;
55529a0bf528SMauro Carvalho Chehab 
55539a0bf528SMauro Carvalho Chehab 	/* Setup BER measurement */
5554ab5060cdSMauro Carvalho Chehab 	status = set_qam_measurement(state, state->m_constellation,
5555ab5060cdSMauro Carvalho Chehab 				     state->props.symbol_rate);
55569a0bf528SMauro Carvalho Chehab 	if (status < 0)
55579a0bf528SMauro Carvalho Chehab 		goto error;
55589a0bf528SMauro Carvalho Chehab 
55599a0bf528SMauro Carvalho Chehab 	/* Reset default values */
55609a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55619a0bf528SMauro Carvalho Chehab 	if (status < 0)
55629a0bf528SMauro Carvalho Chehab 		goto error;
55639a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55649a0bf528SMauro Carvalho Chehab 	if (status < 0)
55659a0bf528SMauro Carvalho Chehab 		goto error;
55669a0bf528SMauro Carvalho Chehab 
55679a0bf528SMauro Carvalho Chehab 	/* Reset default LC values */
55689a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55699a0bf528SMauro Carvalho Chehab 	if (status < 0)
55709a0bf528SMauro Carvalho Chehab 		goto error;
55719a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55729a0bf528SMauro Carvalho Chehab 	if (status < 0)
55739a0bf528SMauro Carvalho Chehab 		goto error;
55749a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
55759a0bf528SMauro Carvalho Chehab 	if (status < 0)
55769a0bf528SMauro Carvalho Chehab 		goto error;
55779a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_MODE__A, 7);
55789a0bf528SMauro Carvalho Chehab 	if (status < 0)
55799a0bf528SMauro Carvalho Chehab 		goto error;
55809a0bf528SMauro Carvalho Chehab 
55819a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
55829a0bf528SMauro Carvalho Chehab 	if (status < 0)
55839a0bf528SMauro Carvalho Chehab 		goto error;
55849a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
55859a0bf528SMauro Carvalho Chehab 	if (status < 0)
55869a0bf528SMauro Carvalho Chehab 		goto error;
55879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
55889a0bf528SMauro Carvalho Chehab 	if (status < 0)
55899a0bf528SMauro Carvalho Chehab 		goto error;
55909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
55919a0bf528SMauro Carvalho Chehab 	if (status < 0)
55929a0bf528SMauro Carvalho Chehab 		goto error;
55939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
55949a0bf528SMauro Carvalho Chehab 	if (status < 0)
55959a0bf528SMauro Carvalho Chehab 		goto error;
55969a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
55979a0bf528SMauro Carvalho Chehab 	if (status < 0)
55989a0bf528SMauro Carvalho Chehab 		goto error;
55999a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
56009a0bf528SMauro Carvalho Chehab 	if (status < 0)
56019a0bf528SMauro Carvalho Chehab 		goto error;
56029a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
56039a0bf528SMauro Carvalho Chehab 	if (status < 0)
56049a0bf528SMauro Carvalho Chehab 		goto error;
56059a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
56069a0bf528SMauro Carvalho Chehab 	if (status < 0)
56079a0bf528SMauro Carvalho Chehab 		goto error;
56089a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
56099a0bf528SMauro Carvalho Chehab 	if (status < 0)
56109a0bf528SMauro Carvalho Chehab 		goto error;
56119a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
56129a0bf528SMauro Carvalho Chehab 	if (status < 0)
56139a0bf528SMauro Carvalho Chehab 		goto error;
56149a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
56159a0bf528SMauro Carvalho Chehab 	if (status < 0)
56169a0bf528SMauro Carvalho Chehab 		goto error;
56179a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
56189a0bf528SMauro Carvalho Chehab 	if (status < 0)
56199a0bf528SMauro Carvalho Chehab 		goto error;
56209a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
56219a0bf528SMauro Carvalho Chehab 	if (status < 0)
56229a0bf528SMauro Carvalho Chehab 		goto error;
56239a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
56249a0bf528SMauro Carvalho Chehab 	if (status < 0)
56259a0bf528SMauro Carvalho Chehab 		goto error;
56269a0bf528SMauro Carvalho Chehab 
56279a0bf528SMauro Carvalho Chehab 	/* Mirroring, QAM-block starting point not inverted */
5628ab5060cdSMauro Carvalho Chehab 	status = write16(state, QAM_SY_SP_INV__A,
5629ab5060cdSMauro Carvalho Chehab 			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
56309a0bf528SMauro Carvalho Chehab 	if (status < 0)
56319a0bf528SMauro Carvalho Chehab 		goto error;
56329a0bf528SMauro Carvalho Chehab 
56339a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
56349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
56359a0bf528SMauro Carvalho Chehab 	if (status < 0)
56369a0bf528SMauro Carvalho Chehab 		goto error;
56379a0bf528SMauro Carvalho Chehab 
56389a0bf528SMauro Carvalho Chehab 	/* STEP 4: modulation specific setup */
56399a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
56409a0bf528SMauro Carvalho Chehab 	case QAM_16:
5641cd7a67a4SMauro Carvalho Chehab 		status = set_qam16(state);
56429a0bf528SMauro Carvalho Chehab 		break;
56439a0bf528SMauro Carvalho Chehab 	case QAM_32:
5644cd7a67a4SMauro Carvalho Chehab 		status = set_qam32(state);
56459a0bf528SMauro Carvalho Chehab 		break;
56469a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
56479a0bf528SMauro Carvalho Chehab 	case QAM_64:
5648cd7a67a4SMauro Carvalho Chehab 		status = set_qam64(state);
56499a0bf528SMauro Carvalho Chehab 		break;
56509a0bf528SMauro Carvalho Chehab 	case QAM_128:
5651cd7a67a4SMauro Carvalho Chehab 		status = set_qam128(state);
56529a0bf528SMauro Carvalho Chehab 		break;
56539a0bf528SMauro Carvalho Chehab 	case QAM_256:
5654cd7a67a4SMauro Carvalho Chehab 		status = set_qam256(state);
56559a0bf528SMauro Carvalho Chehab 		break;
56569a0bf528SMauro Carvalho Chehab 	default:
56579a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
56589a0bf528SMauro Carvalho Chehab 		break;
56599a0bf528SMauro Carvalho Chehab 	}
56609a0bf528SMauro Carvalho Chehab 	if (status < 0)
56619a0bf528SMauro Carvalho Chehab 		goto error;
56629a0bf528SMauro Carvalho Chehab 
56639a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
56649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56659a0bf528SMauro Carvalho Chehab 	if (status < 0)
56669a0bf528SMauro Carvalho Chehab 		goto error;
56679a0bf528SMauro Carvalho Chehab 
56689a0bf528SMauro Carvalho Chehab 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
56699a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.modulation = channel->modulation; */
56709a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
5671cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, state->m_operation_mode);
56729a0bf528SMauro Carvalho Chehab 	if (status < 0)
56739a0bf528SMauro Carvalho Chehab 		goto error;
56749a0bf528SMauro Carvalho Chehab 
5675cd7a67a4SMauro Carvalho Chehab 	/* start processes */
5676cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
56779a0bf528SMauro Carvalho Chehab 	if (status < 0)
56789a0bf528SMauro Carvalho Chehab 		goto error;
56799a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
56809a0bf528SMauro Carvalho Chehab 	if (status < 0)
56819a0bf528SMauro Carvalho Chehab 		goto error;
56829a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
56839a0bf528SMauro Carvalho Chehab 	if (status < 0)
56849a0bf528SMauro Carvalho Chehab 		goto error;
56859a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
56869a0bf528SMauro Carvalho Chehab 	if (status < 0)
56879a0bf528SMauro Carvalho Chehab 		goto error;
56889a0bf528SMauro Carvalho Chehab 
56899a0bf528SMauro Carvalho Chehab 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5690ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5691ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
5692ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
56939a0bf528SMauro Carvalho Chehab 	if (status < 0)
56949a0bf528SMauro Carvalho Chehab 		goto error;
56959a0bf528SMauro Carvalho Chehab 
56969a0bf528SMauro Carvalho Chehab 	/* update global DRXK data container */
56979a0bf528SMauro Carvalho Chehab /*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
56989a0bf528SMauro Carvalho Chehab 
56999a0bf528SMauro Carvalho Chehab error:
57009a0bf528SMauro Carvalho Chehab 	if (status < 0)
57013a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
57029a0bf528SMauro Carvalho Chehab 	return status;
57039a0bf528SMauro Carvalho Chehab }
57049a0bf528SMauro Carvalho Chehab 
5705cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
5706cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
57079a0bf528SMauro Carvalho Chehab {
57089a0bf528SMauro Carvalho Chehab 	int status;
57099a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
57109a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
57119a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
57129a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
57139a0bf528SMauro Carvalho Chehab #endif
57149a0bf528SMauro Carvalho Chehab 
57159a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
57169a0bf528SMauro Carvalho Chehab 
57179a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
5718cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_qam(state);
57199a0bf528SMauro Carvalho Chehab 
57209a0bf528SMauro Carvalho Chehab 	/* Ensure correct power-up mode */
5721cd7a67a4SMauro Carvalho Chehab 	status = power_up_qam(state);
57229a0bf528SMauro Carvalho Chehab 	if (status < 0)
57239a0bf528SMauro Carvalho Chehab 		goto error;
57249a0bf528SMauro Carvalho Chehab 	/* Reset QAM block */
5725cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
57269a0bf528SMauro Carvalho Chehab 	if (status < 0)
57279a0bf528SMauro Carvalho Chehab 		goto error;
57289a0bf528SMauro Carvalho Chehab 
57299a0bf528SMauro Carvalho Chehab 	/* Setup IQM */
57309a0bf528SMauro Carvalho Chehab 
57319a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
57329a0bf528SMauro Carvalho Chehab 	if (status < 0)
57339a0bf528SMauro Carvalho Chehab 		goto error;
57349a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
57359a0bf528SMauro Carvalho Chehab 	if (status < 0)
57369a0bf528SMauro Carvalho Chehab 		goto error;
57379a0bf528SMauro Carvalho Chehab 
57389a0bf528SMauro Carvalho Chehab 	/* Upload IQM Channel Filter settings by
57399a0bf528SMauro Carvalho Chehab 		boot loader from ROM table */
5740cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
57419a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
5742ab5060cdSMauro Carvalho Chehab 		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5743ab5060cdSMauro Carvalho Chehab 				      DRXK_BLCC_NR_ELEMENTS_TAPS,
5744ab5060cdSMauro Carvalho Chehab 			DRXK_BLC_TIMEOUT);
57459a0bf528SMauro Carvalho Chehab 		break;
57469a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
5747ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5748ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5749ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5750ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57519a0bf528SMauro Carvalho Chehab 		if (status < 0)
57529a0bf528SMauro Carvalho Chehab 			goto error;
5753ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state,
5754ab5060cdSMauro Carvalho Chehab 				       IQM_CF_TAP_IM0__A,
5755ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5756ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5757ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57589a0bf528SMauro Carvalho Chehab 		break;
57599a0bf528SMauro Carvalho Chehab 	default:
57609a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
57619a0bf528SMauro Carvalho Chehab 	}
57629a0bf528SMauro Carvalho Chehab 	if (status < 0)
57639a0bf528SMauro Carvalho Chehab 		goto error;
57649a0bf528SMauro Carvalho Chehab 
5765ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
57669a0bf528SMauro Carvalho Chehab 	if (status < 0)
57679a0bf528SMauro Carvalho Chehab 		goto error;
57689a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57699a0bf528SMauro Carvalho Chehab 	if (status < 0)
57709a0bf528SMauro Carvalho Chehab 		goto error;
5771ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_MIDTAP__A,
5772ab5060cdSMauro Carvalho Chehab 		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57739a0bf528SMauro Carvalho Chehab 	if (status < 0)
57749a0bf528SMauro Carvalho Chehab 		goto error;
57759a0bf528SMauro Carvalho Chehab 
57769a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 21);
57779a0bf528SMauro Carvalho Chehab 	if (status < 0)
57789a0bf528SMauro Carvalho Chehab 		goto error;
57799a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
57809a0bf528SMauro Carvalho Chehab 	if (status < 0)
57819a0bf528SMauro Carvalho Chehab 		goto error;
57829a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
57839a0bf528SMauro Carvalho Chehab 	if (status < 0)
57849a0bf528SMauro Carvalho Chehab 		goto error;
57859a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
57869a0bf528SMauro Carvalho Chehab 	if (status < 0)
57879a0bf528SMauro Carvalho Chehab 		goto error;
57889a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
57899a0bf528SMauro Carvalho Chehab 	if (status < 0)
57909a0bf528SMauro Carvalho Chehab 		goto error;
57919a0bf528SMauro Carvalho Chehab 
57929a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FS_ADJ_SEL__A, 1);
57939a0bf528SMauro Carvalho Chehab 	if (status < 0)
57949a0bf528SMauro Carvalho Chehab 		goto error;
57959a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_ADJ_SEL__A, 1);
57969a0bf528SMauro Carvalho Chehab 	if (status < 0)
57979a0bf528SMauro Carvalho Chehab 		goto error;
57989a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_ADJ_SEL__A, 1);
57999a0bf528SMauro Carvalho Chehab 	if (status < 0)
58009a0bf528SMauro Carvalho Chehab 		goto error;
58019a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 0);
58029a0bf528SMauro Carvalho Chehab 	if (status < 0)
58039a0bf528SMauro Carvalho Chehab 		goto error;
58049a0bf528SMauro Carvalho Chehab 
58059a0bf528SMauro Carvalho Chehab 	/* IQM Impulse Noise Processing Unit */
58069a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_CLP_VAL__A, 500);
58079a0bf528SMauro Carvalho Chehab 	if (status < 0)
58089a0bf528SMauro Carvalho Chehab 		goto error;
58099a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 1000);
58109a0bf528SMauro Carvalho Chehab 	if (status < 0)
58119a0bf528SMauro Carvalho Chehab 		goto error;
58129a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_BYPASSDET__A, 1);
58139a0bf528SMauro Carvalho Chehab 	if (status < 0)
58149a0bf528SMauro Carvalho Chehab 		goto error;
58159a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);
58169a0bf528SMauro Carvalho Chehab 	if (status < 0)
58179a0bf528SMauro Carvalho Chehab 		goto error;
58189a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 1);
58199a0bf528SMauro Carvalho Chehab 	if (status < 0)
58209a0bf528SMauro Carvalho Chehab 		goto error;
58219a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 1);
58229a0bf528SMauro Carvalho Chehab 	if (status < 0)
58239a0bf528SMauro Carvalho Chehab 		goto error;
58249a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_BYPASS__A, 1);
58259a0bf528SMauro Carvalho Chehab 	if (status < 0)
58269a0bf528SMauro Carvalho Chehab 		goto error;
58279a0bf528SMauro Carvalho Chehab 
58289a0bf528SMauro Carvalho Chehab 	/* turn on IQMAF. Must be done before setAgc**() */
5829cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
58309a0bf528SMauro Carvalho Chehab 	if (status < 0)
58319a0bf528SMauro Carvalho Chehab 		goto error;
58329a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
58339a0bf528SMauro Carvalho Chehab 	if (status < 0)
58349a0bf528SMauro Carvalho Chehab 		goto error;
58359a0bf528SMauro Carvalho Chehab 
58369a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
5837cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
58389a0bf528SMauro Carvalho Chehab 	if (status < 0)
58399a0bf528SMauro Carvalho Chehab 		goto error;
58409a0bf528SMauro Carvalho Chehab 
58419a0bf528SMauro Carvalho Chehab 	/* Set the FSM step period */
58429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
58439a0bf528SMauro Carvalho Chehab 	if (status < 0)
58449a0bf528SMauro Carvalho Chehab 		goto error;
58459a0bf528SMauro Carvalho Chehab 
58469a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
58479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
58489a0bf528SMauro Carvalho Chehab 	if (status < 0)
58499a0bf528SMauro Carvalho Chehab 		goto error;
58509a0bf528SMauro Carvalho Chehab 
58519a0bf528SMauro Carvalho Chehab 	/* No more resets of the IQM, current standard correctly set =>
58529a0bf528SMauro Carvalho Chehab 		now AGCs can be configured. */
58539a0bf528SMauro Carvalho Chehab 
5854cd7a67a4SMauro Carvalho Chehab 	status = init_agc(state, true);
58559a0bf528SMauro Carvalho Chehab 	if (status < 0)
58569a0bf528SMauro Carvalho Chehab 		goto error;
5857cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
58589a0bf528SMauro Carvalho Chehab 	if (status < 0)
58599a0bf528SMauro Carvalho Chehab 		goto error;
58609a0bf528SMauro Carvalho Chehab 
58619a0bf528SMauro Carvalho Chehab 	/* Configure AGC's */
5862cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
58639a0bf528SMauro Carvalho Chehab 	if (status < 0)
58649a0bf528SMauro Carvalho Chehab 		goto error;
5865cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
58669a0bf528SMauro Carvalho Chehab 	if (status < 0)
58679a0bf528SMauro Carvalho Chehab 		goto error;
58689a0bf528SMauro Carvalho Chehab 
58699a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
58709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58719a0bf528SMauro Carvalho Chehab error:
58729a0bf528SMauro Carvalho Chehab 	if (status < 0)
58733a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
58749a0bf528SMauro Carvalho Chehab 	return status;
58759a0bf528SMauro Carvalho Chehab }
58769a0bf528SMauro Carvalho Chehab 
5877cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state)
58789a0bf528SMauro Carvalho Chehab {
58799a0bf528SMauro Carvalho Chehab 	int status;
58809a0bf528SMauro Carvalho Chehab 	u16 value = 0;
58819a0bf528SMauro Carvalho Chehab 
58829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
58839a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
5884ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
5885ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58869a0bf528SMauro Carvalho Chehab 	if (status < 0)
58879a0bf528SMauro Carvalho Chehab 		goto error;
58889a0bf528SMauro Carvalho Chehab 
58899a0bf528SMauro Carvalho Chehab 	/*  Write magic word to enable pdr reg write               */
58909a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
58919a0bf528SMauro Carvalho Chehab 	if (status < 0)
58929a0bf528SMauro Carvalho Chehab 		goto error;
58939a0bf528SMauro Carvalho Chehab 
5894cd7a67a4SMauro Carvalho Chehab 	if (state->m_has_sawsw) {
5895cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0001) { /* UIO-1 */
58969a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5897ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5898ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58999a0bf528SMauro Carvalho Chehab 			if (status < 0)
59009a0bf528SMauro Carvalho Chehab 				goto error;
59019a0bf528SMauro Carvalho Chehab 
59029a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59039a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59049a0bf528SMauro Carvalho Chehab 			if (status < 0)
59059a0bf528SMauro Carvalho Chehab 				goto error;
5906cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0001) == 0)
59079a0bf528SMauro Carvalho Chehab 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
59089a0bf528SMauro Carvalho Chehab 			else
59099a0bf528SMauro Carvalho Chehab 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
59109a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59119a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59129a0bf528SMauro Carvalho Chehab 			if (status < 0)
59139a0bf528SMauro Carvalho Chehab 				goto error;
59149a0bf528SMauro Carvalho Chehab 		}
5915cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0002) { /* UIO-2 */
59169a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5917ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5918ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59199a0bf528SMauro Carvalho Chehab 			if (status < 0)
59209a0bf528SMauro Carvalho Chehab 				goto error;
59219a0bf528SMauro Carvalho Chehab 
59229a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59239a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59249a0bf528SMauro Carvalho Chehab 			if (status < 0)
59259a0bf528SMauro Carvalho Chehab 				goto error;
5926cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0002) == 0)
59279a0bf528SMauro Carvalho Chehab 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
59289a0bf528SMauro Carvalho Chehab 			else
59299a0bf528SMauro Carvalho Chehab 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
59309a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59319a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59329a0bf528SMauro Carvalho Chehab 			if (status < 0)
59339a0bf528SMauro Carvalho Chehab 				goto error;
59349a0bf528SMauro Carvalho Chehab 		}
5935cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0004) { /* UIO-3 */
59369a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5937ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_GPIO_CFG__A,
5938ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59399a0bf528SMauro Carvalho Chehab 			if (status < 0)
59409a0bf528SMauro Carvalho Chehab 				goto error;
59419a0bf528SMauro Carvalho Chehab 
59429a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59439a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59449a0bf528SMauro Carvalho Chehab 			if (status < 0)
59459a0bf528SMauro Carvalho Chehab 				goto error;
5946cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0004) == 0)
59479a0bf528SMauro Carvalho Chehab 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
59489a0bf528SMauro Carvalho Chehab 			else
59499a0bf528SMauro Carvalho Chehab 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
59509a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59519a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59529a0bf528SMauro Carvalho Chehab 			if (status < 0)
59539a0bf528SMauro Carvalho Chehab 				goto error;
59549a0bf528SMauro Carvalho Chehab 		}
59559a0bf528SMauro Carvalho Chehab 	}
59569a0bf528SMauro Carvalho Chehab 	/*  Write magic word to disable pdr reg write               */
59579a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59589a0bf528SMauro Carvalho Chehab error:
59599a0bf528SMauro Carvalho Chehab 	if (status < 0)
59603a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59619a0bf528SMauro Carvalho Chehab 	return status;
59629a0bf528SMauro Carvalho Chehab }
59639a0bf528SMauro Carvalho Chehab 
5964cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state)
59659a0bf528SMauro Carvalho Chehab {
59669a0bf528SMauro Carvalho Chehab 	int status = 0;
59679a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59689a0bf528SMauro Carvalho Chehab 
59699a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59709a0bf528SMauro Carvalho Chehab 
59719a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59729a0bf528SMauro Carvalho Chehab 		return 0;
59739a0bf528SMauro Carvalho Chehab 
5974cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59759a0bf528SMauro Carvalho Chehab 
59769a0bf528SMauro Carvalho Chehab 	if (state->antenna_dvbt ^ gpio_state) {
59779a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-T mode. Switch */
59789a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5979cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
59809a0bf528SMauro Carvalho Chehab 		else
5981cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
5982cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59839a0bf528SMauro Carvalho Chehab 	}
59849a0bf528SMauro Carvalho Chehab 	if (status < 0)
59853a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59869a0bf528SMauro Carvalho Chehab 	return status;
59879a0bf528SMauro Carvalho Chehab }
59889a0bf528SMauro Carvalho Chehab 
5989cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state)
59909a0bf528SMauro Carvalho Chehab {
59919a0bf528SMauro Carvalho Chehab 	int status = 0;
59929a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59939a0bf528SMauro Carvalho Chehab 
59949a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59959a0bf528SMauro Carvalho Chehab 
59969a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59979a0bf528SMauro Carvalho Chehab 		return 0;
59989a0bf528SMauro Carvalho Chehab 
5999cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
60009a0bf528SMauro Carvalho Chehab 
60019a0bf528SMauro Carvalho Chehab 	if (!(state->antenna_dvbt ^ gpio_state)) {
60029a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-C mode. Switch */
60039a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
6004cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
60059a0bf528SMauro Carvalho Chehab 		else
6006cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
6007cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
60089a0bf528SMauro Carvalho Chehab 	}
60099a0bf528SMauro Carvalho Chehab 	if (status < 0)
60103a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
60119a0bf528SMauro Carvalho Chehab 	return status;
60129a0bf528SMauro Carvalho Chehab }
60139a0bf528SMauro Carvalho Chehab 
60149a0bf528SMauro Carvalho Chehab 
6015cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state)
60169a0bf528SMauro Carvalho Chehab {
60179a0bf528SMauro Carvalho Chehab 	/* Power down to requested mode */
60189a0bf528SMauro Carvalho Chehab 	/* Backup some register settings */
60199a0bf528SMauro Carvalho Chehab 	/* Set pins with possible pull-ups connected to them in input mode */
60209a0bf528SMauro Carvalho Chehab 	/* Analog power down */
60219a0bf528SMauro Carvalho Chehab 	/* ADC power down */
60229a0bf528SMauro Carvalho Chehab 	/* Power down device */
60239a0bf528SMauro Carvalho Chehab 	int status;
60249a0bf528SMauro Carvalho Chehab 
60259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6026cd7a67a4SMauro Carvalho Chehab 	if (state->m_b_p_down_open_bridge) {
60279a0bf528SMauro Carvalho Chehab 		/* Open I2C bridge before power down of DRXK */
60289a0bf528SMauro Carvalho Chehab 		status = ConfigureI2CBridge(state, true);
60299a0bf528SMauro Carvalho Chehab 		if (status < 0)
60309a0bf528SMauro Carvalho Chehab 			goto error;
60319a0bf528SMauro Carvalho Chehab 	}
60329a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
6033cd7a67a4SMauro Carvalho Chehab 	status = dvbt_enable_ofdm_token_ring(state, false);
60349a0bf528SMauro Carvalho Chehab 	if (status < 0)
60359a0bf528SMauro Carvalho Chehab 		goto error;
60369a0bf528SMauro Carvalho Chehab 
6037ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A,
6038ab5060cdSMauro Carvalho Chehab 			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
60399a0bf528SMauro Carvalho Chehab 	if (status < 0)
60409a0bf528SMauro Carvalho Chehab 		goto error;
60419a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60429a0bf528SMauro Carvalho Chehab 	if (status < 0)
60439a0bf528SMauro Carvalho Chehab 		goto error;
6044cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6045cd7a67a4SMauro Carvalho Chehab 	status = hi_cfg_command(state);
60469a0bf528SMauro Carvalho Chehab error:
60479a0bf528SMauro Carvalho Chehab 	if (status < 0)
60483a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
60499a0bf528SMauro Carvalho Chehab 
60509a0bf528SMauro Carvalho Chehab 	return status;
60519a0bf528SMauro Carvalho Chehab }
60529a0bf528SMauro Carvalho Chehab 
60539a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60549a0bf528SMauro Carvalho Chehab {
60559a0bf528SMauro Carvalho Chehab 	int status = 0, n = 0;
6056cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6057cd7a67a4SMauro Carvalho Chehab 	u16 driver_version;
60589a0bf528SMauro Carvalho Chehab 
60599a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6060cd7a67a4SMauro Carvalho Chehab 	if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
60619a0bf528SMauro Carvalho Chehab 		drxk_i2c_lock(state);
6062cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
60639a0bf528SMauro Carvalho Chehab 		if (status < 0)
60649a0bf528SMauro Carvalho Chehab 			goto error;
6065cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
60669a0bf528SMauro Carvalho Chehab 		if (status < 0)
60679a0bf528SMauro Carvalho Chehab 			goto error;
60689a0bf528SMauro Carvalho Chehab 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
6069ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_CC_SOFT_RST__A,
6070ab5060cdSMauro Carvalho Chehab 				 SIO_CC_SOFT_RST_OFDM__M
6071ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_SYS__M
6072ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_OSC__M);
60739a0bf528SMauro Carvalho Chehab 		if (status < 0)
60749a0bf528SMauro Carvalho Chehab 			goto error;
60759a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60769a0bf528SMauro Carvalho Chehab 		if (status < 0)
60779a0bf528SMauro Carvalho Chehab 			goto error;
6078ab5060cdSMauro Carvalho Chehab 		/*
6079ab5060cdSMauro Carvalho Chehab 		 * TODO is this needed? If yes, how much delay in
6080ab5060cdSMauro Carvalho Chehab 		 * worst case scenario
6081ab5060cdSMauro Carvalho Chehab 		 */
6082b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
6083cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_a3_patch_code = true;
6084cd7a67a4SMauro Carvalho Chehab 		status = get_device_capabilities(state);
60859a0bf528SMauro Carvalho Chehab 		if (status < 0)
60869a0bf528SMauro Carvalho Chehab 			goto error;
60879a0bf528SMauro Carvalho Chehab 
60889a0bf528SMauro Carvalho Chehab 		/* Bridge delay, uses oscilator clock */
60899a0bf528SMauro Carvalho Chehab 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60909a0bf528SMauro Carvalho Chehab 		/* SDA brdige delay */
6091cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay =
6092cd7a67a4SMauro Carvalho Chehab 			(u16) ((state->m_osc_clock_freq / 1000) *
60939a0bf528SMauro Carvalho Chehab 				HI_I2C_BRIDGE_DELAY) / 1000;
60949a0bf528SMauro Carvalho Chehab 		/* Clipping */
6095cd7a67a4SMauro Carvalho Chehab 		if (state->m_hi_cfg_bridge_delay >
60969a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6097cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay =
60989a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
60999a0bf528SMauro Carvalho Chehab 		}
61009a0bf528SMauro Carvalho Chehab 		/* SCL bridge delay, same as SDA for now */
6101cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay +=
6102cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay <<
61039a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
61049a0bf528SMauro Carvalho Chehab 
6105cd7a67a4SMauro Carvalho Chehab 		status = init_hi(state);
61069a0bf528SMauro Carvalho Chehab 		if (status < 0)
61079a0bf528SMauro Carvalho Chehab 			goto error;
61089a0bf528SMauro Carvalho Chehab 		/* disable various processes */
61099a0bf528SMauro Carvalho Chehab #if NOA1ROM
61109a0bf528SMauro Carvalho Chehab 		if (!(state->m_DRXK_A1_ROM_CODE)
61119a0bf528SMauro Carvalho Chehab 			&& !(state->m_DRXK_A2_ROM_CODE))
61129a0bf528SMauro Carvalho Chehab #endif
61139a0bf528SMauro Carvalho Chehab 		{
6114ab5060cdSMauro Carvalho Chehab 			status = write16(state, SCU_RAM_GPIO__A,
6115ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
61169a0bf528SMauro Carvalho Chehab 			if (status < 0)
61179a0bf528SMauro Carvalho Chehab 				goto error;
61189a0bf528SMauro Carvalho Chehab 		}
61199a0bf528SMauro Carvalho Chehab 
61209a0bf528SMauro Carvalho Chehab 		/* disable MPEG port */
6121cd7a67a4SMauro Carvalho Chehab 		status = mpegts_disable(state);
61229a0bf528SMauro Carvalho Chehab 		if (status < 0)
61239a0bf528SMauro Carvalho Chehab 			goto error;
61249a0bf528SMauro Carvalho Chehab 
61259a0bf528SMauro Carvalho Chehab 		/* Stop AUD and SCU */
61269a0bf528SMauro Carvalho Chehab 		status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
61279a0bf528SMauro Carvalho Chehab 		if (status < 0)
61289a0bf528SMauro Carvalho Chehab 			goto error;
61299a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
61309a0bf528SMauro Carvalho Chehab 		if (status < 0)
61319a0bf528SMauro Carvalho Chehab 			goto error;
61329a0bf528SMauro Carvalho Chehab 
61339a0bf528SMauro Carvalho Chehab 		/* enable token-ring bus through OFDM block for possible ucode upload */
6134ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6135ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
61369a0bf528SMauro Carvalho Chehab 		if (status < 0)
61379a0bf528SMauro Carvalho Chehab 			goto error;
61389a0bf528SMauro Carvalho Chehab 
61399a0bf528SMauro Carvalho Chehab 		/* include boot loader section */
6140ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_BL_COMM_EXEC__A,
6141ab5060cdSMauro Carvalho Chehab 				 SIO_BL_COMM_EXEC_ACTIVE);
61429a0bf528SMauro Carvalho Chehab 		if (status < 0)
61439a0bf528SMauro Carvalho Chehab 			goto error;
6144cd7a67a4SMauro Carvalho Chehab 		status = bl_chain_cmd(state, 0, 6, 100);
61459a0bf528SMauro Carvalho Chehab 		if (status < 0)
61469a0bf528SMauro Carvalho Chehab 			goto error;
61479a0bf528SMauro Carvalho Chehab 
61489a0bf528SMauro Carvalho Chehab 		if (state->fw) {
6149cd7a67a4SMauro Carvalho Chehab 			status = download_microcode(state, state->fw->data,
61509a0bf528SMauro Carvalho Chehab 						   state->fw->size);
61519a0bf528SMauro Carvalho Chehab 			if (status < 0)
61529a0bf528SMauro Carvalho Chehab 				goto error;
61539a0bf528SMauro Carvalho Chehab 		}
61549a0bf528SMauro Carvalho Chehab 
61559a0bf528SMauro Carvalho Chehab 		/* disable token-ring bus through OFDM block for possible ucode upload */
6156ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6157ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
61589a0bf528SMauro Carvalho Chehab 		if (status < 0)
61599a0bf528SMauro Carvalho Chehab 			goto error;
61609a0bf528SMauro Carvalho Chehab 
61619a0bf528SMauro Carvalho Chehab 		/* Run SCU for a little while to initialize microcode version numbers */
61629a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61639a0bf528SMauro Carvalho Chehab 		if (status < 0)
61649a0bf528SMauro Carvalho Chehab 			goto error;
6165cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
61669a0bf528SMauro Carvalho Chehab 		if (status < 0)
61679a0bf528SMauro Carvalho Chehab 			goto error;
61689a0bf528SMauro Carvalho Chehab 		/* added for test */
61699a0bf528SMauro Carvalho Chehab 		msleep(30);
61709a0bf528SMauro Carvalho Chehab 
6171cd7a67a4SMauro Carvalho Chehab 		power_mode = DRXK_POWER_DOWN_OFDM;
6172cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
61739a0bf528SMauro Carvalho Chehab 		if (status < 0)
61749a0bf528SMauro Carvalho Chehab 			goto error;
61759a0bf528SMauro Carvalho Chehab 
61769a0bf528SMauro Carvalho Chehab 		/* Stamp driver version number in SCU data RAM in BCD code
61779a0bf528SMauro Carvalho Chehab 			Done to enable field application engineers to retreive drxdriver version
61789a0bf528SMauro Carvalho Chehab 			via I2C from SCU RAM.
61799a0bf528SMauro Carvalho Chehab 			Not using SCU command interface for SCU register access since no
61809a0bf528SMauro Carvalho Chehab 			microcode may be present.
61819a0bf528SMauro Carvalho Chehab 			*/
6182cd7a67a4SMauro Carvalho Chehab 		driver_version =
61839a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61849a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61859a0bf528SMauro Carvalho Chehab 			((DRXK_VERSION_MAJOR % 10) << 4) +
61869a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_MINOR % 10);
6187ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6188ab5060cdSMauro Carvalho Chehab 				 driver_version);
61899a0bf528SMauro Carvalho Chehab 		if (status < 0)
61909a0bf528SMauro Carvalho Chehab 			goto error;
6191cd7a67a4SMauro Carvalho Chehab 		driver_version =
61929a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61939a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61949a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
61959a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_PATCH % 10);
6196ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6197ab5060cdSMauro Carvalho Chehab 				 driver_version);
61989a0bf528SMauro Carvalho Chehab 		if (status < 0)
61999a0bf528SMauro Carvalho Chehab 			goto error;
62009a0bf528SMauro Carvalho Chehab 
62013a4398f5SMauro Carvalho Chehab 		pr_info("DRXK driver version %d.%d.%d\n",
62029a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
62039a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_PATCH);
62049a0bf528SMauro Carvalho Chehab 
6205ab5060cdSMauro Carvalho Chehab 		/*
6206ab5060cdSMauro Carvalho Chehab 		 * Dirty fix of default values for ROM/PATCH microcode
6207ab5060cdSMauro Carvalho Chehab 		 * Dirty because this fix makes it impossible to setup
6208ab5060cdSMauro Carvalho Chehab 		 * suitable values before calling DRX_Open. This solution
6209ab5060cdSMauro Carvalho Chehab 		 * requires changes to RF AGC speed to be done via the CTRL
6210ab5060cdSMauro Carvalho Chehab 		 * function after calling DRX_Open
6211ab5060cdSMauro Carvalho Chehab 		 */
62129a0bf528SMauro Carvalho Chehab 
6213cd7a67a4SMauro Carvalho Chehab 		/* m_dvbt_rf_agc_cfg.speed = 3; */
62149a0bf528SMauro Carvalho Chehab 
62159a0bf528SMauro Carvalho Chehab 		/* Reset driver debug flags to 0 */
62169a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
62179a0bf528SMauro Carvalho Chehab 		if (status < 0)
62189a0bf528SMauro Carvalho Chehab 			goto error;
62199a0bf528SMauro Carvalho Chehab 		/* driver 0.9.0 */
62209a0bf528SMauro Carvalho Chehab 		/* Setup FEC OC:
62219a0bf528SMauro Carvalho Chehab 			NOTE: No more full FEC resets allowed afterwards!! */
62229a0bf528SMauro Carvalho Chehab 		status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
62239a0bf528SMauro Carvalho Chehab 		if (status < 0)
62249a0bf528SMauro Carvalho Chehab 			goto error;
62259a0bf528SMauro Carvalho Chehab 		/* MPEGTS functions are still the same */
6226cd7a67a4SMauro Carvalho Chehab 		status = mpegts_dto_init(state);
62279a0bf528SMauro Carvalho Chehab 		if (status < 0)
62289a0bf528SMauro Carvalho Chehab 			goto error;
6229cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
62309a0bf528SMauro Carvalho Chehab 		if (status < 0)
62319a0bf528SMauro Carvalho Chehab 			goto error;
6232cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_polarity(state);
62339a0bf528SMauro Carvalho Chehab 		if (status < 0)
62349a0bf528SMauro Carvalho Chehab 			goto error;
6235cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
62369a0bf528SMauro Carvalho Chehab 		if (status < 0)
62379a0bf528SMauro Carvalho Chehab 			goto error;
62389a0bf528SMauro Carvalho Chehab 		/* added: configure GPIO */
6239cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
62409a0bf528SMauro Carvalho Chehab 		if (status < 0)
62419a0bf528SMauro Carvalho Chehab 			goto error;
62429a0bf528SMauro Carvalho Chehab 
6243cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_STOPPED;
62449a0bf528SMauro Carvalho Chehab 
6245cd7a67a4SMauro Carvalho Chehab 		if (state->m_b_power_down) {
6246cd7a67a4SMauro Carvalho Chehab 			status = power_down_device(state);
62479a0bf528SMauro Carvalho Chehab 			if (status < 0)
62489a0bf528SMauro Carvalho Chehab 				goto error;
6249cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_POWERED_DOWN;
62509a0bf528SMauro Carvalho Chehab 		} else
6251cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_STOPPED;
62529a0bf528SMauro Carvalho Chehab 
62539a0bf528SMauro Carvalho Chehab 		/* Initialize the supported delivery systems */
62549a0bf528SMauro Carvalho Chehab 		n = 0;
6255cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbc) {
62569a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62579a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62589a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-C",
62599a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62609a0bf528SMauro Carvalho Chehab 		}
6261cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbt) {
62629a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBT;
62639a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-T",
62649a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62659a0bf528SMauro Carvalho Chehab 		}
62669a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62679a0bf528SMauro Carvalho Chehab 	}
62689a0bf528SMauro Carvalho Chehab error:
62699a0bf528SMauro Carvalho Chehab 	if (status < 0) {
6270cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_NO_DEV;
62719a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62723a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
62739a0bf528SMauro Carvalho Chehab 	}
62749a0bf528SMauro Carvalho Chehab 
62759a0bf528SMauro Carvalho Chehab 	return status;
62769a0bf528SMauro Carvalho Chehab }
62779a0bf528SMauro Carvalho Chehab 
62789a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62799a0bf528SMauro Carvalho Chehab 			     void *context)
62809a0bf528SMauro Carvalho Chehab {
62819a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = context;
62829a0bf528SMauro Carvalho Chehab 
62839a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62849a0bf528SMauro Carvalho Chehab 	if (!fw) {
62853a4398f5SMauro Carvalho Chehab 		pr_err("Could not load firmware file %s.\n",
62869a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62873a4398f5SMauro Carvalho Chehab 		pr_info("Copy %s to your hotplug directory!\n",
62889a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62899a0bf528SMauro Carvalho Chehab 		state->microcode_name = NULL;
62909a0bf528SMauro Carvalho Chehab 
62919a0bf528SMauro Carvalho Chehab 		/*
62929a0bf528SMauro Carvalho Chehab 		 * As firmware is now load asynchronous, it is not possible
62939a0bf528SMauro Carvalho Chehab 		 * anymore to fail at frontend attach. We might silently
62949a0bf528SMauro Carvalho Chehab 		 * return here, and hope that the driver won't crash.
62959a0bf528SMauro Carvalho Chehab 		 * We might also change all DVB callbacks to return -ENODEV
62969a0bf528SMauro Carvalho Chehab 		 * if the device is not initialized.
62979a0bf528SMauro Carvalho Chehab 		 * As the DRX-K devices have their own internal firmware,
62989a0bf528SMauro Carvalho Chehab 		 * let's just hope that it will match a firmware revision
62999a0bf528SMauro Carvalho Chehab 		 * compatible with this driver and proceed.
63009a0bf528SMauro Carvalho Chehab 		 */
63019a0bf528SMauro Carvalho Chehab 	}
63029a0bf528SMauro Carvalho Chehab 	state->fw = fw;
63039a0bf528SMauro Carvalho Chehab 
63049a0bf528SMauro Carvalho Chehab 	init_drxk(state);
63059a0bf528SMauro Carvalho Chehab }
63069a0bf528SMauro Carvalho Chehab 
63079a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
63089a0bf528SMauro Carvalho Chehab {
63099a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63109a0bf528SMauro Carvalho Chehab 
63119a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63129a0bf528SMauro Carvalho Chehab 	if (state->fw)
63139a0bf528SMauro Carvalho Chehab 		release_firmware(state->fw);
63149a0bf528SMauro Carvalho Chehab 
63159a0bf528SMauro Carvalho Chehab 	kfree(state);
63169a0bf528SMauro Carvalho Chehab }
63179a0bf528SMauro Carvalho Chehab 
63189a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
63199a0bf528SMauro Carvalho Chehab {
63209a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63219a0bf528SMauro Carvalho Chehab 
63229a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63239a0bf528SMauro Carvalho Chehab 
6324cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63259a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6326cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63279a0bf528SMauro Carvalho Chehab 		return 0;
63289a0bf528SMauro Carvalho Chehab 
6329cd7a67a4SMauro Carvalho Chehab 	shut_down(state);
63309a0bf528SMauro Carvalho Chehab 	return 0;
63319a0bf528SMauro Carvalho Chehab }
63329a0bf528SMauro Carvalho Chehab 
63339a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
63349a0bf528SMauro Carvalho Chehab {
63359a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63369a0bf528SMauro Carvalho Chehab 
63379a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
63389a0bf528SMauro Carvalho Chehab 
6339cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63409a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63419a0bf528SMauro Carvalho Chehab 
63429a0bf528SMauro Carvalho Chehab 	return ConfigureI2CBridge(state, enable ? true : false);
63439a0bf528SMauro Carvalho Chehab }
63449a0bf528SMauro Carvalho Chehab 
63459a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
63469a0bf528SMauro Carvalho Chehab {
63479a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
63489a0bf528SMauro Carvalho Chehab 	u32 delsys  = p->delivery_system, old_delsys;
63499a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63509a0bf528SMauro Carvalho Chehab 	u32 IF;
63519a0bf528SMauro Carvalho Chehab 
63529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63539a0bf528SMauro Carvalho Chehab 
6354cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63559a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63569a0bf528SMauro Carvalho Chehab 
6357cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63589a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
63599a0bf528SMauro Carvalho Chehab 
63609a0bf528SMauro Carvalho Chehab 	if (!fe->ops.tuner_ops.get_if_frequency) {
63613a4398f5SMauro Carvalho Chehab 		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63629a0bf528SMauro Carvalho Chehab 		return -EINVAL;
63639a0bf528SMauro Carvalho Chehab 	}
63649a0bf528SMauro Carvalho Chehab 
63659a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63669a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 1);
63679a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
63689a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
63699a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63709a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 0);
63719a0bf528SMauro Carvalho Chehab 
63729a0bf528SMauro Carvalho Chehab 	old_delsys = state->props.delivery_system;
63739a0bf528SMauro Carvalho Chehab 	state->props = *p;
63749a0bf528SMauro Carvalho Chehab 
63759a0bf528SMauro Carvalho Chehab 	if (old_delsys != delsys) {
6376cd7a67a4SMauro Carvalho Chehab 		shut_down(state);
63779a0bf528SMauro Carvalho Chehab 		switch (delsys) {
63789a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_A:
63799a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_C:
6380cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbc)
63819a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6382ab5060cdSMauro Carvalho Chehab 			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6383ab5060cdSMauro Carvalho Chehab 						true : false;
63849a0bf528SMauro Carvalho Chehab 			if (state->m_itut_annex_c)
6385cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_C);
63869a0bf528SMauro Carvalho Chehab 			else
6387cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_A);
63889a0bf528SMauro Carvalho Chehab 			break;
63899a0bf528SMauro Carvalho Chehab 		case SYS_DVBT:
6390cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbt)
63919a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6392cd7a67a4SMauro Carvalho Chehab 			setoperation_mode(state, OM_DVBT);
63939a0bf528SMauro Carvalho Chehab 			break;
63949a0bf528SMauro Carvalho Chehab 		default:
63959a0bf528SMauro Carvalho Chehab 			return -EINVAL;
63969a0bf528SMauro Carvalho Chehab 		}
63979a0bf528SMauro Carvalho Chehab 	}
63989a0bf528SMauro Carvalho Chehab 
63999a0bf528SMauro Carvalho Chehab 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
6400cd7a67a4SMauro Carvalho Chehab 	start(state, 0, IF);
64019a0bf528SMauro Carvalho Chehab 
64028f3741e0SMauro Carvalho Chehab 	/* After set_frontend, stats aren't avaliable */
64038f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
64048f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64058f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64068f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64078f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64088f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64098f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64108f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64118f3741e0SMauro Carvalho Chehab 
64129a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
64139a0bf528SMauro Carvalho Chehab 
64149a0bf528SMauro Carvalho Chehab 	return 0;
64159a0bf528SMauro Carvalho Chehab }
64169a0bf528SMauro Carvalho Chehab 
641759a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength)
641859a7a23cSMauro Carvalho Chehab {
641959a7a23cSMauro Carvalho Chehab 	int status;
6420cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc   rf_agc, if_agc;
6421cd7a67a4SMauro Carvalho Chehab 	u32          total_gain  = 0;
642259a7a23cSMauro Carvalho Chehab 	u32          atten      = 0;
6423cd7a67a4SMauro Carvalho Chehab 	u32          agc_range   = 0;
642459a7a23cSMauro Carvalho Chehab 	u16            scu_lvl  = 0;
642559a7a23cSMauro Carvalho Chehab 	u16            scu_coc  = 0;
642659a7a23cSMauro Carvalho Chehab 	/* FIXME: those are part of the tuner presets */
6427cd7a67a4SMauro Carvalho Chehab 	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
6428cd7a67a4SMauro Carvalho Chehab 	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
642959a7a23cSMauro Carvalho Chehab 
643059a7a23cSMauro Carvalho Chehab 	*strength = 0;
643159a7a23cSMauro Carvalho Chehab 
6432cd7a67a4SMauro Carvalho Chehab 	if (is_dvbt(state)) {
6433cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_dvbt_rf_agc_cfg;
6434cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_dvbt_if_agc_cfg;
6435cd7a67a4SMauro Carvalho Chehab 	} else if (is_qam(state)) {
6436cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_qam_rf_agc_cfg;
6437cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_qam_if_agc_cfg;
643859a7a23cSMauro Carvalho Chehab 	} else {
6439cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_atv_rf_agc_cfg;
6440cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_atv_if_agc_cfg;
644159a7a23cSMauro Carvalho Chehab 	}
644259a7a23cSMauro Carvalho Chehab 
6443cd7a67a4SMauro Carvalho Chehab 	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6444cd7a67a4SMauro Carvalho Chehab 		/* SCU output_level */
644559a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
644659a7a23cSMauro Carvalho Chehab 		if (status < 0)
644759a7a23cSMauro Carvalho Chehab 			return status;
644859a7a23cSMauro Carvalho Chehab 
644959a7a23cSMauro Carvalho Chehab 		/* SCU c.o.c. */
645059a7a23cSMauro Carvalho Chehab 		read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
645159a7a23cSMauro Carvalho Chehab 		if (status < 0)
645259a7a23cSMauro Carvalho Chehab 			return status;
645359a7a23cSMauro Carvalho Chehab 
645459a7a23cSMauro Carvalho Chehab 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6455cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = scu_lvl + scu_coc;
645659a7a23cSMauro Carvalho Chehab 		else
6457cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = 0xffff;
645859a7a23cSMauro Carvalho Chehab 
645959a7a23cSMauro Carvalho Chehab 		/* Take RF gain into account */
6460cd7a67a4SMauro Carvalho Chehab 		total_gain += tuner_rf_gain;
646159a7a23cSMauro Carvalho Chehab 
646259a7a23cSMauro Carvalho Chehab 		/* clip output value */
6463cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level < rf_agc.min_output_level)
6464cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.min_output_level;
6465cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level > rf_agc.max_output_level)
6466cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.max_output_level;
646759a7a23cSMauro Carvalho Chehab 
6468cd7a67a4SMauro Carvalho Chehab 		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6469cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
647059a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6471cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_rf_gain)) *
6472cd7a67a4SMauro Carvalho Chehab 				((u32)(rf_agc.output_level - rf_agc.min_output_level))
6473cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
647459a7a23cSMauro Carvalho Chehab 		}
647559a7a23cSMauro Carvalho Chehab 	}
647659a7a23cSMauro Carvalho Chehab 
6477cd7a67a4SMauro Carvalho Chehab 	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
647859a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6479cd7a67a4SMauro Carvalho Chehab 				&if_agc.output_level);
648059a7a23cSMauro Carvalho Chehab 		if (status < 0)
648159a7a23cSMauro Carvalho Chehab 			return status;
648259a7a23cSMauro Carvalho Chehab 
648359a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6484cd7a67a4SMauro Carvalho Chehab 				&if_agc.top);
648559a7a23cSMauro Carvalho Chehab 		if (status < 0)
648659a7a23cSMauro Carvalho Chehab 			return status;
648759a7a23cSMauro Carvalho Chehab 
648859a7a23cSMauro Carvalho Chehab 		/* Take IF gain into account */
6489cd7a67a4SMauro Carvalho Chehab 		total_gain += (u32) tuner_if_gain;
649059a7a23cSMauro Carvalho Chehab 
649159a7a23cSMauro Carvalho Chehab 		/* clip output value */
6492cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level < if_agc.min_output_level)
6493cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.min_output_level;
6494cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level > if_agc.max_output_level)
6495cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.max_output_level;
649659a7a23cSMauro Carvalho Chehab 
6497cd7a67a4SMauro Carvalho Chehab 		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
6498cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
649959a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6500cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_if_gain)) *
6501cd7a67a4SMauro Carvalho Chehab 				((u32)(if_agc.output_level - if_agc.min_output_level))
6502cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
650359a7a23cSMauro Carvalho Chehab 		}
650459a7a23cSMauro Carvalho Chehab 	}
650559a7a23cSMauro Carvalho Chehab 
650659a7a23cSMauro Carvalho Chehab 	/*
650759a7a23cSMauro Carvalho Chehab 	 * Convert to 0..65535 scale.
650859a7a23cSMauro Carvalho Chehab 	 * If it can't be measured (AGC is disabled), just show 100%.
650959a7a23cSMauro Carvalho Chehab 	 */
6510cd7a67a4SMauro Carvalho Chehab 	if (total_gain > 0)
6511cd7a67a4SMauro Carvalho Chehab 		*strength = (65535UL * atten / total_gain / 100);
651259a7a23cSMauro Carvalho Chehab 	else
651359a7a23cSMauro Carvalho Chehab 		*strength = 65535;
651459a7a23cSMauro Carvalho Chehab 
651559a7a23cSMauro Carvalho Chehab 	return 0;
651659a7a23cSMauro Carvalho Chehab }
651759a7a23cSMauro Carvalho Chehab 
65188f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe)
65199a0bf528SMauro Carvalho Chehab {
65208f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
65219a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
65228f3741e0SMauro Carvalho Chehab 	int status;
65239a0bf528SMauro Carvalho Chehab 	u32 stat;
65248f3741e0SMauro Carvalho Chehab 	u16 reg16;
65258f3741e0SMauro Carvalho Chehab 	u32 post_bit_count;
65268f3741e0SMauro Carvalho Chehab 	u32 post_bit_err_count;
65278f3741e0SMauro Carvalho Chehab 	u32 post_bit_error_scale;
65288f3741e0SMauro Carvalho Chehab 	u32 pre_bit_err_count;
65298f3741e0SMauro Carvalho Chehab 	u32 pre_bit_count;
65308f3741e0SMauro Carvalho Chehab 	u32 pkt_count;
65318f3741e0SMauro Carvalho Chehab 	u32 pkt_error_count;
653259a7a23cSMauro Carvalho Chehab 	s32 cnr;
65339a0bf528SMauro Carvalho Chehab 
6534cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
65359a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6536cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
65379a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
65389a0bf528SMauro Carvalho Chehab 
65398f3741e0SMauro Carvalho Chehab 	/* get status */
65408f3741e0SMauro Carvalho Chehab 	state->fe_status = 0;
6541cd7a67a4SMauro Carvalho Chehab 	get_lock_status(state, &stat);
65429a0bf528SMauro Carvalho Chehab 	if (stat == MPEG_LOCK)
65438f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x1f;
65449a0bf528SMauro Carvalho Chehab 	if (stat == FEC_LOCK)
65458f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x0f;
65469a0bf528SMauro Carvalho Chehab 	if (stat == DEMOD_LOCK)
65478f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x07;
65488f3741e0SMauro Carvalho Chehab 
654959a7a23cSMauro Carvalho Chehab 	/*
655059a7a23cSMauro Carvalho Chehab 	 * Estimate signal strength from AGC
655159a7a23cSMauro Carvalho Chehab 	 */
655259a7a23cSMauro Carvalho Chehab 	get_strength(state, &c->strength.stat[0].uvalue);
655359a7a23cSMauro Carvalho Chehab 	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
655459a7a23cSMauro Carvalho Chehab 
655559a7a23cSMauro Carvalho Chehab 
65568f3741e0SMauro Carvalho Chehab 	if (stat >= DEMOD_LOCK) {
6557cd7a67a4SMauro Carvalho Chehab 		get_signal_to_noise(state, &cnr);
65588f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].svalue = cnr * 100;
65598f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
65608f3741e0SMauro Carvalho Chehab 	} else {
65618f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65628f3741e0SMauro Carvalho Chehab 	}
65638f3741e0SMauro Carvalho Chehab 
65648f3741e0SMauro Carvalho Chehab 	if (stat < FEC_LOCK) {
65658f3741e0SMauro Carvalho Chehab 		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65668f3741e0SMauro Carvalho Chehab 		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65678f3741e0SMauro Carvalho Chehab 		c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65688f3741e0SMauro Carvalho Chehab 		c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65698f3741e0SMauro Carvalho Chehab 		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65708f3741e0SMauro Carvalho Chehab 		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65718f3741e0SMauro Carvalho Chehab 		return 0;
65728f3741e0SMauro Carvalho Chehab 	}
65738f3741e0SMauro Carvalho Chehab 
65748f3741e0SMauro Carvalho Chehab 	/* Get post BER */
65758f3741e0SMauro Carvalho Chehab 
65768f3741e0SMauro Carvalho Chehab 	/* BER measurement is valid if at least FEC lock is achieved */
65778f3741e0SMauro Carvalho Chehab 
6578ab5060cdSMauro Carvalho Chehab 	/*
6579ab5060cdSMauro Carvalho Chehab 	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6580ab5060cdSMauro Carvalho Chehab 	 * written to set nr of symbols or bits over which to measure
6581ab5060cdSMauro Carvalho Chehab 	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6582ab5060cdSMauro Carvalho Chehab 	 */
65838f3741e0SMauro Carvalho Chehab 
65848f3741e0SMauro Carvalho Chehab 	/* Read registers for post/preViterbi BER calculation */
65858f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
65868f3741e0SMauro Carvalho Chehab 	if (status < 0)
65878f3741e0SMauro Carvalho Chehab 		goto error;
65888f3741e0SMauro Carvalho Chehab 	pre_bit_err_count = reg16;
65898f3741e0SMauro Carvalho Chehab 
65908f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
65918f3741e0SMauro Carvalho Chehab 	if (status < 0)
65928f3741e0SMauro Carvalho Chehab 		goto error;
65938f3741e0SMauro Carvalho Chehab 	pre_bit_count = reg16;
65948f3741e0SMauro Carvalho Chehab 
65958f3741e0SMauro Carvalho Chehab 	/* Number of bit-errors */
65968f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
65978f3741e0SMauro Carvalho Chehab 	if (status < 0)
65988f3741e0SMauro Carvalho Chehab 		goto error;
65998f3741e0SMauro Carvalho Chehab 	post_bit_err_count = reg16;
66008f3741e0SMauro Carvalho Chehab 
66018f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
66028f3741e0SMauro Carvalho Chehab 	if (status < 0)
66038f3741e0SMauro Carvalho Chehab 		goto error;
66048f3741e0SMauro Carvalho Chehab 	post_bit_error_scale = reg16;
66058f3741e0SMauro Carvalho Chehab 
66068f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
66078f3741e0SMauro Carvalho Chehab 	if (status < 0)
66088f3741e0SMauro Carvalho Chehab 		goto error;
66098f3741e0SMauro Carvalho Chehab 	pkt_count = reg16;
66108f3741e0SMauro Carvalho Chehab 
66118f3741e0SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
66128f3741e0SMauro Carvalho Chehab 	if (status < 0)
66138f3741e0SMauro Carvalho Chehab 		goto error;
66148f3741e0SMauro Carvalho Chehab 	pkt_error_count = reg16;
66158f3741e0SMauro Carvalho Chehab 	write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
66168f3741e0SMauro Carvalho Chehab 
66178f3741e0SMauro Carvalho Chehab 	post_bit_err_count *= post_bit_error_scale;
66188f3741e0SMauro Carvalho Chehab 
66198f3741e0SMauro Carvalho Chehab 	post_bit_count = pkt_count * 204 * 8;
66208f3741e0SMauro Carvalho Chehab 
66218f3741e0SMauro Carvalho Chehab 	/* Store the results */
66228f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
66238f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].uvalue += pkt_error_count;
66248f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].scale = FE_SCALE_COUNTER;
66258f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].uvalue += pkt_count;
66268f3741e0SMauro Carvalho Chehab 
66278f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66288f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
66298f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66308f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].uvalue += pre_bit_count;
66318f3741e0SMauro Carvalho Chehab 
66328f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66338f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].uvalue += post_bit_err_count;
66348f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66358f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].uvalue += post_bit_count;
66368f3741e0SMauro Carvalho Chehab 
66378f3741e0SMauro Carvalho Chehab error:
66388f3741e0SMauro Carvalho Chehab 	return status;
66398f3741e0SMauro Carvalho Chehab }
66408f3741e0SMauro Carvalho Chehab 
66418f3741e0SMauro Carvalho Chehab 
66428f3741e0SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
66438f3741e0SMauro Carvalho Chehab {
66448f3741e0SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66458f3741e0SMauro Carvalho Chehab 	int rc;
66468f3741e0SMauro Carvalho Chehab 
66478f3741e0SMauro Carvalho Chehab 	dprintk(1, "\n");
66488f3741e0SMauro Carvalho Chehab 
66498f3741e0SMauro Carvalho Chehab 	rc = drxk_get_stats(fe);
66508f3741e0SMauro Carvalho Chehab 	if (rc < 0)
66518f3741e0SMauro Carvalho Chehab 		return rc;
66528f3741e0SMauro Carvalho Chehab 
66538f3741e0SMauro Carvalho Chehab 	*status = state->fe_status;
66548f3741e0SMauro Carvalho Chehab 
66559a0bf528SMauro Carvalho Chehab 	return 0;
66569a0bf528SMauro Carvalho Chehab }
66579a0bf528SMauro Carvalho Chehab 
66589a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
66599a0bf528SMauro Carvalho Chehab 				     u16 *strength)
66609a0bf528SMauro Carvalho Chehab {
66619a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
6662340e7696SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &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 
6671340e7696SMauro Carvalho Chehab 	*strength = c->strength.stat[0].uvalue;
66729a0bf528SMauro Carvalho Chehab 	return 0;
66739a0bf528SMauro Carvalho Chehab }
66749a0bf528SMauro Carvalho Chehab 
66759a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
66769a0bf528SMauro Carvalho Chehab {
66779a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66789a0bf528SMauro Carvalho Chehab 	s32 snr2;
66799a0bf528SMauro Carvalho Chehab 
66809a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66819a0bf528SMauro Carvalho Chehab 
6682cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66839a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6684cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66859a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66869a0bf528SMauro Carvalho Chehab 
6687cd7a67a4SMauro Carvalho Chehab 	get_signal_to_noise(state, &snr2);
66888f3741e0SMauro Carvalho Chehab 
66898f3741e0SMauro Carvalho Chehab 	/* No negative SNR, clip to zero */
66908f3741e0SMauro Carvalho Chehab 	if (snr2 < 0)
66918f3741e0SMauro Carvalho Chehab 		snr2 = 0;
66929a0bf528SMauro Carvalho Chehab 	*snr = snr2 & 0xffff;
66939a0bf528SMauro Carvalho Chehab 	return 0;
66949a0bf528SMauro Carvalho Chehab }
66959a0bf528SMauro Carvalho Chehab 
66969a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
66979a0bf528SMauro Carvalho Chehab {
66989a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66999a0bf528SMauro Carvalho Chehab 	u16 err;
67009a0bf528SMauro Carvalho Chehab 
67019a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67029a0bf528SMauro Carvalho Chehab 
6703cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
67049a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6705cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
67069a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
67079a0bf528SMauro Carvalho Chehab 
6708cd7a67a4SMauro Carvalho Chehab 	dvbtqam_get_acc_pkt_err(state, &err);
67099a0bf528SMauro Carvalho Chehab 	*ucblocks = (u32) err;
67109a0bf528SMauro Carvalho Chehab 	return 0;
67119a0bf528SMauro Carvalho Chehab }
67129a0bf528SMauro Carvalho Chehab 
6713ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe,
6714ab5060cdSMauro Carvalho Chehab 				  struct dvb_frontend_tune_settings *sets)
67159a0bf528SMauro Carvalho Chehab {
67169a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
67179a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
67189a0bf528SMauro Carvalho Chehab 
67199a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67209a0bf528SMauro Carvalho Chehab 
6721cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
67229a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6723cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
67249a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
67259a0bf528SMauro Carvalho Chehab 
67269a0bf528SMauro Carvalho Chehab 	switch (p->delivery_system) {
67279a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_A:
67289a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_C:
67299a0bf528SMauro Carvalho Chehab 	case SYS_DVBT:
67309a0bf528SMauro Carvalho Chehab 		sets->min_delay_ms = 3000;
67319a0bf528SMauro Carvalho Chehab 		sets->max_drift = 0;
67329a0bf528SMauro Carvalho Chehab 		sets->step_size = 0;
67339a0bf528SMauro Carvalho Chehab 		return 0;
67349a0bf528SMauro Carvalho Chehab 	default:
67359a0bf528SMauro Carvalho Chehab 		return -EINVAL;
67369a0bf528SMauro Carvalho Chehab 	}
67379a0bf528SMauro Carvalho Chehab }
67389a0bf528SMauro Carvalho Chehab 
67399a0bf528SMauro Carvalho Chehab static struct dvb_frontend_ops drxk_ops = {
67409a0bf528SMauro Carvalho Chehab 	/* .delsys will be filled dynamically */
67419a0bf528SMauro Carvalho Chehab 	.info = {
67429a0bf528SMauro Carvalho Chehab 		.name = "DRXK",
67439a0bf528SMauro Carvalho Chehab 		.frequency_min = 47000000,
67449a0bf528SMauro Carvalho Chehab 		.frequency_max = 865000000,
67459a0bf528SMauro Carvalho Chehab 		 /* For DVB-C */
67469a0bf528SMauro Carvalho Chehab 		.symbol_rate_min = 870000,
67479a0bf528SMauro Carvalho Chehab 		.symbol_rate_max = 11700000,
67489a0bf528SMauro Carvalho Chehab 		/* For DVB-T */
67499a0bf528SMauro Carvalho Chehab 		.frequency_stepsize = 166667,
67509a0bf528SMauro Carvalho Chehab 
67519a0bf528SMauro Carvalho Chehab 		.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
67529a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
67539a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
67549a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
67559a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
67569a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
67579a0bf528SMauro Carvalho Chehab 	},
67589a0bf528SMauro Carvalho Chehab 
67599a0bf528SMauro Carvalho Chehab 	.release = drxk_release,
67609a0bf528SMauro Carvalho Chehab 	.sleep = drxk_sleep,
67619a0bf528SMauro Carvalho Chehab 	.i2c_gate_ctrl = drxk_gate_ctrl,
67629a0bf528SMauro Carvalho Chehab 
67639a0bf528SMauro Carvalho Chehab 	.set_frontend = drxk_set_parameters,
67649a0bf528SMauro Carvalho Chehab 	.get_tune_settings = drxk_get_tune_settings,
67659a0bf528SMauro Carvalho Chehab 
67669a0bf528SMauro Carvalho Chehab 	.read_status = drxk_read_status,
67679a0bf528SMauro Carvalho Chehab 	.read_signal_strength = drxk_read_signal_strength,
67689a0bf528SMauro Carvalho Chehab 	.read_snr = drxk_read_snr,
67699a0bf528SMauro Carvalho Chehab 	.read_ucblocks = drxk_read_ucblocks,
67709a0bf528SMauro Carvalho Chehab };
67719a0bf528SMauro Carvalho Chehab 
67729a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
67739a0bf528SMauro Carvalho Chehab 				 struct i2c_adapter *i2c)
67749a0bf528SMauro Carvalho Chehab {
67758f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *p;
67769a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = NULL;
67779a0bf528SMauro Carvalho Chehab 	u8 adr = config->adr;
67789a0bf528SMauro Carvalho Chehab 	int status;
67799a0bf528SMauro Carvalho Chehab 
67809a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67819a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
67829a0bf528SMauro Carvalho Chehab 	if (!state)
67839a0bf528SMauro Carvalho Chehab 		return NULL;
67849a0bf528SMauro Carvalho Chehab 
67859a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
67869a0bf528SMauro Carvalho Chehab 	state->demod_address = adr;
67879a0bf528SMauro Carvalho Chehab 	state->single_master = config->single_master;
67889a0bf528SMauro Carvalho Chehab 	state->microcode_name = config->microcode_name;
67899a0bf528SMauro Carvalho Chehab 	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
67909a0bf528SMauro Carvalho Chehab 	state->no_i2c_bridge = config->no_i2c_bridge;
67919a0bf528SMauro Carvalho Chehab 	state->antenna_gpio = config->antenna_gpio;
67929a0bf528SMauro Carvalho Chehab 	state->antenna_dvbt = config->antenna_dvbt;
6793cd7a67a4SMauro Carvalho Chehab 	state->m_chunk_size = config->chunk_size;
67949a0bf528SMauro Carvalho Chehab 	state->enable_merr_cfg = config->enable_merr_cfg;
67959a0bf528SMauro Carvalho Chehab 
67969a0bf528SMauro Carvalho Chehab 	if (config->dynamic_clk) {
6797cd7a67a4SMauro Carvalho Chehab 		state->m_dvbt_static_clk = 0;
6798cd7a67a4SMauro Carvalho Chehab 		state->m_dvbc_static_clk = 0;
67999a0bf528SMauro Carvalho Chehab 	} else {
6800cd7a67a4SMauro Carvalho Chehab 		state->m_dvbt_static_clk = 1;
6801cd7a67a4SMauro Carvalho Chehab 		state->m_dvbc_static_clk = 1;
68029a0bf528SMauro Carvalho Chehab 	}
68039a0bf528SMauro Carvalho Chehab 
68049a0bf528SMauro Carvalho Chehab 
68059a0bf528SMauro Carvalho Chehab 	if (config->mpeg_out_clk_strength)
6806cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
68079a0bf528SMauro Carvalho Chehab 	else
6808cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = 0x06;
68099a0bf528SMauro Carvalho Chehab 
68109a0bf528SMauro Carvalho Chehab 	if (config->parallel_ts)
6811cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = true;
68129a0bf528SMauro Carvalho Chehab 	else
6813cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = false;
68149a0bf528SMauro Carvalho Chehab 
68159a0bf528SMauro Carvalho Chehab 	/* NOTE: as more UIO bits will be used, add them to the mask */
6816cd7a67a4SMauro Carvalho Chehab 	state->uio_mask = config->antenna_gpio;
68179a0bf528SMauro Carvalho Chehab 
68189a0bf528SMauro Carvalho Chehab 	/* Default gpio to DVB-C */
68199a0bf528SMauro Carvalho Chehab 	if (!state->antenna_dvbt && state->antenna_gpio)
6820cd7a67a4SMauro Carvalho Chehab 		state->m_gpio |= state->antenna_gpio;
68219a0bf528SMauro Carvalho Chehab 	else
6822cd7a67a4SMauro Carvalho Chehab 		state->m_gpio &= ~state->antenna_gpio;
68239a0bf528SMauro Carvalho Chehab 
68249a0bf528SMauro Carvalho Chehab 	mutex_init(&state->mutex);
68259a0bf528SMauro Carvalho Chehab 
68269a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
68279a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
68289a0bf528SMauro Carvalho Chehab 
68299a0bf528SMauro Carvalho Chehab 	init_state(state);
68309a0bf528SMauro Carvalho Chehab 
68319a0bf528SMauro Carvalho Chehab 	/* Load firmware and initialize DRX-K */
68329a0bf528SMauro Carvalho Chehab 	if (state->microcode_name) {
68338e30783bSMauro Carvalho Chehab 		if (config->load_firmware_sync) {
68348e30783bSMauro Carvalho Chehab 			const struct firmware *fw = NULL;
68358e30783bSMauro Carvalho Chehab 
68368e30783bSMauro Carvalho Chehab 			status = request_firmware(&fw, state->microcode_name,
68378e30783bSMauro Carvalho Chehab 						  state->i2c->dev.parent);
68388e30783bSMauro Carvalho Chehab 			if (status < 0)
68398e30783bSMauro Carvalho Chehab 				fw = NULL;
68408e30783bSMauro Carvalho Chehab 			load_firmware_cb(fw, state);
68418e30783bSMauro Carvalho Chehab 		} else {
68429a0bf528SMauro Carvalho Chehab 			status = request_firmware_nowait(THIS_MODULE, 1,
68439a0bf528SMauro Carvalho Chehab 					      state->microcode_name,
68449a0bf528SMauro Carvalho Chehab 					      state->i2c->dev.parent,
68459a0bf528SMauro Carvalho Chehab 					      GFP_KERNEL,
68469a0bf528SMauro Carvalho Chehab 					      state, load_firmware_cb);
68479a0bf528SMauro Carvalho Chehab 			if (status < 0) {
68483a4398f5SMauro Carvalho Chehab 				pr_err("failed to request a firmware\n");
68499a0bf528SMauro Carvalho Chehab 				return NULL;
68509a0bf528SMauro Carvalho Chehab 			}
68518e30783bSMauro Carvalho Chehab 		}
68529a0bf528SMauro Carvalho Chehab 	} else if (init_drxk(state) < 0)
68539a0bf528SMauro Carvalho Chehab 		goto error;
68549a0bf528SMauro Carvalho Chehab 
68558f3741e0SMauro Carvalho Chehab 
68568f3741e0SMauro Carvalho Chehab 	/* Initialize stats */
68578f3741e0SMauro Carvalho Chehab 	p = &state->frontend.dtv_property_cache;
68588f3741e0SMauro Carvalho Chehab 	p->strength.len = 1;
68598f3741e0SMauro Carvalho Chehab 	p->cnr.len = 1;
68608f3741e0SMauro Carvalho Chehab 	p->block_error.len = 1;
68618f3741e0SMauro Carvalho Chehab 	p->block_count.len = 1;
68628f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.len = 1;
68638f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.len = 1;
68648f3741e0SMauro Carvalho Chehab 	p->post_bit_error.len = 1;
68658f3741e0SMauro Carvalho Chehab 	p->post_bit_count.len = 1;
68668f3741e0SMauro Carvalho Chehab 
68678f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
68688f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68698f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68708f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68718f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68728f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68738f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68748f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68758f3741e0SMauro Carvalho Chehab 
68763a4398f5SMauro Carvalho Chehab 	pr_info("frontend initialized.\n");
68779a0bf528SMauro Carvalho Chehab 	return &state->frontend;
68789a0bf528SMauro Carvalho Chehab 
68799a0bf528SMauro Carvalho Chehab error:
68803a4398f5SMauro Carvalho Chehab 	pr_err("not found\n");
68819a0bf528SMauro Carvalho Chehab 	kfree(state);
68829a0bf528SMauro Carvalho Chehab 	return NULL;
68839a0bf528SMauro Carvalho Chehab }
68849a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach);
68859a0bf528SMauro Carvalho Chehab 
68869a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
68879a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
68889a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6889