189ee7f4fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29a0bf528SMauro Carvalho Chehab /*
39a0bf528SMauro Carvalho Chehab  * drxk_hard: DRX-K DVB-C/T demodulator driver
49a0bf528SMauro Carvalho Chehab  *
59a0bf528SMauro Carvalho Chehab  * Copyright (C) 2010-2011 Digital Devices GmbH
69a0bf528SMauro Carvalho Chehab  */
79a0bf528SMauro Carvalho Chehab 
83a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
93a4398f5SMauro Carvalho Chehab 
109a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
119a0bf528SMauro Carvalho Chehab #include <linux/module.h>
129a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
139a0bf528SMauro Carvalho Chehab #include <linux/init.h>
149a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
159a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
169a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
179a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
189a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
199a0bf528SMauro Carvalho Chehab 
20fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
219a0bf528SMauro Carvalho Chehab #include "drxk.h"
229a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
23fada1935SMauro Carvalho Chehab #include <media/dvb_math.h>
249a0bf528SMauro Carvalho Chehab 
25cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
26cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state);
27cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
28cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
29cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
30cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode);
31cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
32cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset);
33cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
34cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
35cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state);
36cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
37cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset);
38cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
39cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
40cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state);
41cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state);
429a0bf528SMauro Carvalho Chehab 
43cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state)
449a0bf528SMauro Carvalho Chehab {
45cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_DVBT;
469a0bf528SMauro Carvalho Chehab }
479a0bf528SMauro Carvalho Chehab 
48cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state)
499a0bf528SMauro Carvalho Chehab {
50cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_QAM_ITU_A ||
51cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_B ||
52cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_C;
539a0bf528SMauro Carvalho Chehab }
549a0bf528SMauro Carvalho Chehab 
559a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
569a0bf528SMauro Carvalho Chehab 
579a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
589a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
599a0bf528SMauro Carvalho Chehab 
609a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83  165
619a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93  250
629a0bf528SMauro Carvalho Chehab 
639a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
649a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
659a0bf528SMauro Carvalho Chehab #endif
669a0bf528SMauro Carvalho Chehab 
679a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
689a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
699a0bf528SMauro Carvalho Chehab #endif
709a0bf528SMauro Carvalho Chehab 
719a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
729a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
739a0bf528SMauro Carvalho Chehab 
749a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
759a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV   4
769a0bf528SMauro Carvalho Chehab #endif
779a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
789a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV   6
799a0bf528SMauro Carvalho Chehab #endif
809a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
819a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV   7
829a0bf528SMauro Carvalho Chehab #endif
839a0bf528SMauro Carvalho Chehab 
849a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
859a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM   3
869a0bf528SMauro Carvalho Chehab #endif
879a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
889a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM   4
899a0bf528SMauro Carvalho Chehab #endif
909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
919a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM   7
929a0bf528SMauro Carvalho Chehab #endif
939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
949a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
959a0bf528SMauro Carvalho Chehab #endif
969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
979a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
989a0bf528SMauro Carvalho Chehab #endif
999a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1009a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
1019a0bf528SMauro Carvalho Chehab #endif
1029a0bf528SMauro Carvalho Chehab 
1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1049a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1059a0bf528SMauro Carvalho Chehab #endif
1069a0bf528SMauro Carvalho Chehab 
1079a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1089a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
1099a0bf528SMauro Carvalho Chehab #endif
1109a0bf528SMauro Carvalho Chehab 
1119a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1129a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
1139a0bf528SMauro Carvalho Chehab #endif
1149a0bf528SMauro Carvalho Chehab 
1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1169a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
1179a0bf528SMauro Carvalho Chehab #endif
1189a0bf528SMauro Carvalho Chehab 
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1209a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab 
1239a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
1249a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
1259a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
1269a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG      24
1279a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
1289a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
1299a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM      48
1309a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE        0
1319a0bf528SMauro Carvalho Chehab 
1329a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT                100
1339a0bf528SMauro Carvalho Chehab 
1349a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS      2
1359a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE     6
1369a0bf528SMauro Carvalho Chehab 
1379a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS      28
1389a0bf528SMauro Carvalho Chehab 
1399a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1409a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
1419a0bf528SMauro Carvalho Chehab #endif
1429a0bf528SMauro Carvalho Chehab 
1439a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
1449a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
1459a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
1469a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
1479a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
1489a0bf528SMauro Carvalho Chehab 
1499a0bf528SMauro Carvalho Chehab static unsigned int debug;
1509a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1519a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1529a0bf528SMauro Carvalho Chehab 
1539a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do {				\
1549a0bf528SMauro Carvalho Chehab if (debug >= level)							\
15552ee29feSMauro Carvalho Chehab 	printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg);	\
1569a0bf528SMauro Carvalho Chehab } while (0)
1579a0bf528SMauro Carvalho Chehab 
158ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c)
1599a0bf528SMauro Carvalho Chehab {
1609a0bf528SMauro Carvalho Chehab 	int i = 0;
1619a0bf528SMauro Carvalho Chehab 	u32 Q1 = 0;
1629a0bf528SMauro Carvalho Chehab 	u32 R0 = 0;
1639a0bf528SMauro Carvalho Chehab 
1649a0bf528SMauro Carvalho Chehab 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
165ab5060cdSMauro Carvalho Chehab 	Q1 = a / c;		/*
166ab5060cdSMauro Carvalho Chehab 				 * integer part, only the 4 least significant
167ab5060cdSMauro Carvalho Chehab 				 * bits will be visible in the result
168ab5060cdSMauro Carvalho Chehab 				 */
1699a0bf528SMauro Carvalho Chehab 
1709a0bf528SMauro Carvalho Chehab 	/* division using radix 16, 7 nibbles in the result */
1719a0bf528SMauro Carvalho Chehab 	for (i = 0; i < 7; i++) {
1729a0bf528SMauro Carvalho Chehab 		Q1 = (Q1 << 4) | (R0 / c);
1739a0bf528SMauro Carvalho Chehab 		R0 = (R0 % c) << 4;
1749a0bf528SMauro Carvalho Chehab 	}
1759a0bf528SMauro Carvalho Chehab 	/* rounding */
1769a0bf528SMauro Carvalho Chehab 	if ((R0 >> 3) >= c)
1779a0bf528SMauro Carvalho Chehab 		Q1++;
1789a0bf528SMauro Carvalho Chehab 
1799a0bf528SMauro Carvalho Chehab 	return Q1;
1809a0bf528SMauro Carvalho Chehab }
1819a0bf528SMauro Carvalho Chehab 
182b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value)
1839a0bf528SMauro Carvalho Chehab {
184b5e9eb6fSMauro Carvalho Chehab 	return (100L * intlog10(value)) >> 24;
1859a0bf528SMauro Carvalho Chehab }
1869a0bf528SMauro Carvalho Chehab 
18734eb9751SMauro Carvalho Chehab /***************************************************************************/
1889a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
18934eb9751SMauro Carvalho Chehab /***************************************************************************/
1909a0bf528SMauro Carvalho Chehab 
1919a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
1929a0bf528SMauro Carvalho Chehab {
193c060a9feSPeter Rosin 	i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
1949a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = true;
1959a0bf528SMauro Carvalho Chehab 
1969a0bf528SMauro Carvalho Chehab 	return 0;
1979a0bf528SMauro Carvalho Chehab }
1989a0bf528SMauro Carvalho Chehab 
1999a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
2009a0bf528SMauro Carvalho Chehab {
2019a0bf528SMauro Carvalho Chehab 	if (!state->drxk_i2c_exclusive_lock)
2029a0bf528SMauro Carvalho Chehab 		return;
2039a0bf528SMauro Carvalho Chehab 
204c060a9feSPeter Rosin 	i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
2059a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = false;
2069a0bf528SMauro Carvalho Chehab }
2079a0bf528SMauro Carvalho Chehab 
2089a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
2099a0bf528SMauro Carvalho Chehab 			     unsigned len)
2109a0bf528SMauro Carvalho Chehab {
2119a0bf528SMauro Carvalho Chehab 	if (state->drxk_i2c_exclusive_lock)
2129a0bf528SMauro Carvalho Chehab 		return __i2c_transfer(state->i2c, msgs, len);
2139a0bf528SMauro Carvalho Chehab 	else
2149a0bf528SMauro Carvalho Chehab 		return i2c_transfer(state->i2c, msgs, len);
2159a0bf528SMauro Carvalho Chehab }
2169a0bf528SMauro Carvalho Chehab 
2179a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
2189a0bf528SMauro Carvalho Chehab {
2199a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
2209a0bf528SMauro Carvalho Chehab 				    .buf = val, .len = 1}
2219a0bf528SMauro Carvalho Chehab 	};
2229a0bf528SMauro Carvalho Chehab 
2239a0bf528SMauro Carvalho Chehab 	return drxk_i2c_transfer(state, msgs, 1);
2249a0bf528SMauro Carvalho Chehab }
2259a0bf528SMauro Carvalho Chehab 
2269a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
2279a0bf528SMauro Carvalho Chehab {
2289a0bf528SMauro Carvalho Chehab 	int status;
2299a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg = {
2309a0bf528SMauro Carvalho Chehab 	    .addr = adr, .flags = 0, .buf = data, .len = len };
2319a0bf528SMauro Carvalho Chehab 
2329a0bf528SMauro Carvalho Chehab 	dprintk(3, ":");
2339a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2349a0bf528SMauro Carvalho Chehab 		int i;
2359a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
2360fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", data[i]);
2370fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
2389a0bf528SMauro Carvalho Chehab 	}
2399a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, &msg, 1);
2409a0bf528SMauro Carvalho Chehab 	if (status >= 0 && status != 1)
2419a0bf528SMauro Carvalho Chehab 		status = -EIO;
2429a0bf528SMauro Carvalho Chehab 
2439a0bf528SMauro Carvalho Chehab 	if (status < 0)
2443a4398f5SMauro Carvalho Chehab 		pr_err("i2c write error at addr 0x%02x\n", adr);
2459a0bf528SMauro Carvalho Chehab 
2469a0bf528SMauro Carvalho Chehab 	return status;
2479a0bf528SMauro Carvalho Chehab }
2489a0bf528SMauro Carvalho Chehab 
2499a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
2509a0bf528SMauro Carvalho Chehab 		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
2519a0bf528SMauro Carvalho Chehab {
2529a0bf528SMauro Carvalho Chehab 	int status;
2539a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[2] = {
2549a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = 0,
2559a0bf528SMauro Carvalho Chehab 				    .buf = msg, .len = len},
2569a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = I2C_M_RD,
2579a0bf528SMauro Carvalho Chehab 		 .buf = answ, .len = alen}
2589a0bf528SMauro Carvalho Chehab 	};
2599a0bf528SMauro Carvalho Chehab 
2609a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, msgs, 2);
2619a0bf528SMauro Carvalho Chehab 	if (status != 2) {
2629a0bf528SMauro Carvalho Chehab 		if (debug > 2)
2630fb220f2SMauro Carvalho Chehab 			pr_cont(": ERROR!\n");
2649a0bf528SMauro Carvalho Chehab 		if (status >= 0)
2659a0bf528SMauro Carvalho Chehab 			status = -EIO;
2669a0bf528SMauro Carvalho Chehab 
2673a4398f5SMauro Carvalho Chehab 		pr_err("i2c read error at addr 0x%02x\n", adr);
2689a0bf528SMauro Carvalho Chehab 		return status;
2699a0bf528SMauro Carvalho Chehab 	}
2709a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2719a0bf528SMauro Carvalho Chehab 		int i;
2729a0bf528SMauro Carvalho Chehab 		dprintk(2, ": read from");
2739a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
2740fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", msg[i]);
2750fb220f2SMauro Carvalho Chehab 		pr_cont(", value = ");
2769a0bf528SMauro Carvalho Chehab 		for (i = 0; i < alen; i++)
2770fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", answ[i]);
2780fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
2799a0bf528SMauro Carvalho Chehab 	}
2809a0bf528SMauro Carvalho Chehab 	return 0;
2819a0bf528SMauro Carvalho Chehab }
2829a0bf528SMauro Carvalho Chehab 
2839a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
2849a0bf528SMauro Carvalho Chehab {
2859a0bf528SMauro Carvalho Chehab 	int status;
2869a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[2], len;
2879a0bf528SMauro Carvalho Chehab 
2889a0bf528SMauro Carvalho Chehab 	if (state->single_master)
2899a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
2909a0bf528SMauro Carvalho Chehab 
2919a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
2929a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
2939a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
2949a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
2959a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
2969a0bf528SMauro Carvalho Chehab 		len = 4;
2979a0bf528SMauro Carvalho Chehab 	} else {
2989a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
2999a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3009a0bf528SMauro Carvalho Chehab 		len = 2;
3019a0bf528SMauro Carvalho Chehab 	}
3029a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3039a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 2);
3049a0bf528SMauro Carvalho Chehab 	if (status < 0)
3059a0bf528SMauro Carvalho Chehab 		return status;
3069a0bf528SMauro Carvalho Chehab 	if (data)
3079a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8);
3089a0bf528SMauro Carvalho Chehab 
3099a0bf528SMauro Carvalho Chehab 	return 0;
3109a0bf528SMauro Carvalho Chehab }
3119a0bf528SMauro Carvalho Chehab 
3129a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
3139a0bf528SMauro Carvalho Chehab {
3149a0bf528SMauro Carvalho Chehab 	return read16_flags(state, reg, data, 0);
3159a0bf528SMauro Carvalho Chehab }
3169a0bf528SMauro Carvalho Chehab 
3179a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
3189a0bf528SMauro Carvalho Chehab {
3199a0bf528SMauro Carvalho Chehab 	int status;
3209a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[4], len;
3219a0bf528SMauro Carvalho Chehab 
3229a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3239a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3249a0bf528SMauro Carvalho Chehab 
3259a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3269a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3279a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3289a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3299a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3309a0bf528SMauro Carvalho Chehab 		len = 4;
3319a0bf528SMauro Carvalho Chehab 	} else {
3329a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3339a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3349a0bf528SMauro Carvalho Chehab 		len = 2;
3359a0bf528SMauro Carvalho Chehab 	}
3369a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3379a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 4);
3389a0bf528SMauro Carvalho Chehab 	if (status < 0)
3399a0bf528SMauro Carvalho Chehab 		return status;
3409a0bf528SMauro Carvalho Chehab 	if (data)
3419a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8) |
3429a0bf528SMauro Carvalho Chehab 		    (mm2[2] << 16) | (mm2[3] << 24);
3439a0bf528SMauro Carvalho Chehab 
3449a0bf528SMauro Carvalho Chehab 	return 0;
3459a0bf528SMauro Carvalho Chehab }
3469a0bf528SMauro Carvalho Chehab 
3479a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
3489a0bf528SMauro Carvalho Chehab {
3499a0bf528SMauro Carvalho Chehab 	return read32_flags(state, reg, data, 0);
3509a0bf528SMauro Carvalho Chehab }
3519a0bf528SMauro Carvalho Chehab 
3529a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
3539a0bf528SMauro Carvalho Chehab {
3549a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[6], len;
3559a0bf528SMauro Carvalho Chehab 
3569a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3579a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3589a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3599a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3609a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3619a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3629a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3639a0bf528SMauro Carvalho Chehab 		len = 4;
3649a0bf528SMauro Carvalho Chehab 	} else {
3659a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3669a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3679a0bf528SMauro Carvalho Chehab 		len = 2;
3689a0bf528SMauro Carvalho Chehab 	}
3699a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3709a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
3719a0bf528SMauro Carvalho Chehab 
3729a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
3739a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 2);
3749a0bf528SMauro Carvalho Chehab }
3759a0bf528SMauro Carvalho Chehab 
3769a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
3779a0bf528SMauro Carvalho Chehab {
3789a0bf528SMauro Carvalho Chehab 	return write16_flags(state, reg, data, 0);
3799a0bf528SMauro Carvalho Chehab }
3809a0bf528SMauro Carvalho Chehab 
3819a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
3829a0bf528SMauro Carvalho Chehab {
3839a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[8], len;
3849a0bf528SMauro Carvalho Chehab 
3859a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3869a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3879a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3889a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3899a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3909a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3919a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3929a0bf528SMauro Carvalho Chehab 		len = 4;
3939a0bf528SMauro Carvalho Chehab 	} else {
3949a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3959a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3969a0bf528SMauro Carvalho Chehab 		len = 2;
3979a0bf528SMauro Carvalho Chehab 	}
3989a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3999a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
4009a0bf528SMauro Carvalho Chehab 	mm[len + 2] = (data >> 16) & 0xff;
4019a0bf528SMauro Carvalho Chehab 	mm[len + 3] = (data >> 24) & 0xff;
4029a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
4039a0bf528SMauro Carvalho Chehab 
4049a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 4);
4059a0bf528SMauro Carvalho Chehab }
4069a0bf528SMauro Carvalho Chehab 
4079a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
4089a0bf528SMauro Carvalho Chehab {
4099a0bf528SMauro Carvalho Chehab 	return write32_flags(state, reg, data, 0);
4109a0bf528SMauro Carvalho Chehab }
4119a0bf528SMauro Carvalho Chehab 
412cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address,
413cd7a67a4SMauro Carvalho Chehab 		      const int block_size, const u8 p_block[])
4149a0bf528SMauro Carvalho Chehab {
415cd7a67a4SMauro Carvalho Chehab 	int status = 0, blk_size = block_size;
416cd7a67a4SMauro Carvalho Chehab 	u8 flags = 0;
4179a0bf528SMauro Carvalho Chehab 
4189a0bf528SMauro Carvalho Chehab 	if (state->single_master)
419cd7a67a4SMauro Carvalho Chehab 		flags |= 0xC0;
4209a0bf528SMauro Carvalho Chehab 
421cd7a67a4SMauro Carvalho Chehab 	while (blk_size > 0) {
422cd7a67a4SMauro Carvalho Chehab 		int chunk = blk_size > state->m_chunk_size ?
423cd7a67a4SMauro Carvalho Chehab 		    state->m_chunk_size : blk_size;
424cd7a67a4SMauro Carvalho Chehab 		u8 *adr_buf = &state->chunk[0];
425cd7a67a4SMauro Carvalho Chehab 		u32 adr_length = 0;
4269a0bf528SMauro Carvalho Chehab 
427cd7a67a4SMauro Carvalho Chehab 		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
428cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
429cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = ((address >> 16) & 0xFF);
430cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] = ((address >> 24) & 0xFF);
431cd7a67a4SMauro Carvalho Chehab 			adr_buf[3] = ((address >> 7) & 0xFF);
432cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] |= flags;
433cd7a67a4SMauro Carvalho Chehab 			adr_length = 4;
434cd7a67a4SMauro Carvalho Chehab 			if (chunk == state->m_chunk_size)
435cd7a67a4SMauro Carvalho Chehab 				chunk -= 2;
4369a0bf528SMauro Carvalho Chehab 		} else {
437cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = ((address << 1) & 0xFF);
438cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = (((address >> 16) & 0x0F) |
439cd7a67a4SMauro Carvalho Chehab 				     ((address >> 18) & 0xF0));
440cd7a67a4SMauro Carvalho Chehab 			adr_length = 2;
4419a0bf528SMauro Carvalho Chehab 		}
442cd7a67a4SMauro Carvalho Chehab 		memcpy(&state->chunk[adr_length], p_block, chunk);
443cd7a67a4SMauro Carvalho Chehab 		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
4449a0bf528SMauro Carvalho Chehab 		if (debug > 1) {
4459a0bf528SMauro Carvalho Chehab 			int i;
446cd7a67a4SMauro Carvalho Chehab 			if (p_block)
447cd7a67a4SMauro Carvalho Chehab 				for (i = 0; i < chunk; i++)
4480fb220f2SMauro Carvalho Chehab 					pr_cont(" %02x", p_block[i]);
4490fb220f2SMauro Carvalho Chehab 			pr_cont("\n");
4509a0bf528SMauro Carvalho Chehab 		}
4519a0bf528SMauro Carvalho Chehab 		status = i2c_write(state, state->demod_address,
452cd7a67a4SMauro Carvalho Chehab 				   &state->chunk[0], chunk + adr_length);
4539a0bf528SMauro Carvalho Chehab 		if (status < 0) {
4543a4398f5SMauro Carvalho Chehab 			pr_err("%s: i2c write error at addr 0x%02x\n",
455cd7a67a4SMauro Carvalho Chehab 			       __func__, address);
4569a0bf528SMauro Carvalho Chehab 			break;
4579a0bf528SMauro Carvalho Chehab 		}
458cd7a67a4SMauro Carvalho Chehab 		p_block += chunk;
459cd7a67a4SMauro Carvalho Chehab 		address += (chunk >> 1);
460cd7a67a4SMauro Carvalho Chehab 		blk_size -= chunk;
4619a0bf528SMauro Carvalho Chehab 	}
4629a0bf528SMauro Carvalho Chehab 	return status;
4639a0bf528SMauro Carvalho Chehab }
4649a0bf528SMauro Carvalho Chehab 
4659a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
4669a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
4679a0bf528SMauro Carvalho Chehab #endif
4689a0bf528SMauro Carvalho Chehab 
469cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state)
4709a0bf528SMauro Carvalho Chehab {
4719a0bf528SMauro Carvalho Chehab 	int status;
4729a0bf528SMauro Carvalho Chehab 	u8 data = 0;
473cd7a67a4SMauro Carvalho Chehab 	u16 retry_count = 0;
4749a0bf528SMauro Carvalho Chehab 
4759a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4769a0bf528SMauro Carvalho Chehab 
4779a0bf528SMauro Carvalho Chehab 	status = i2c_read1(state, state->demod_address, &data);
4789a0bf528SMauro Carvalho Chehab 	if (status < 0) {
4799a0bf528SMauro Carvalho Chehab 		do {
4809a0bf528SMauro Carvalho Chehab 			data = 0;
4819a0bf528SMauro Carvalho Chehab 			status = i2c_write(state, state->demod_address,
4829a0bf528SMauro Carvalho Chehab 					   &data, 1);
483b72852baSMauro Carvalho Chehab 			usleep_range(10000, 11000);
484cd7a67a4SMauro Carvalho Chehab 			retry_count++;
4859a0bf528SMauro Carvalho Chehab 			if (status < 0)
4869a0bf528SMauro Carvalho Chehab 				continue;
4879a0bf528SMauro Carvalho Chehab 			status = i2c_read1(state, state->demod_address,
4889a0bf528SMauro Carvalho Chehab 					   &data);
4899a0bf528SMauro Carvalho Chehab 		} while (status < 0 &&
490cd7a67a4SMauro Carvalho Chehab 			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
491cd7a67a4SMauro Carvalho Chehab 		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
4929a0bf528SMauro Carvalho Chehab 			goto error;
4939a0bf528SMauro Carvalho Chehab 	}
4949a0bf528SMauro Carvalho Chehab 
4959a0bf528SMauro Carvalho Chehab 	/* Make sure all clk domains are active */
4969a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
4979a0bf528SMauro Carvalho Chehab 	if (status < 0)
4989a0bf528SMauro Carvalho Chehab 		goto error;
4999a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5009a0bf528SMauro Carvalho Chehab 	if (status < 0)
5019a0bf528SMauro Carvalho Chehab 		goto error;
5029a0bf528SMauro Carvalho Chehab 	/* Enable pll lock tests */
5039a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PLL_LOCK__A, 1);
5049a0bf528SMauro Carvalho Chehab 	if (status < 0)
5059a0bf528SMauro Carvalho Chehab 		goto error;
5069a0bf528SMauro Carvalho Chehab 
507cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_UP;
5089a0bf528SMauro Carvalho Chehab 
5099a0bf528SMauro Carvalho Chehab error:
5109a0bf528SMauro Carvalho Chehab 	if (status < 0)
5113a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
5129a0bf528SMauro Carvalho Chehab 
5139a0bf528SMauro Carvalho Chehab 	return status;
5149a0bf528SMauro Carvalho Chehab }
5159a0bf528SMauro Carvalho Chehab 
5169a0bf528SMauro Carvalho Chehab 
5179a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
5189a0bf528SMauro Carvalho Chehab {
5199a0bf528SMauro Carvalho Chehab 	/*
5205a13e40bSMauro Carvalho Chehab 	 * FIXME: most (all?) of the values below should be moved into
5219a0bf528SMauro Carvalho Chehab 	 * struct drxk_config, as they are probably board-specific
5229a0bf528SMauro Carvalho Chehab 	 */
523cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
524cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_output_level = 0;
525cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_min_level = 0;
526cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_max_level = 0x7FFF;
527cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_speed = 3;
5289a0bf528SMauro Carvalho Chehab 
529cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
530cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_output_level = 0;
531cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_min_level = 0;
532cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
533cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_speed = 3;
534cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_top = 9500;
535cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_cut_off_current = 4000;
5369a0bf528SMauro Carvalho Chehab 
537cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
538cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_output_level = 0;
539cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_min_level = 0;
540cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_max_level = 0;
541cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_speed = 3;
5429a0bf528SMauro Carvalho Chehab 
543cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
544cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_output_level = 0;
545cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_min_level = 0;
546cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_max_level = 0;
547cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_top = 9500;
548cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_cut_off_current = 4000;
549cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_speed = 3;
5509a0bf528SMauro Carvalho Chehab 
5519a0bf528SMauro Carvalho Chehab 	u32 ulQual83 = DEFAULT_MER_83;
5529a0bf528SMauro Carvalho Chehab 	u32 ulQual93 = DEFAULT_MER_93;
5539a0bf528SMauro Carvalho Chehab 
554cd7a67a4SMauro Carvalho Chehab 	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
555cd7a67a4SMauro Carvalho Chehab 	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
5569a0bf528SMauro Carvalho Chehab 
5579a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
5589a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_mode output mode is drive always */
5599a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
560cd7a67a4SMauro Carvalho Chehab 	u32 ul_gpio_cfg = 0x0113;
561cd7a67a4SMauro Carvalho Chehab 	u32 ul_invert_ts_clock = 0;
562cd7a67a4SMauro Carvalho Chehab 	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
563cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbt_bitrate = 50000000;
564cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
5659a0bf528SMauro Carvalho Chehab 
566cd7a67a4SMauro Carvalho Chehab 	u32 ul_insert_rs_byte = 0;
5679a0bf528SMauro Carvalho Chehab 
568cd7a67a4SMauro Carvalho Chehab 	u32 ul_rf_mirror = 1;
569cd7a67a4SMauro Carvalho Chehab 	u32 ul_power_down = 0;
5709a0bf528SMauro Carvalho Chehab 
5719a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5729a0bf528SMauro Carvalho Chehab 
573cd7a67a4SMauro Carvalho Chehab 	state->m_has_lna = false;
574cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbt = false;
575cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbc = false;
576cd7a67a4SMauro Carvalho Chehab 	state->m_has_atv = false;
577cd7a67a4SMauro Carvalho Chehab 	state->m_has_oob = false;
578cd7a67a4SMauro Carvalho Chehab 	state->m_has_audio = false;
5799a0bf528SMauro Carvalho Chehab 
580cd7a67a4SMauro Carvalho Chehab 	if (!state->m_chunk_size)
581cd7a67a4SMauro Carvalho Chehab 		state->m_chunk_size = 124;
5829a0bf528SMauro Carvalho Chehab 
583cd7a67a4SMauro Carvalho Chehab 	state->m_osc_clock_freq = 0;
584cd7a67a4SMauro Carvalho Chehab 	state->m_smart_ant_inverted = false;
585cd7a67a4SMauro Carvalho Chehab 	state->m_b_p_down_open_bridge = false;
5869a0bf528SMauro Carvalho Chehab 
5879a0bf528SMauro Carvalho Chehab 	/* real system clock frequency in kHz */
588cd7a67a4SMauro Carvalho Chehab 	state->m_sys_clock_freq = 151875;
5899a0bf528SMauro Carvalho Chehab 	/* Timing div, 250ns/Psys */
5909a0bf528SMauro Carvalho Chehab 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
591cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
5929a0bf528SMauro Carvalho Chehab 				   HI_I2C_DELAY) / 1000;
5939a0bf528SMauro Carvalho Chehab 	/* Clipping */
594cd7a67a4SMauro Carvalho Chehab 	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
595cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
596cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
5979a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
598cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
5999a0bf528SMauro Carvalho Chehab 
600cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = (ul_power_down != 0);
6019a0bf528SMauro Carvalho Chehab 
602cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_a3_patch_code = false;
6039a0bf528SMauro Carvalho Chehab 
6049a0bf528SMauro Carvalho Chehab 	/* Init AGC and PGA parameters */
6059a0bf528SMauro Carvalho Chehab 	/* VSB IF */
606949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
607949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
608949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
609949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
610949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
611cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pga_cfg = 140;
6129a0bf528SMauro Carvalho Chehab 
6139a0bf528SMauro Carvalho Chehab 	/* VSB RF */
614949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
615949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
616949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
617949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
618949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
619949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
620949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
621cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.reference = 0x07;
622cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
6239a0bf528SMauro Carvalho Chehab 
6249a0bf528SMauro Carvalho Chehab 	state->m_Quality83percent = DEFAULT_MER_83;
6259a0bf528SMauro Carvalho Chehab 	state->m_Quality93percent = DEFAULT_MER_93;
6269a0bf528SMauro Carvalho Chehab 	if (ulQual93 <= 500 && ulQual83 < ulQual93) {
6279a0bf528SMauro Carvalho Chehab 		state->m_Quality83percent = ulQual83;
6289a0bf528SMauro Carvalho Chehab 		state->m_Quality93percent = ulQual93;
6299a0bf528SMauro Carvalho Chehab 	}
6309a0bf528SMauro Carvalho Chehab 
6319a0bf528SMauro Carvalho Chehab 	/* ATV IF */
632949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
633949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
634949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
635949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
636949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
6379a0bf528SMauro Carvalho Chehab 
6389a0bf528SMauro Carvalho Chehab 	/* ATV RF */
639949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
640949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
641949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
642949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
643949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
644949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
645949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
646cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.reference = 0x04;
647cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.use_pre_saw = true;
6489a0bf528SMauro Carvalho Chehab 
6499a0bf528SMauro Carvalho Chehab 
6509a0bf528SMauro Carvalho Chehab 	/* DVBT RF */
651cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
652cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.output_level = 0;
653cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
654cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
655cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.top = 0x2100;
656cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
657cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.speed = 1;
6589a0bf528SMauro Carvalho Chehab 
6599a0bf528SMauro Carvalho Chehab 
6609a0bf528SMauro Carvalho Chehab 	/* DVBT IF */
661cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
662cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.output_level = 0;
663cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.min_output_level = 0;
664cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
665cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.top = 13424;
666cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
667cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.speed = 3;
668cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
669cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
6709a0bf528SMauro Carvalho Chehab 	/* state->m_dvbtPgaCfg = 140; */
6719a0bf528SMauro Carvalho Chehab 
672cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.reference = 4;
673cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
6749a0bf528SMauro Carvalho Chehab 
6759a0bf528SMauro Carvalho Chehab 	/* QAM RF */
676cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
677cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.output_level = 0;
678cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.min_output_level = 6023;
679cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.max_output_level = 27000;
680cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.top = 0x2380;
681cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
682cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.speed = 3;
6839a0bf528SMauro Carvalho Chehab 
6849a0bf528SMauro Carvalho Chehab 	/* QAM IF */
685cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
686cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.output_level = 0;
687cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.min_output_level = 0;
688cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.max_output_level = 9000;
689cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.top = 0x0511;
690cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.cut_off_current = 0;
691cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.speed = 3;
692cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
693cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
6949a0bf528SMauro Carvalho Chehab 
695cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pga_cfg = 140;
696cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.reference = 4;
697cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.use_pre_saw = false;
6989a0bf528SMauro Carvalho Chehab 
699cd7a67a4SMauro Carvalho Chehab 	state->m_operation_mode = OM_NONE;
700cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_state = DRXK_UNINITIALIZED;
7019a0bf528SMauro Carvalho Chehab 
7029a0bf528SMauro Carvalho Chehab 	/* MPEG output configuration */
703868c9a17SMauro Carvalho Chehab 	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG output */
704cd7a67a4SMauro Carvalho Chehab 	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
705cd7a67a4SMauro Carvalho Chehab 	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
706cd7a67a4SMauro Carvalho Chehab 	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
707cd7a67a4SMauro Carvalho Chehab 	state->m_invert_str = false;	/* If TRUE; invert STR signals */
708cd7a67a4SMauro Carvalho Chehab 	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
709cd7a67a4SMauro Carvalho Chehab 	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
7109a0bf528SMauro Carvalho Chehab 
7119a0bf528SMauro Carvalho Chehab 	/* If TRUE; static MPEG clockrate will be used;
7129a0bf528SMauro Carvalho Chehab 	   otherwise clockrate will adapt to the bitrate of the TS */
7139a0bf528SMauro Carvalho Chehab 
714cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_bitrate = ul_dvbt_bitrate;
715cd7a67a4SMauro Carvalho Chehab 	state->m_dvbc_bitrate = ul_dvbc_bitrate;
7169a0bf528SMauro Carvalho Chehab 
717cd7a67a4SMauro Carvalho Chehab 	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
7189a0bf528SMauro Carvalho Chehab 
7199a0bf528SMauro Carvalho Chehab 	/* Maximum bitrate in b/s in case static clockrate is selected */
720cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_ts_static_bitrate = 19392658;
721cd7a67a4SMauro Carvalho Chehab 	state->m_disable_te_ihandling = false;
7229a0bf528SMauro Carvalho Chehab 
723cd7a67a4SMauro Carvalho Chehab 	if (ul_insert_rs_byte)
724cd7a67a4SMauro Carvalho Chehab 		state->m_insert_rs_byte = true;
7259a0bf528SMauro Carvalho Chehab 
726cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
727cd7a67a4SMauro Carvalho Chehab 	if (ul_mpeg_lock_time_out < 10000)
728cd7a67a4SMauro Carvalho Chehab 		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
729cd7a67a4SMauro Carvalho Chehab 	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
730cd7a67a4SMauro Carvalho Chehab 	if (ul_demod_lock_time_out < 10000)
731cd7a67a4SMauro Carvalho Chehab 		state->m_demod_lock_time_out = ul_demod_lock_time_out;
7329a0bf528SMauro Carvalho Chehab 
7339a0bf528SMauro Carvalho Chehab 	/* QAM defaults */
734cd7a67a4SMauro Carvalho Chehab 	state->m_constellation = DRX_CONSTELLATION_AUTO;
735cd7a67a4SMauro Carvalho Chehab 	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
736cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
737cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_prescale = 1;
7389a0bf528SMauro Carvalho Chehab 
739cd7a67a4SMauro Carvalho Chehab 	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
740cd7a67a4SMauro Carvalho Chehab 	state->m_agcfast_clip_ctrl_delay = 0;
7419a0bf528SMauro Carvalho Chehab 
742949dd08dSMauro Carvalho Chehab 	state->m_gpio_cfg = ul_gpio_cfg;
7439a0bf528SMauro Carvalho Chehab 
744cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = false;
745cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_DOWN;
7469a0bf528SMauro Carvalho Chehab 
747cd7a67a4SMauro Carvalho Chehab 	state->m_rfmirror = (ul_rf_mirror == 0);
748cd7a67a4SMauro Carvalho Chehab 	state->m_if_agc_pol = false;
7499a0bf528SMauro Carvalho Chehab 	return 0;
7509a0bf528SMauro Carvalho Chehab }
7519a0bf528SMauro Carvalho Chehab 
752cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state)
7539a0bf528SMauro Carvalho Chehab {
7549a0bf528SMauro Carvalho Chehab 	int status = 0;
7559a0bf528SMauro Carvalho Chehab 	u32 jtag = 0;
7569a0bf528SMauro Carvalho Chehab 	u16 bid = 0;
7579a0bf528SMauro Carvalho Chehab 	u16 key = 0;
7589a0bf528SMauro Carvalho Chehab 
7599a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7609a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
761ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
762ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7639a0bf528SMauro Carvalho Chehab 	if (status < 0)
7649a0bf528SMauro Carvalho Chehab 		goto error;
7659a0bf528SMauro Carvalho Chehab 	/* Check device id */
7669a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_TOP_COMM_KEY__A, &key);
7679a0bf528SMauro Carvalho Chehab 	if (status < 0)
7689a0bf528SMauro Carvalho Chehab 		goto error;
7699a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7709a0bf528SMauro Carvalho Chehab 	if (status < 0)
7719a0bf528SMauro Carvalho Chehab 		goto error;
7729a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
7739a0bf528SMauro Carvalho Chehab 	if (status < 0)
7749a0bf528SMauro Carvalho Chehab 		goto error;
7759a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
7769a0bf528SMauro Carvalho Chehab 	if (status < 0)
7779a0bf528SMauro Carvalho Chehab 		goto error;
7789a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
7799a0bf528SMauro Carvalho Chehab error:
7809a0bf528SMauro Carvalho Chehab 	if (status < 0)
7813a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
7829a0bf528SMauro Carvalho Chehab 	return status;
7839a0bf528SMauro Carvalho Chehab }
7849a0bf528SMauro Carvalho Chehab 
785cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state)
7869a0bf528SMauro Carvalho Chehab {
787cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_ohw_cfg = 0;
788cd7a67a4SMauro Carvalho Chehab 	u32 sio_top_jtagid_lo = 0;
7899a0bf528SMauro Carvalho Chehab 	int status;
7909a0bf528SMauro Carvalho Chehab 	const char *spin = "";
7919a0bf528SMauro Carvalho Chehab 
7929a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7939a0bf528SMauro Carvalho Chehab 
7949a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
7959a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
796ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
797ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7989a0bf528SMauro Carvalho Chehab 	if (status < 0)
7999a0bf528SMauro Carvalho Chehab 		goto error;
8008418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
8019a0bf528SMauro Carvalho Chehab 	if (status < 0)
8029a0bf528SMauro Carvalho Chehab 		goto error;
803cd7a67a4SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
8049a0bf528SMauro Carvalho Chehab 	if (status < 0)
8059a0bf528SMauro Carvalho Chehab 		goto error;
8069a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
8079a0bf528SMauro Carvalho Chehab 	if (status < 0)
8089a0bf528SMauro Carvalho Chehab 		goto error;
8099a0bf528SMauro Carvalho Chehab 
810cd7a67a4SMauro Carvalho Chehab 	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
8119a0bf528SMauro Carvalho Chehab 	case 0:
8129a0bf528SMauro Carvalho Chehab 		/* ignore (bypass ?) */
8139a0bf528SMauro Carvalho Chehab 		break;
8149a0bf528SMauro Carvalho Chehab 	case 1:
8159a0bf528SMauro Carvalho Chehab 		/* 27 MHz */
816cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 27000;
8179a0bf528SMauro Carvalho Chehab 		break;
8189a0bf528SMauro Carvalho Chehab 	case 2:
8199a0bf528SMauro Carvalho Chehab 		/* 20.25 MHz */
820cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8219a0bf528SMauro Carvalho Chehab 		break;
8229a0bf528SMauro Carvalho Chehab 	case 3:
8239a0bf528SMauro Carvalho Chehab 		/* 4 MHz */
824cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8259a0bf528SMauro Carvalho Chehab 		break;
8269a0bf528SMauro Carvalho Chehab 	default:
8273a4398f5SMauro Carvalho Chehab 		pr_err("Clock Frequency is unknown\n");
8289a0bf528SMauro Carvalho Chehab 		return -EINVAL;
8299a0bf528SMauro Carvalho Chehab 	}
8309a0bf528SMauro Carvalho Chehab 	/*
8319a0bf528SMauro Carvalho Chehab 		Determine device capabilities
8329a0bf528SMauro Carvalho Chehab 		Based on pinning v14
8339a0bf528SMauro Carvalho Chehab 		*/
834cd7a67a4SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
8359a0bf528SMauro Carvalho Chehab 	if (status < 0)
8369a0bf528SMauro Carvalho Chehab 		goto error;
8379a0bf528SMauro Carvalho Chehab 
8383a4398f5SMauro Carvalho Chehab 	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
8399a0bf528SMauro Carvalho Chehab 
8409a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
841cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
8429a0bf528SMauro Carvalho Chehab 	case 0:
843cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A1;
8449a0bf528SMauro Carvalho Chehab 		spin = "A1";
8459a0bf528SMauro Carvalho Chehab 		break;
8469a0bf528SMauro Carvalho Chehab 	case 2:
847cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A2;
8489a0bf528SMauro Carvalho Chehab 		spin = "A2";
8499a0bf528SMauro Carvalho Chehab 		break;
8509a0bf528SMauro Carvalho Chehab 	case 3:
851cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A3;
8529a0bf528SMauro Carvalho Chehab 		spin = "A3";
8539a0bf528SMauro Carvalho Chehab 		break;
8549a0bf528SMauro Carvalho Chehab 	default:
855cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_UNKNOWN;
8569a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
8573a4398f5SMauro Carvalho Chehab 		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
8589a0bf528SMauro Carvalho Chehab 		goto error2;
8599a0bf528SMauro Carvalho Chehab 	}
860cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
8619a0bf528SMauro Carvalho Chehab 	case 0x13:
8629a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3913K_TYPE_ID */
863cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
864cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
865cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = false;
866cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
867cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
868cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
869cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
870cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = false;
871cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = false;
872cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8739a0bf528SMauro Carvalho Chehab 		break;
8749a0bf528SMauro Carvalho Chehab 	case 0x15:
8759a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3915K_TYPE_ID */
876cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
877cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
878cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
879cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
880cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
881cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
882cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
883cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
884cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
885cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8869a0bf528SMauro Carvalho Chehab 		break;
8879a0bf528SMauro Carvalho Chehab 	case 0x16:
8889a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3916K_TYPE_ID */
889cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
890cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
891cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
892cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
893cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
894cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
895cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
896cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
897cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
898cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8999a0bf528SMauro Carvalho Chehab 		break;
9009a0bf528SMauro Carvalho Chehab 	case 0x18:
9019a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3918K_TYPE_ID */
902cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
903cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
904cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
905cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
906cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
907cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
908cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
909cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
910cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
911cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9129a0bf528SMauro Carvalho Chehab 		break;
9139a0bf528SMauro Carvalho Chehab 	case 0x21:
9149a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3921K_TYPE_ID */
915cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
916cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
917cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
918cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
919cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
920cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
921cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
922cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
923cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
924cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9259a0bf528SMauro Carvalho Chehab 		break;
9269a0bf528SMauro Carvalho Chehab 	case 0x23:
9279a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3923K_TYPE_ID */
928cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
929cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
930cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
931cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
932cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
933cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
934cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
935cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
936cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
937cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9389a0bf528SMauro Carvalho Chehab 		break;
9399a0bf528SMauro Carvalho Chehab 	case 0x25:
9409a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3925K_TYPE_ID */
941cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
942cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
943cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
944cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
945cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
946cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
947cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
948cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
949cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
950cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9519a0bf528SMauro Carvalho Chehab 		break;
9529a0bf528SMauro Carvalho Chehab 	case 0x26:
9539a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3926K_TYPE_ID */
954cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
955cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
956cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
957cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
958cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
959cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
960cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
961cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
962cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
963cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9649a0bf528SMauro Carvalho Chehab 		break;
9659a0bf528SMauro Carvalho Chehab 	default:
9663a4398f5SMauro Carvalho Chehab 		pr_err("DeviceID 0x%02x not supported\n",
967cd7a67a4SMauro Carvalho Chehab 			((sio_top_jtagid_lo >> 12) & 0xFF));
9689a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
9699a0bf528SMauro Carvalho Chehab 		goto error2;
9709a0bf528SMauro Carvalho Chehab 	}
9719a0bf528SMauro Carvalho Chehab 
9723a4398f5SMauro Carvalho Chehab 	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
973cd7a67a4SMauro Carvalho Chehab 	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
974cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq / 1000,
975cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq % 1000);
9769a0bf528SMauro Carvalho Chehab 
9779a0bf528SMauro Carvalho Chehab error:
9789a0bf528SMauro Carvalho Chehab 	if (status < 0)
9793a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
9809a0bf528SMauro Carvalho Chehab 
9819a0bf528SMauro Carvalho Chehab error2:
9829a0bf528SMauro Carvalho Chehab 	return status;
9839a0bf528SMauro Carvalho Chehab }
9849a0bf528SMauro Carvalho Chehab 
985cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
9869a0bf528SMauro Carvalho Chehab {
9879a0bf528SMauro Carvalho Chehab 	int status;
9889a0bf528SMauro Carvalho Chehab 	bool powerdown_cmd;
9899a0bf528SMauro Carvalho Chehab 
9909a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
9919a0bf528SMauro Carvalho Chehab 
9929a0bf528SMauro Carvalho Chehab 	/* Write command */
9939a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
9949a0bf528SMauro Carvalho Chehab 	if (status < 0)
9959a0bf528SMauro Carvalho Chehab 		goto error;
9969a0bf528SMauro Carvalho Chehab 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
997b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
9989a0bf528SMauro Carvalho Chehab 
9999a0bf528SMauro Carvalho Chehab 	powerdown_cmd =
10009a0bf528SMauro Carvalho Chehab 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1001cd7a67a4SMauro Carvalho Chehab 		    ((state->m_hi_cfg_ctrl) &
10029a0bf528SMauro Carvalho Chehab 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
10039a0bf528SMauro Carvalho Chehab 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
10045a7f7b79SMauro Carvalho Chehab 	if (!powerdown_cmd) {
10059a0bf528SMauro Carvalho Chehab 		/* Wait until command rdy */
1006cd7a67a4SMauro Carvalho Chehab 		u32 retry_count = 0;
1007cd7a67a4SMauro Carvalho Chehab 		u16 wait_cmd;
10089a0bf528SMauro Carvalho Chehab 
10099a0bf528SMauro Carvalho Chehab 		do {
1010b72852baSMauro Carvalho Chehab 			usleep_range(1000, 2000);
1011cd7a67a4SMauro Carvalho Chehab 			retry_count += 1;
10129a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
1013cd7a67a4SMauro Carvalho Chehab 					  &wait_cmd);
1014cd7a67a4SMauro Carvalho Chehab 		} while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
1015cd7a67a4SMauro Carvalho Chehab 			 && (wait_cmd != 0));
10169a0bf528SMauro Carvalho Chehab 		if (status < 0)
10179a0bf528SMauro Carvalho Chehab 			goto error;
1018cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
10199a0bf528SMauro Carvalho Chehab 	}
10209a0bf528SMauro Carvalho Chehab error:
10219a0bf528SMauro Carvalho Chehab 	if (status < 0)
10223a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10239a0bf528SMauro Carvalho Chehab 
10249a0bf528SMauro Carvalho Chehab 	return status;
10259a0bf528SMauro Carvalho Chehab }
10269a0bf528SMauro Carvalho Chehab 
1027cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state)
10289a0bf528SMauro Carvalho Chehab {
10299a0bf528SMauro Carvalho Chehab 	int status;
10309a0bf528SMauro Carvalho Chehab 
10319a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10329a0bf528SMauro Carvalho Chehab 
10339a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
10349a0bf528SMauro Carvalho Chehab 
1035ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1036ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timeout);
10379a0bf528SMauro Carvalho Chehab 	if (status < 0)
10389a0bf528SMauro Carvalho Chehab 		goto error;
1039ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1040ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_ctrl);
10419a0bf528SMauro Carvalho Chehab 	if (status < 0)
10429a0bf528SMauro Carvalho Chehab 		goto error;
1043ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1044ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_wake_up_key);
10459a0bf528SMauro Carvalho Chehab 	if (status < 0)
10469a0bf528SMauro Carvalho Chehab 		goto error;
1047ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1048ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_bridge_delay);
10499a0bf528SMauro Carvalho Chehab 	if (status < 0)
10509a0bf528SMauro Carvalho Chehab 		goto error;
1051ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1052ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timing_div);
10539a0bf528SMauro Carvalho Chehab 	if (status < 0)
10549a0bf528SMauro Carvalho Chehab 		goto error;
1055ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1056ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
10579a0bf528SMauro Carvalho Chehab 	if (status < 0)
10589a0bf528SMauro Carvalho Chehab 		goto error;
1059b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
10609a0bf528SMauro Carvalho Chehab 	if (status < 0)
10619a0bf528SMauro Carvalho Chehab 		goto error;
10629a0bf528SMauro Carvalho Chehab 
1063cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
10649a0bf528SMauro Carvalho Chehab error:
10659a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
10669a0bf528SMauro Carvalho Chehab 	if (status < 0)
10673a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10689a0bf528SMauro Carvalho Chehab 	return status;
10699a0bf528SMauro Carvalho Chehab }
10709a0bf528SMauro Carvalho Chehab 
1071cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state)
10729a0bf528SMauro Carvalho Chehab {
10739a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10749a0bf528SMauro Carvalho Chehab 
1075cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1076cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timeout = 0x96FF;
10779a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
1078cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
10799a0bf528SMauro Carvalho Chehab 
1080cd7a67a4SMauro Carvalho Chehab 	return hi_cfg_command(state);
10819a0bf528SMauro Carvalho Chehab }
10829a0bf528SMauro Carvalho Chehab 
1083cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
10849a0bf528SMauro Carvalho Chehab {
108543c4dc3fSColin Ian King 	int status;
1086cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mclk_cfg = 0;
1087cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mdx_cfg = 0;
10889a0bf528SMauro Carvalho Chehab 	u16 err_cfg = 0;
10899a0bf528SMauro Carvalho Chehab 
10909a0bf528SMauro Carvalho Chehab 	dprintk(1, ": mpeg %s, %s mode\n",
1091cd7a67a4SMauro Carvalho Chehab 		mpeg_enable ? "enable" : "disable",
1092cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel ? "parallel" : "serial");
10939a0bf528SMauro Carvalho Chehab 
10949a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
1095ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1096ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
10979a0bf528SMauro Carvalho Chehab 	if (status < 0)
10989a0bf528SMauro Carvalho Chehab 		goto error;
10999a0bf528SMauro Carvalho Chehab 
11009a0bf528SMauro Carvalho Chehab 	/*  MPEG TS pad configuration */
11018418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
11029a0bf528SMauro Carvalho Chehab 	if (status < 0)
11039a0bf528SMauro Carvalho Chehab 		goto error;
11049a0bf528SMauro Carvalho Chehab 
11055a7f7b79SMauro Carvalho Chehab 	if (!mpeg_enable) {
11069a0bf528SMauro Carvalho Chehab 		/*  Set MPEG TS pads to inputmode */
11079a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
11089a0bf528SMauro Carvalho Chehab 		if (status < 0)
11099a0bf528SMauro Carvalho Chehab 			goto error;
11109a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
11119a0bf528SMauro Carvalho Chehab 		if (status < 0)
11129a0bf528SMauro Carvalho Chehab 			goto error;
11139a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
11149a0bf528SMauro Carvalho Chehab 		if (status < 0)
11159a0bf528SMauro Carvalho Chehab 			goto error;
11169a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
11179a0bf528SMauro Carvalho Chehab 		if (status < 0)
11189a0bf528SMauro Carvalho Chehab 			goto error;
11199a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
11209a0bf528SMauro Carvalho Chehab 		if (status < 0)
11219a0bf528SMauro Carvalho Chehab 			goto error;
11229a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11239a0bf528SMauro Carvalho Chehab 		if (status < 0)
11249a0bf528SMauro Carvalho Chehab 			goto error;
11259a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11269a0bf528SMauro Carvalho Chehab 		if (status < 0)
11279a0bf528SMauro Carvalho Chehab 			goto error;
11289a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11299a0bf528SMauro Carvalho Chehab 		if (status < 0)
11309a0bf528SMauro Carvalho Chehab 			goto error;
11319a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11329a0bf528SMauro Carvalho Chehab 		if (status < 0)
11339a0bf528SMauro Carvalho Chehab 			goto error;
11349a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11359a0bf528SMauro Carvalho Chehab 		if (status < 0)
11369a0bf528SMauro Carvalho Chehab 			goto error;
11379a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11389a0bf528SMauro Carvalho Chehab 		if (status < 0)
11399a0bf528SMauro Carvalho Chehab 			goto error;
11409a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
11419a0bf528SMauro Carvalho Chehab 		if (status < 0)
11429a0bf528SMauro Carvalho Chehab 			goto error;
11439a0bf528SMauro Carvalho Chehab 	} else {
11449a0bf528SMauro Carvalho Chehab 		/* Enable MPEG output */
1145cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mdx_cfg =
1146cd7a67a4SMauro Carvalho Chehab 			((state->m_ts_data_strength <<
11479a0bf528SMauro Carvalho Chehab 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1148cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
11499a0bf528SMauro Carvalho Chehab 					SIO_PDR_MCLK_CFG_DRIVE__B) |
11509a0bf528SMauro Carvalho Chehab 					0x0003);
11519a0bf528SMauro Carvalho Chehab 
1152cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
11539a0bf528SMauro Carvalho Chehab 		if (status < 0)
11549a0bf528SMauro Carvalho Chehab 			goto error;
11559a0bf528SMauro Carvalho Chehab 
11569a0bf528SMauro Carvalho Chehab 		if (state->enable_merr_cfg)
1157cd7a67a4SMauro Carvalho Chehab 			err_cfg = sio_pdr_mdx_cfg;
11589a0bf528SMauro Carvalho Chehab 
11599a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
11609a0bf528SMauro Carvalho Chehab 		if (status < 0)
11619a0bf528SMauro Carvalho Chehab 			goto error;
11629a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
11639a0bf528SMauro Carvalho Chehab 		if (status < 0)
11649a0bf528SMauro Carvalho Chehab 			goto error;
11659a0bf528SMauro Carvalho Chehab 
11665a7f7b79SMauro Carvalho Chehab 		if (state->m_enable_parallel) {
116739c1cb2bSJonathan McCrohan 			/* parallel -> enable MD1 to MD7 */
1168ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A,
1169ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11709a0bf528SMauro Carvalho Chehab 			if (status < 0)
11719a0bf528SMauro Carvalho Chehab 				goto error;
1172ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A,
1173ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11749a0bf528SMauro Carvalho Chehab 			if (status < 0)
11759a0bf528SMauro Carvalho Chehab 				goto error;
1176ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A,
1177ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11789a0bf528SMauro Carvalho Chehab 			if (status < 0)
11799a0bf528SMauro Carvalho Chehab 				goto error;
1180ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A,
1181ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11829a0bf528SMauro Carvalho Chehab 			if (status < 0)
11839a0bf528SMauro Carvalho Chehab 				goto error;
1184ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A,
1185ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11869a0bf528SMauro Carvalho Chehab 			if (status < 0)
11879a0bf528SMauro Carvalho Chehab 				goto error;
1188ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A,
1189ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11909a0bf528SMauro Carvalho Chehab 			if (status < 0)
11919a0bf528SMauro Carvalho Chehab 				goto error;
1192ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A,
1193ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11949a0bf528SMauro Carvalho Chehab 			if (status < 0)
11959a0bf528SMauro Carvalho Chehab 				goto error;
11969a0bf528SMauro Carvalho Chehab 		} else {
1197cd7a67a4SMauro Carvalho Chehab 			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
11989a0bf528SMauro Carvalho Chehab 						SIO_PDR_MD0_CFG_DRIVE__B)
11999a0bf528SMauro Carvalho Chehab 					| 0x0003);
12009a0bf528SMauro Carvalho Chehab 			/* serial -> disable MD1 to MD7 */
12019a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
12029a0bf528SMauro Carvalho Chehab 			if (status < 0)
12039a0bf528SMauro Carvalho Chehab 				goto error;
12049a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
12059a0bf528SMauro Carvalho Chehab 			if (status < 0)
12069a0bf528SMauro Carvalho Chehab 				goto error;
12079a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
12089a0bf528SMauro Carvalho Chehab 			if (status < 0)
12099a0bf528SMauro Carvalho Chehab 				goto error;
12109a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
12119a0bf528SMauro Carvalho Chehab 			if (status < 0)
12129a0bf528SMauro Carvalho Chehab 				goto error;
12139a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
12149a0bf528SMauro Carvalho Chehab 			if (status < 0)
12159a0bf528SMauro Carvalho Chehab 				goto error;
12169a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
12179a0bf528SMauro Carvalho Chehab 			if (status < 0)
12189a0bf528SMauro Carvalho Chehab 				goto error;
12199a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12209a0bf528SMauro Carvalho Chehab 			if (status < 0)
12219a0bf528SMauro Carvalho Chehab 				goto error;
12229a0bf528SMauro Carvalho Chehab 		}
1223cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
12249a0bf528SMauro Carvalho Chehab 		if (status < 0)
12259a0bf528SMauro Carvalho Chehab 			goto error;
1226cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
12279a0bf528SMauro Carvalho Chehab 		if (status < 0)
12289a0bf528SMauro Carvalho Chehab 			goto error;
12299a0bf528SMauro Carvalho Chehab 	}
12309a0bf528SMauro Carvalho Chehab 	/*  Enable MB output over MPEG pads and ctl input */
12319a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
12329a0bf528SMauro Carvalho Chehab 	if (status < 0)
12339a0bf528SMauro Carvalho Chehab 		goto error;
12349a0bf528SMauro Carvalho Chehab 	/*  Write nomagic word to enable pdr reg write */
12359a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
12369a0bf528SMauro Carvalho Chehab error:
12379a0bf528SMauro Carvalho Chehab 	if (status < 0)
12383a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12399a0bf528SMauro Carvalho Chehab 	return status;
12409a0bf528SMauro Carvalho Chehab }
12419a0bf528SMauro Carvalho Chehab 
1242cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state)
12439a0bf528SMauro Carvalho Chehab {
12449a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12459a0bf528SMauro Carvalho Chehab 
1246cd7a67a4SMauro Carvalho Chehab 	return mpegts_configure_pins(state, false);
12479a0bf528SMauro Carvalho Chehab }
12489a0bf528SMauro Carvalho Chehab 
1249cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state,
1250cd7a67a4SMauro Carvalho Chehab 		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
12519a0bf528SMauro Carvalho Chehab {
1252cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
12539a0bf528SMauro Carvalho Chehab 	int status;
12549a0bf528SMauro Carvalho Chehab 	unsigned long end;
12559a0bf528SMauro Carvalho Chehab 
12569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12579a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
12589a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
12599a0bf528SMauro Carvalho Chehab 	if (status < 0)
12609a0bf528SMauro Carvalho Chehab 		goto error;
1261cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
12629a0bf528SMauro Carvalho Chehab 	if (status < 0)
12639a0bf528SMauro Carvalho Chehab 		goto error;
1264cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
12659a0bf528SMauro Carvalho Chehab 	if (status < 0)
12669a0bf528SMauro Carvalho Chehab 		goto error;
12679a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
12689a0bf528SMauro Carvalho Chehab 	if (status < 0)
12699a0bf528SMauro Carvalho Chehab 		goto error;
12709a0bf528SMauro Carvalho Chehab 
1271cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
12729a0bf528SMauro Carvalho Chehab 	do {
1273b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1274cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
12759a0bf528SMauro Carvalho Chehab 		if (status < 0)
12769a0bf528SMauro Carvalho Chehab 			goto error;
1277cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) &&
12789a0bf528SMauro Carvalho Chehab 			((time_is_after_jiffies(end))));
12799a0bf528SMauro Carvalho Chehab 
1280cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
12813a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
12829a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
12839a0bf528SMauro Carvalho Chehab 		goto error2;
12849a0bf528SMauro Carvalho Chehab 	}
12859a0bf528SMauro Carvalho Chehab error:
12869a0bf528SMauro Carvalho Chehab 	if (status < 0)
12873a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12889a0bf528SMauro Carvalho Chehab error2:
12899a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
12909a0bf528SMauro Carvalho Chehab 	return status;
12919a0bf528SMauro Carvalho Chehab }
12929a0bf528SMauro Carvalho Chehab 
12939a0bf528SMauro Carvalho Chehab 
1294cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state,
1295cd7a67a4SMauro Carvalho Chehab 			     const u8 p_mc_image[], u32 length)
12969a0bf528SMauro Carvalho Chehab {
1297cd7a67a4SMauro Carvalho Chehab 	const u8 *p_src = p_mc_image;
1298cd7a67a4SMauro Carvalho Chehab 	u32 address;
1299cd7a67a4SMauro Carvalho Chehab 	u16 n_blocks;
1300cd7a67a4SMauro Carvalho Chehab 	u16 block_size;
13019a0bf528SMauro Carvalho Chehab 	u32 offset = 0;
13029a0bf528SMauro Carvalho Chehab 	u32 i;
13039a0bf528SMauro Carvalho Chehab 	int status = 0;
13049a0bf528SMauro Carvalho Chehab 
13059a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13069a0bf528SMauro Carvalho Chehab 
13079a0bf528SMauro Carvalho Chehab 	/* down the drain (we don't care about MAGIC_WORD) */
13089a0bf528SMauro Carvalho Chehab #if 0
13099a0bf528SMauro Carvalho Chehab 	/* For future reference */
1310cd7a67a4SMauro Carvalho Chehab 	drain = (p_src[0] << 8) | p_src[1];
13119a0bf528SMauro Carvalho Chehab #endif
1312cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13139a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
1314cd7a67a4SMauro Carvalho Chehab 	n_blocks = (p_src[0] << 8) | p_src[1];
1315cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13169a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
13179a0bf528SMauro Carvalho Chehab 
1318cd7a67a4SMauro Carvalho Chehab 	for (i = 0; i < n_blocks; i += 1) {
1319cd7a67a4SMauro Carvalho Chehab 		address = (p_src[0] << 24) | (p_src[1] << 16) |
1320cd7a67a4SMauro Carvalho Chehab 		    (p_src[2] << 8) | p_src[3];
1321cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u32);
13229a0bf528SMauro Carvalho Chehab 		offset += sizeof(u32);
13239a0bf528SMauro Carvalho Chehab 
1324cd7a67a4SMauro Carvalho Chehab 		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1325cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13269a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13279a0bf528SMauro Carvalho Chehab 
13289a0bf528SMauro Carvalho Chehab #if 0
13299a0bf528SMauro Carvalho Chehab 		/* For future reference */
1330cd7a67a4SMauro Carvalho Chehab 		flags = (p_src[0] << 8) | p_src[1];
13319a0bf528SMauro Carvalho Chehab #endif
1332cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13339a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13349a0bf528SMauro Carvalho Chehab 
13359a0bf528SMauro Carvalho Chehab #if 0
13369a0bf528SMauro Carvalho Chehab 		/* For future reference */
1337cd7a67a4SMauro Carvalho Chehab 		block_crc = (p_src[0] << 8) | p_src[1];
13389a0bf528SMauro Carvalho Chehab #endif
1339cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13409a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13419a0bf528SMauro Carvalho Chehab 
1342cd7a67a4SMauro Carvalho Chehab 		if (offset + block_size > length) {
13433a4398f5SMauro Carvalho Chehab 			pr_err("Firmware is corrupted.\n");
13449a0bf528SMauro Carvalho Chehab 			return -EINVAL;
13459a0bf528SMauro Carvalho Chehab 		}
13469a0bf528SMauro Carvalho Chehab 
1347cd7a67a4SMauro Carvalho Chehab 		status = write_block(state, address, block_size, p_src);
13489a0bf528SMauro Carvalho Chehab 		if (status < 0) {
13493a4398f5SMauro Carvalho Chehab 			pr_err("Error %d while loading firmware\n", status);
13509a0bf528SMauro Carvalho Chehab 			break;
13519a0bf528SMauro Carvalho Chehab 		}
1352cd7a67a4SMauro Carvalho Chehab 		p_src += block_size;
1353cd7a67a4SMauro Carvalho Chehab 		offset += block_size;
13549a0bf528SMauro Carvalho Chehab 	}
13559a0bf528SMauro Carvalho Chehab 	return status;
13569a0bf528SMauro Carvalho Chehab }
13579a0bf528SMauro Carvalho Chehab 
1358cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
13599a0bf528SMauro Carvalho Chehab {
13609a0bf528SMauro Carvalho Chehab 	int status;
13619a0bf528SMauro Carvalho Chehab 	u16 data = 0;
1362cd7a67a4SMauro Carvalho Chehab 	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1363cd7a67a4SMauro Carvalho Chehab 	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
13649a0bf528SMauro Carvalho Chehab 	unsigned long end;
13659a0bf528SMauro Carvalho Chehab 
13669a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13679a0bf528SMauro Carvalho Chehab 
13685a7f7b79SMauro Carvalho Chehab 	if (!enable) {
1369cd7a67a4SMauro Carvalho Chehab 		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1370cd7a67a4SMauro Carvalho Chehab 		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
13719a0bf528SMauro Carvalho Chehab 	}
13729a0bf528SMauro Carvalho Chehab 
13739a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1374cd7a67a4SMauro Carvalho Chehab 	if (status >= 0 && data == desired_status) {
13759a0bf528SMauro Carvalho Chehab 		/* tokenring already has correct status */
13769a0bf528SMauro Carvalho Chehab 		return status;
13779a0bf528SMauro Carvalho Chehab 	}
13789a0bf528SMauro Carvalho Chehab 	/* Disable/enable dvbt tokenring bridge   */
1379cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
13809a0bf528SMauro Carvalho Chehab 
13819a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
13829a0bf528SMauro Carvalho Chehab 	do {
13839a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1384ab5060cdSMauro Carvalho Chehab 		if ((status >= 0 && data == desired_status)
1385ab5060cdSMauro Carvalho Chehab 		    || time_is_after_jiffies(end))
13869a0bf528SMauro Carvalho Chehab 			break;
1387b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
13889a0bf528SMauro Carvalho Chehab 	} while (1);
1389cd7a67a4SMauro Carvalho Chehab 	if (data != desired_status) {
13903a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
13919a0bf528SMauro Carvalho Chehab 		return -EINVAL;
13929a0bf528SMauro Carvalho Chehab 	}
13939a0bf528SMauro Carvalho Chehab 	return status;
13949a0bf528SMauro Carvalho Chehab }
13959a0bf528SMauro Carvalho Chehab 
1396cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state)
13979a0bf528SMauro Carvalho Chehab {
13989a0bf528SMauro Carvalho Chehab 	int status = 0;
1399cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
1400cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_ipr_mode = 0;
14019a0bf528SMauro Carvalho Chehab 
14029a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14039a0bf528SMauro Carvalho Chehab 
140439c1cb2bSJonathan McCrohan 	/* Graceful shutdown (byte boundaries) */
1405cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
14069a0bf528SMauro Carvalho Chehab 	if (status < 0)
14079a0bf528SMauro Carvalho Chehab 		goto error;
1408cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1409cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
14109a0bf528SMauro Carvalho Chehab 	if (status < 0)
14119a0bf528SMauro Carvalho Chehab 		goto error;
14129a0bf528SMauro Carvalho Chehab 
14139a0bf528SMauro Carvalho Chehab 	/* Suppress MCLK during absence of data */
1414cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
14159a0bf528SMauro Carvalho Chehab 	if (status < 0)
14169a0bf528SMauro Carvalho Chehab 		goto error;
1417cd7a67a4SMauro Carvalho Chehab 	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1418cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
14199a0bf528SMauro Carvalho Chehab 
14209a0bf528SMauro Carvalho Chehab error:
14219a0bf528SMauro Carvalho Chehab 	if (status < 0)
14223a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14239a0bf528SMauro Carvalho Chehab 
14249a0bf528SMauro Carvalho Chehab 	return status;
14259a0bf528SMauro Carvalho Chehab }
14269a0bf528SMauro Carvalho Chehab 
14279a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
1428cd7a67a4SMauro Carvalho Chehab 		       u16 cmd, u8 parameter_len,
1429cd7a67a4SMauro Carvalho Chehab 		       u16 *parameter, u8 result_len, u16 *result)
14309a0bf528SMauro Carvalho Chehab {
14319a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
14329a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
14339a0bf528SMauro Carvalho Chehab #endif
1434cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
14359a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
14369a0bf528SMauro Carvalho Chehab 	unsigned long end;
14379a0bf528SMauro Carvalho Chehab 	u8 buffer[34];
14389a0bf528SMauro Carvalho Chehab 	int cnt = 0, ii;
14399a0bf528SMauro Carvalho Chehab 	const char *p;
14409a0bf528SMauro Carvalho Chehab 	char errname[30];
14419a0bf528SMauro Carvalho Chehab 
14429a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14439a0bf528SMauro Carvalho Chehab 
1444cd7a67a4SMauro Carvalho Chehab 	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1445cd7a67a4SMauro Carvalho Chehab 	    ((result_len > 0) && (result == NULL))) {
14463a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14479a0bf528SMauro Carvalho Chehab 		return status;
14489a0bf528SMauro Carvalho Chehab 	}
14499a0bf528SMauro Carvalho Chehab 
14509a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
14519a0bf528SMauro Carvalho Chehab 
14529a0bf528SMauro Carvalho Chehab 	/* assume that the command register is ready
14539a0bf528SMauro Carvalho Chehab 		since it is checked afterwards */
1454daad52c8SMauro Carvalho Chehab 	if (parameter) {
1455cd7a67a4SMauro Carvalho Chehab 		for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
14569a0bf528SMauro Carvalho Chehab 			buffer[cnt++] = (parameter[ii] & 0xFF);
14579a0bf528SMauro Carvalho Chehab 			buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
14589a0bf528SMauro Carvalho Chehab 		}
1459daad52c8SMauro Carvalho Chehab 	}
14609a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = (cmd & 0xFF);
14619a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
14629a0bf528SMauro Carvalho Chehab 
14639a0bf528SMauro Carvalho Chehab 	write_block(state, SCU_RAM_PARAM_0__A -
1464cd7a67a4SMauro Carvalho Chehab 			(parameter_len - 1), cnt, buffer);
14659a0bf528SMauro Carvalho Chehab 	/* Wait until SCU has processed command */
14669a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
14679a0bf528SMauro Carvalho Chehab 	do {
1468b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1469cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
14709a0bf528SMauro Carvalho Chehab 		if (status < 0)
14719a0bf528SMauro Carvalho Chehab 			goto error;
1472cd7a67a4SMauro Carvalho Chehab 	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1473cd7a67a4SMauro Carvalho Chehab 	if (cur_cmd != DRX_SCU_READY) {
14743a4398f5SMauro Carvalho Chehab 		pr_err("SCU not ready\n");
14759a0bf528SMauro Carvalho Chehab 		status = -EIO;
14769a0bf528SMauro Carvalho Chehab 		goto error2;
14779a0bf528SMauro Carvalho Chehab 	}
14789a0bf528SMauro Carvalho Chehab 	/* read results */
1479cd7a67a4SMauro Carvalho Chehab 	if ((result_len > 0) && (result != NULL)) {
14809a0bf528SMauro Carvalho Chehab 		s16 err;
14819a0bf528SMauro Carvalho Chehab 		int ii;
14829a0bf528SMauro Carvalho Chehab 
1483cd7a67a4SMauro Carvalho Chehab 		for (ii = result_len - 1; ii >= 0; ii -= 1) {
1484ab5060cdSMauro Carvalho Chehab 			status = read16(state, SCU_RAM_PARAM_0__A - ii,
1485ab5060cdSMauro Carvalho Chehab 					&result[ii]);
14869a0bf528SMauro Carvalho Chehab 			if (status < 0)
14879a0bf528SMauro Carvalho Chehab 				goto error;
14889a0bf528SMauro Carvalho Chehab 		}
14899a0bf528SMauro Carvalho Chehab 
14909a0bf528SMauro Carvalho Chehab 		/* Check if an error was reported by SCU */
14919a0bf528SMauro Carvalho Chehab 		err = (s16)result[0];
14929a0bf528SMauro Carvalho Chehab 		if (err >= 0)
14939a0bf528SMauro Carvalho Chehab 			goto error;
14949a0bf528SMauro Carvalho Chehab 
14959a0bf528SMauro Carvalho Chehab 		/* check for the known error codes */
14969a0bf528SMauro Carvalho Chehab 		switch (err) {
14979a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKCMD:
14989a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKCMD";
14999a0bf528SMauro Carvalho Chehab 			break;
15009a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKSTD:
15019a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKSTD";
15029a0bf528SMauro Carvalho Chehab 			break;
15039a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_SIZE:
15049a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_SIZE";
15059a0bf528SMauro Carvalho Chehab 			break;
15069a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_INVPAR:
15079a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_INVPAR";
15089a0bf528SMauro Carvalho Chehab 			break;
15099a0bf528SMauro Carvalho Chehab 		default: /* Other negative values are errors */
15109a0bf528SMauro Carvalho Chehab 			sprintf(errname, "ERROR: %d\n", err);
15119a0bf528SMauro Carvalho Chehab 			p = errname;
15129a0bf528SMauro Carvalho Chehab 		}
15133a4398f5SMauro Carvalho Chehab 		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
15149a0bf528SMauro Carvalho Chehab 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
15159a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
15169a0bf528SMauro Carvalho Chehab 		goto error2;
15179a0bf528SMauro Carvalho Chehab 	}
15189a0bf528SMauro Carvalho Chehab 
15199a0bf528SMauro Carvalho Chehab error:
15209a0bf528SMauro Carvalho Chehab 	if (status < 0)
15213a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15229a0bf528SMauro Carvalho Chehab error2:
15239a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
15249a0bf528SMauro Carvalho Chehab 	return status;
15259a0bf528SMauro Carvalho Chehab }
15269a0bf528SMauro Carvalho Chehab 
1527cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active)
15289a0bf528SMauro Carvalho Chehab {
15299a0bf528SMauro Carvalho Chehab 	u16 data = 0;
15309a0bf528SMauro Carvalho Chehab 	int status;
15319a0bf528SMauro Carvalho Chehab 
15329a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15339a0bf528SMauro Carvalho Chehab 
15349a0bf528SMauro Carvalho Chehab 	/* Configure IQM */
15359a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_STDBY__A, &data);
15369a0bf528SMauro Carvalho Chehab 	if (status < 0)
15379a0bf528SMauro Carvalho Chehab 		goto error;
15389a0bf528SMauro Carvalho Chehab 
15399a0bf528SMauro Carvalho Chehab 	if (!active) {
15409a0bf528SMauro Carvalho Chehab 		data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
15419a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_AMP_STANDBY
15429a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_PD_STANDBY
15439a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
15449a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
15459a0bf528SMauro Carvalho Chehab 	} else {
15469a0bf528SMauro Carvalho Chehab 		data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
15479a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
15489a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_PD_STANDBY)
15499a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
15509a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
15519a0bf528SMauro Carvalho Chehab 			);
15529a0bf528SMauro Carvalho Chehab 	}
15539a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_STDBY__A, data);
15549a0bf528SMauro Carvalho Chehab 
15559a0bf528SMauro Carvalho Chehab error:
15569a0bf528SMauro Carvalho Chehab 	if (status < 0)
15573a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15589a0bf528SMauro Carvalho Chehab 	return status;
15599a0bf528SMauro Carvalho Chehab }
15609a0bf528SMauro Carvalho Chehab 
1561cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
15629a0bf528SMauro Carvalho Chehab {
15639a0bf528SMauro Carvalho Chehab 	int status = 0;
1564cd7a67a4SMauro Carvalho Chehab 	u16 sio_cc_pwd_mode = 0;
15659a0bf528SMauro Carvalho Chehab 
15669a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15679a0bf528SMauro Carvalho Chehab 
15689a0bf528SMauro Carvalho Chehab 	/* Check arguments */
15699a0bf528SMauro Carvalho Chehab 	if (mode == NULL)
15709a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15719a0bf528SMauro Carvalho Chehab 
15729a0bf528SMauro Carvalho Chehab 	switch (*mode) {
15739a0bf528SMauro Carvalho Chehab 	case DRX_POWER_UP:
1574cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
15759a0bf528SMauro Carvalho Chehab 		break;
15769a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_OFDM:
1577cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
15789a0bf528SMauro Carvalho Chehab 		break;
15799a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_CORE:
1580cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
15819a0bf528SMauro Carvalho Chehab 		break;
15829a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_PLL:
1583cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
15849a0bf528SMauro Carvalho Chehab 		break;
15859a0bf528SMauro Carvalho Chehab 	case DRX_POWER_DOWN:
1586cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
15879a0bf528SMauro Carvalho Chehab 		break;
15889a0bf528SMauro Carvalho Chehab 	default:
15899a0bf528SMauro Carvalho Chehab 		/* Unknow sleep mode */
15909a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15919a0bf528SMauro Carvalho Chehab 	}
15929a0bf528SMauro Carvalho Chehab 
15939a0bf528SMauro Carvalho Chehab 	/* If already in requested power mode, do nothing */
1594cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode == *mode)
15959a0bf528SMauro Carvalho Chehab 		return 0;
15969a0bf528SMauro Carvalho Chehab 
15979a0bf528SMauro Carvalho Chehab 	/* For next steps make sure to start from DRX_POWER_UP mode */
1598cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode != DRX_POWER_UP) {
1599cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
16009a0bf528SMauro Carvalho Chehab 		if (status < 0)
16019a0bf528SMauro Carvalho Chehab 			goto error;
1602cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, true);
16039a0bf528SMauro Carvalho Chehab 		if (status < 0)
16049a0bf528SMauro Carvalho Chehab 			goto error;
16059a0bf528SMauro Carvalho Chehab 	}
16069a0bf528SMauro Carvalho Chehab 
16079a0bf528SMauro Carvalho Chehab 	if (*mode == DRX_POWER_UP) {
16082c149601SMasahiro Yamada 		/* Restore analog & pin configuration */
16099a0bf528SMauro Carvalho Chehab 	} else {
16109a0bf528SMauro Carvalho Chehab 		/* Power down to requested mode */
16119a0bf528SMauro Carvalho Chehab 		/* Backup some register settings */
16129a0bf528SMauro Carvalho Chehab 		/* Set pins with possible pull-ups connected
16139a0bf528SMauro Carvalho Chehab 		   to them in input mode */
16149a0bf528SMauro Carvalho Chehab 		/* Analog power down */
16159a0bf528SMauro Carvalho Chehab 		/* ADC power down */
16169a0bf528SMauro Carvalho Chehab 		/* Power down device */
16179a0bf528SMauro Carvalho Chehab 		/* stop all comm_exec */
16189a0bf528SMauro Carvalho Chehab 		/* Stop and power down previous standard */
1619cd7a67a4SMauro Carvalho Chehab 		switch (state->m_operation_mode) {
16209a0bf528SMauro Carvalho Chehab 		case OM_DVBT:
1621cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16229a0bf528SMauro Carvalho Chehab 			if (status < 0)
16239a0bf528SMauro Carvalho Chehab 				goto error;
1624cd7a67a4SMauro Carvalho Chehab 			status = power_down_dvbt(state, false);
16259a0bf528SMauro Carvalho Chehab 			if (status < 0)
16269a0bf528SMauro Carvalho Chehab 				goto error;
16279a0bf528SMauro Carvalho Chehab 			break;
16289a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_A:
16299a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_C:
1630cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16319a0bf528SMauro Carvalho Chehab 			if (status < 0)
16329a0bf528SMauro Carvalho Chehab 				goto error;
1633cd7a67a4SMauro Carvalho Chehab 			status = power_down_qam(state);
16349a0bf528SMauro Carvalho Chehab 			if (status < 0)
16359a0bf528SMauro Carvalho Chehab 				goto error;
16369a0bf528SMauro Carvalho Chehab 			break;
16379a0bf528SMauro Carvalho Chehab 		default:
16389a0bf528SMauro Carvalho Chehab 			break;
16399a0bf528SMauro Carvalho Chehab 		}
1640cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, false);
16419a0bf528SMauro Carvalho Chehab 		if (status < 0)
16429a0bf528SMauro Carvalho Chehab 			goto error;
1643cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
16449a0bf528SMauro Carvalho Chehab 		if (status < 0)
16459a0bf528SMauro Carvalho Chehab 			goto error;
16469a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
16479a0bf528SMauro Carvalho Chehab 		if (status < 0)
16489a0bf528SMauro Carvalho Chehab 			goto error;
16499a0bf528SMauro Carvalho Chehab 
16509a0bf528SMauro Carvalho Chehab 		if (*mode != DRXK_POWER_DOWN_OFDM) {
1651cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_ctrl |=
16529a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1653cd7a67a4SMauro Carvalho Chehab 			status = hi_cfg_command(state);
16549a0bf528SMauro Carvalho Chehab 			if (status < 0)
16559a0bf528SMauro Carvalho Chehab 				goto error;
16569a0bf528SMauro Carvalho Chehab 		}
16579a0bf528SMauro Carvalho Chehab 	}
1658cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = *mode;
16599a0bf528SMauro Carvalho Chehab 
16609a0bf528SMauro Carvalho Chehab error:
16619a0bf528SMauro Carvalho Chehab 	if (status < 0)
16623a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
16639a0bf528SMauro Carvalho Chehab 
16649a0bf528SMauro Carvalho Chehab 	return status;
16659a0bf528SMauro Carvalho Chehab }
16669a0bf528SMauro Carvalho Chehab 
1667cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
16689a0bf528SMauro Carvalho Chehab {
1669cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1670cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
16719a0bf528SMauro Carvalho Chehab 	u16 data = 0;
16729a0bf528SMauro Carvalho Chehab 	int status;
16739a0bf528SMauro Carvalho Chehab 
16749a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
16759a0bf528SMauro Carvalho Chehab 
16769a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
16779a0bf528SMauro Carvalho Chehab 	if (status < 0)
16789a0bf528SMauro Carvalho Chehab 		goto error;
16799a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
16809a0bf528SMauro Carvalho Chehab 		/* Send OFDM stop command */
1681ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1682ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1683ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1684ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
16859a0bf528SMauro Carvalho Chehab 		if (status < 0)
16869a0bf528SMauro Carvalho Chehab 			goto error;
16879a0bf528SMauro Carvalho Chehab 		/* Send OFDM reset command */
1688ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1689ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1690ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1691ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
16929a0bf528SMauro Carvalho Chehab 		if (status < 0)
16939a0bf528SMauro Carvalho Chehab 			goto error;
16949a0bf528SMauro Carvalho Chehab 	}
16959a0bf528SMauro Carvalho Chehab 
16969a0bf528SMauro Carvalho Chehab 	/* Reset datapath for OFDM, processors first */
16979a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
16989a0bf528SMauro Carvalho Chehab 	if (status < 0)
16999a0bf528SMauro Carvalho Chehab 		goto error;
17009a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
17019a0bf528SMauro Carvalho Chehab 	if (status < 0)
17029a0bf528SMauro Carvalho Chehab 		goto error;
17039a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
17049a0bf528SMauro Carvalho Chehab 	if (status < 0)
17059a0bf528SMauro Carvalho Chehab 		goto error;
17069a0bf528SMauro Carvalho Chehab 
17079a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
1708cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
17099a0bf528SMauro Carvalho Chehab 	if (status < 0)
17109a0bf528SMauro Carvalho Chehab 		goto error;
17119a0bf528SMauro Carvalho Chehab 
17129a0bf528SMauro Carvalho Chehab 	/* powerdown to OFDM mode          */
1713cd7a67a4SMauro Carvalho Chehab 	if (set_power_mode) {
1714cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
17159a0bf528SMauro Carvalho Chehab 		if (status < 0)
17169a0bf528SMauro Carvalho Chehab 			goto error;
17179a0bf528SMauro Carvalho Chehab 	}
17189a0bf528SMauro Carvalho Chehab error:
17199a0bf528SMauro Carvalho Chehab 	if (status < 0)
17203a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
17219a0bf528SMauro Carvalho Chehab 	return status;
17229a0bf528SMauro Carvalho Chehab }
17239a0bf528SMauro Carvalho Chehab 
1724cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state,
1725cd7a67a4SMauro Carvalho Chehab 			    enum operation_mode o_mode)
17269a0bf528SMauro Carvalho Chehab {
17279a0bf528SMauro Carvalho Chehab 	int status = 0;
17289a0bf528SMauro Carvalho Chehab 
17299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17309a0bf528SMauro Carvalho Chehab 	/*
17319a0bf528SMauro Carvalho Chehab 	   Stop and power down previous standard
17329a0bf528SMauro Carvalho Chehab 	   TODO investigate total power down instead of partial
17339a0bf528SMauro Carvalho Chehab 	   power down depending on "previous" standard.
17349a0bf528SMauro Carvalho Chehab 	 */
17359a0bf528SMauro Carvalho Chehab 
17369a0bf528SMauro Carvalho Chehab 	/* disable HW lock indicator */
1737ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1738ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
17399a0bf528SMauro Carvalho Chehab 	if (status < 0)
17409a0bf528SMauro Carvalho Chehab 		goto error;
17419a0bf528SMauro Carvalho Chehab 
17429a0bf528SMauro Carvalho Chehab 	/* Device is already at the required mode */
1743cd7a67a4SMauro Carvalho Chehab 	if (state->m_operation_mode == o_mode)
17449a0bf528SMauro Carvalho Chehab 		return 0;
17459a0bf528SMauro Carvalho Chehab 
1746cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
17479a0bf528SMauro Carvalho Chehab 		/* OM_NONE was added for start up */
17489a0bf528SMauro Carvalho Chehab 	case OM_NONE:
17499a0bf528SMauro Carvalho Chehab 		break;
17509a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1751cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17529a0bf528SMauro Carvalho Chehab 		if (status < 0)
17539a0bf528SMauro Carvalho Chehab 			goto error;
1754cd7a67a4SMauro Carvalho Chehab 		status = power_down_dvbt(state, true);
17559a0bf528SMauro Carvalho Chehab 		if (status < 0)
17569a0bf528SMauro Carvalho Chehab 			goto error;
1757cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17589a0bf528SMauro Carvalho Chehab 		break;
1759df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
17609a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1761cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17629a0bf528SMauro Carvalho Chehab 		if (status < 0)
17639a0bf528SMauro Carvalho Chehab 			goto error;
1764cd7a67a4SMauro Carvalho Chehab 		status = power_down_qam(state);
17659a0bf528SMauro Carvalho Chehab 		if (status < 0)
17669a0bf528SMauro Carvalho Chehab 			goto error;
1767cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17689a0bf528SMauro Carvalho Chehab 		break;
17699a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17709a0bf528SMauro Carvalho Chehab 	default:
17719a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17729a0bf528SMauro Carvalho Chehab 		goto error;
17739a0bf528SMauro Carvalho Chehab 	}
17749a0bf528SMauro Carvalho Chehab 
17759a0bf528SMauro Carvalho Chehab 	/*
17769a0bf528SMauro Carvalho Chehab 		Power up new standard
17779a0bf528SMauro Carvalho Chehab 		*/
1778cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
17799a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
17809a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-T\n");
1781cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1782cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt_standard(state, o_mode);
17839a0bf528SMauro Carvalho Chehab 		if (status < 0)
17849a0bf528SMauro Carvalho Chehab 			goto error;
17859a0bf528SMauro Carvalho Chehab 		break;
1786df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
17879a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
17889a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-C Annex %c\n",
1789cd7a67a4SMauro Carvalho Chehab 			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1790cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1791cd7a67a4SMauro Carvalho Chehab 		status = set_qam_standard(state, o_mode);
17929a0bf528SMauro Carvalho Chehab 		if (status < 0)
17939a0bf528SMauro Carvalho Chehab 			goto error;
17949a0bf528SMauro Carvalho Chehab 		break;
17959a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17969a0bf528SMauro Carvalho Chehab 	default:
17979a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17989a0bf528SMauro Carvalho Chehab 	}
17999a0bf528SMauro Carvalho Chehab error:
18009a0bf528SMauro Carvalho Chehab 	if (status < 0)
18013a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18029a0bf528SMauro Carvalho Chehab 	return status;
18039a0bf528SMauro Carvalho Chehab }
18049a0bf528SMauro Carvalho Chehab 
1805cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq,
1806cd7a67a4SMauro Carvalho Chehab 		 s32 intermediate_frequency)
18079a0bf528SMauro Carvalho Chehab {
18089a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18099a0bf528SMauro Carvalho Chehab 
1810cd7a67a4SMauro Carvalho Chehab 	u16 i_freqk_hz;
1811cd7a67a4SMauro Carvalho Chehab 	s32 offsetk_hz = offset_freq / 1000;
18129a0bf528SMauro Carvalho Chehab 
18139a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
1814cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state != DRXK_STOPPED &&
1815cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state != DRXK_DTV_STARTED)
18169a0bf528SMauro Carvalho Chehab 		goto error;
18179a0bf528SMauro Carvalho Chehab 
1818cd7a67a4SMauro Carvalho Chehab 	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
18199a0bf528SMauro Carvalho Chehab 
1820cd7a67a4SMauro Carvalho Chehab 	if (intermediate_frequency < 0) {
1821cd7a67a4SMauro Carvalho Chehab 		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1822cd7a67a4SMauro Carvalho Chehab 		intermediate_frequency = -intermediate_frequency;
18239a0bf528SMauro Carvalho Chehab 	}
18249a0bf528SMauro Carvalho Chehab 
1825cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18269a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18279a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1828cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1829cd7a67a4SMauro Carvalho Chehab 		status = set_qam(state, i_freqk_hz, offsetk_hz);
18309a0bf528SMauro Carvalho Chehab 		if (status < 0)
18319a0bf528SMauro Carvalho Chehab 			goto error;
1832cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18339a0bf528SMauro Carvalho Chehab 		break;
18349a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1835cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1836cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
18379a0bf528SMauro Carvalho Chehab 		if (status < 0)
18389a0bf528SMauro Carvalho Chehab 			goto error;
1839cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
18409a0bf528SMauro Carvalho Chehab 		if (status < 0)
18419a0bf528SMauro Carvalho Chehab 			goto error;
1842cd7a67a4SMauro Carvalho Chehab 		status = dvbt_start(state);
18439a0bf528SMauro Carvalho Chehab 		if (status < 0)
18449a0bf528SMauro Carvalho Chehab 			goto error;
1845cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18469a0bf528SMauro Carvalho Chehab 		break;
18479a0bf528SMauro Carvalho Chehab 	default:
18489a0bf528SMauro Carvalho Chehab 		break;
18499a0bf528SMauro Carvalho Chehab 	}
18509a0bf528SMauro Carvalho Chehab error:
18519a0bf528SMauro Carvalho Chehab 	if (status < 0)
18523a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18539a0bf528SMauro Carvalho Chehab 	return status;
18549a0bf528SMauro Carvalho Chehab }
18559a0bf528SMauro Carvalho Chehab 
1856cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state)
18579a0bf528SMauro Carvalho Chehab {
18589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18599a0bf528SMauro Carvalho Chehab 
1860cd7a67a4SMauro Carvalho Chehab 	mpegts_stop(state);
18619a0bf528SMauro Carvalho Chehab 	return 0;
18629a0bf528SMauro Carvalho Chehab }
18639a0bf528SMauro Carvalho Chehab 
1864cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
18659a0bf528SMauro Carvalho Chehab {
18669a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18679a0bf528SMauro Carvalho Chehab 
18689a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18699a0bf528SMauro Carvalho Chehab 
1870cd7a67a4SMauro Carvalho Chehab 	if (p_lock_status == NULL)
18719a0bf528SMauro Carvalho Chehab 		goto error;
18729a0bf528SMauro Carvalho Chehab 
1873cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
18749a0bf528SMauro Carvalho Chehab 
18759a0bf528SMauro Carvalho Chehab 	/* define the SCU command code */
1876cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18779a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18789a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18799a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1880cd7a67a4SMauro Carvalho Chehab 		status = get_qam_lock_status(state, p_lock_status);
18819a0bf528SMauro Carvalho Chehab 		break;
18829a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1883cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_lock_status(state, p_lock_status);
18849a0bf528SMauro Carvalho Chehab 		break;
18859a0bf528SMauro Carvalho Chehab 	default:
1886b73bb2abSDaniel Scheller 		pr_debug("Unsupported operation mode %d in %s\n",
1887b73bb2abSDaniel Scheller 			state->m_operation_mode, __func__);
1888b73bb2abSDaniel Scheller 		return 0;
18899a0bf528SMauro Carvalho Chehab 	}
18909a0bf528SMauro Carvalho Chehab error:
18919a0bf528SMauro Carvalho Chehab 	if (status < 0)
18923a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18939a0bf528SMauro Carvalho Chehab 	return status;
18949a0bf528SMauro Carvalho Chehab }
18959a0bf528SMauro Carvalho Chehab 
1896cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state)
18979a0bf528SMauro Carvalho Chehab {
18989a0bf528SMauro Carvalho Chehab 	int status;
18999a0bf528SMauro Carvalho Chehab 
1900cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
19019a0bf528SMauro Carvalho Chehab 
19029a0bf528SMauro Carvalho Chehab 	/* Allow OC to sync again */
1903cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
19049a0bf528SMauro Carvalho Chehab 	if (status < 0)
19059a0bf528SMauro Carvalho Chehab 		goto error;
1906cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1907cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
19089a0bf528SMauro Carvalho Chehab 	if (status < 0)
19099a0bf528SMauro Carvalho Chehab 		goto error;
19109a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
19119a0bf528SMauro Carvalho Chehab error:
19129a0bf528SMauro Carvalho Chehab 	if (status < 0)
19133a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19149a0bf528SMauro Carvalho Chehab 	return status;
19159a0bf528SMauro Carvalho Chehab }
19169a0bf528SMauro Carvalho Chehab 
1917cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state)
19189a0bf528SMauro Carvalho Chehab {
19199a0bf528SMauro Carvalho Chehab 	int status;
19209a0bf528SMauro Carvalho Chehab 
19219a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19229a0bf528SMauro Carvalho Chehab 
19239a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
19249a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
19259a0bf528SMauro Carvalho Chehab 	if (status < 0)
19269a0bf528SMauro Carvalho Chehab 		goto error;
19279a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
19289a0bf528SMauro Carvalho Chehab 	if (status < 0)
19299a0bf528SMauro Carvalho Chehab 		goto error;
19309a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
19319a0bf528SMauro Carvalho Chehab 	if (status < 0)
19329a0bf528SMauro Carvalho Chehab 		goto error;
19339a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
19349a0bf528SMauro Carvalho Chehab 	if (status < 0)
19359a0bf528SMauro Carvalho Chehab 		goto error;
19369a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
19379a0bf528SMauro Carvalho Chehab 	if (status < 0)
19389a0bf528SMauro Carvalho Chehab 		goto error;
19399a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
19409a0bf528SMauro Carvalho Chehab 	if (status < 0)
19419a0bf528SMauro Carvalho Chehab 		goto error;
19429a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
19439a0bf528SMauro Carvalho Chehab 	if (status < 0)
19449a0bf528SMauro Carvalho Chehab 		goto error;
19459a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
19469a0bf528SMauro Carvalho Chehab 	if (status < 0)
19479a0bf528SMauro Carvalho Chehab 		goto error;
19489a0bf528SMauro Carvalho Chehab 
19499a0bf528SMauro Carvalho Chehab 	/* Additional configuration */
19509a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_OCR_INVERT__A, 0);
19519a0bf528SMauro Carvalho Chehab 	if (status < 0)
19529a0bf528SMauro Carvalho Chehab 		goto error;
19539a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_LWM__A, 2);
19549a0bf528SMauro Carvalho Chehab 	if (status < 0)
19559a0bf528SMauro Carvalho Chehab 		goto error;
19569a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
19579a0bf528SMauro Carvalho Chehab error:
19589a0bf528SMauro Carvalho Chehab 	if (status < 0)
19593a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19609a0bf528SMauro Carvalho Chehab 
19619a0bf528SMauro Carvalho Chehab 	return status;
19629a0bf528SMauro Carvalho Chehab }
19639a0bf528SMauro Carvalho Chehab 
1964cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state,
1965cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
19669a0bf528SMauro Carvalho Chehab {
19679a0bf528SMauro Carvalho Chehab 	int status;
19689a0bf528SMauro Carvalho Chehab 
1969cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
1970cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
1971cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1972cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1973cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
1974cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
1975cd7a67a4SMauro Carvalho Chehab 	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
1976cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_mode = 0;
1977cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_int_upd_rate = 0;
1978cd7a67a4SMauro Carvalho Chehab 	u32 max_bit_rate = 0;
1979cd7a67a4SMauro Carvalho Chehab 	bool static_clk = false;
19809a0bf528SMauro Carvalho Chehab 
19819a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19829a0bf528SMauro Carvalho Chehab 
19839a0bf528SMauro Carvalho Chehab 	/* Check insertion of the Reed-Solomon parity bytes */
1984cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
19859a0bf528SMauro Carvalho Chehab 	if (status < 0)
19869a0bf528SMauro Carvalho Chehab 		goto error;
1987cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
19889a0bf528SMauro Carvalho Chehab 	if (status < 0)
19899a0bf528SMauro Carvalho Chehab 		goto error;
1990cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
1991cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
19925a7f7b79SMauro Carvalho Chehab 	if (state->m_insert_rs_byte) {
19939a0bf528SMauro Carvalho Chehab 		/* enable parity symbol forward */
1994cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
19959a0bf528SMauro Carvalho Chehab 		/* MVAL disable during parity bytes */
1996cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
19979a0bf528SMauro Carvalho Chehab 		/* TS burst length to 204 */
1998cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_burst_len = 204;
19999a0bf528SMauro Carvalho Chehab 	}
20009a0bf528SMauro Carvalho Chehab 
200139c1cb2bSJonathan McCrohan 	/* Check serial or parallel output */
2002cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
20035a7f7b79SMauro Carvalho Chehab 	if (!state->m_enable_parallel) {
20049a0bf528SMauro Carvalho Chehab 		/* MPEG data output is serial -> set ipr_mode[0] */
2005cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
20069a0bf528SMauro Carvalho Chehab 	}
20079a0bf528SMauro Carvalho Chehab 
2008cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
20099a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2010cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbt_bitrate;
2011cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 3;
2012cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xC00000;
2013cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbt_static_clk;
20149a0bf528SMauro Carvalho Chehab 		break;
2015df561f66SGustavo A. R. Silva 	case OM_QAM_ITU_A:
20169a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2017cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 0x0004;
2018cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
2019cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbc_bitrate;
2020cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbc_static_clk;
20219a0bf528SMauro Carvalho Chehab 		break;
20229a0bf528SMauro Carvalho Chehab 	default:
20239a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
20249a0bf528SMauro Carvalho Chehab 	}		/* switch (standard) */
20259a0bf528SMauro Carvalho Chehab 	if (status < 0)
20269a0bf528SMauro Carvalho Chehab 		goto error;
20279a0bf528SMauro Carvalho Chehab 
20289a0bf528SMauro Carvalho Chehab 	/* Configure DTO's */
2029cd7a67a4SMauro Carvalho Chehab 	if (static_clk) {
2030cd7a67a4SMauro Carvalho Chehab 		u32 bit_rate = 0;
20319a0bf528SMauro Carvalho Chehab 
20329a0bf528SMauro Carvalho Chehab 		/* Rational DTO for MCLK source (static MCLK rate),
20339a0bf528SMauro Carvalho Chehab 			Dynamic DTO for optimal grouping
20349a0bf528SMauro Carvalho Chehab 			(avoid intra-packet gaps),
20359a0bf528SMauro Carvalho Chehab 			DTO offset enable to sync TS burst with MSTRT */
2036cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
20379a0bf528SMauro Carvalho Chehab 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2038cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
20399a0bf528SMauro Carvalho Chehab 				FEC_OC_FCT_MODE_VIRT_ENA__M);
20409a0bf528SMauro Carvalho Chehab 
20419a0bf528SMauro Carvalho Chehab 		/* Check user defined bitrate */
2042cd7a67a4SMauro Carvalho Chehab 		bit_rate = max_bit_rate;
2043cd7a67a4SMauro Carvalho Chehab 		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
2044cd7a67a4SMauro Carvalho Chehab 			bit_rate = 75900000UL;
20459a0bf528SMauro Carvalho Chehab 		}
20469a0bf528SMauro Carvalho Chehab 		/* Rational DTO period:
20479a0bf528SMauro Carvalho Chehab 			dto_period = (Fsys / bitrate) - 2
20489a0bf528SMauro Carvalho Chehab 
2049cd7a67a4SMauro Carvalho Chehab 			result should be floored,
20509a0bf528SMauro Carvalho Chehab 			to make sure >= requested bitrate
20519a0bf528SMauro Carvalho Chehab 			*/
2052cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2053cd7a67a4SMauro Carvalho Chehab 						* 1000) / bit_rate);
2054cd7a67a4SMauro Carvalho Chehab 		if (fec_oc_dto_period <= 2)
2055cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period = 0;
20569a0bf528SMauro Carvalho Chehab 		else
2057cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period -= 2;
2058cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 8;
20599a0bf528SMauro Carvalho Chehab 	} else {
2060cd7a67a4SMauro Carvalho Chehab 		/* (commonAttr->static_clk == false) => dynamic mode */
2061cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2062cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2063cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 5;
20649a0bf528SMauro Carvalho Chehab 	}
20659a0bf528SMauro Carvalho Chehab 
20669a0bf528SMauro Carvalho Chehab 	/* Write appropriate registers with requested configuration */
2067cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
20689a0bf528SMauro Carvalho Chehab 	if (status < 0)
20699a0bf528SMauro Carvalho Chehab 		goto error;
2070cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
20719a0bf528SMauro Carvalho Chehab 	if (status < 0)
20729a0bf528SMauro Carvalho Chehab 		goto error;
2073cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
20749a0bf528SMauro Carvalho Chehab 	if (status < 0)
20759a0bf528SMauro Carvalho Chehab 		goto error;
2076cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
20779a0bf528SMauro Carvalho Chehab 	if (status < 0)
20789a0bf528SMauro Carvalho Chehab 		goto error;
2079cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
20809a0bf528SMauro Carvalho Chehab 	if (status < 0)
20819a0bf528SMauro Carvalho Chehab 		goto error;
2082cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
20839a0bf528SMauro Carvalho Chehab 	if (status < 0)
20849a0bf528SMauro Carvalho Chehab 		goto error;
20859a0bf528SMauro Carvalho Chehab 
20869a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
2087cd7a67a4SMauro Carvalho Chehab 	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
20889a0bf528SMauro Carvalho Chehab 	if (status < 0)
20899a0bf528SMauro Carvalho Chehab 		goto error;
2090ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2091ab5060cdSMauro Carvalho Chehab 			 fec_oc_tmd_int_upd_rate);
20929a0bf528SMauro Carvalho Chehab 	if (status < 0)
20939a0bf528SMauro Carvalho Chehab 		goto error;
2094cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
20959a0bf528SMauro Carvalho Chehab error:
20969a0bf528SMauro Carvalho Chehab 	if (status < 0)
20973a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
20989a0bf528SMauro Carvalho Chehab 	return status;
20999a0bf528SMauro Carvalho Chehab }
21009a0bf528SMauro Carvalho Chehab 
2101cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state)
21029a0bf528SMauro Carvalho Chehab {
2103cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_invert = 0;
21049a0bf528SMauro Carvalho Chehab 
21059a0bf528SMauro Carvalho Chehab 	/* Data mask for the output data byte */
2106cd7a67a4SMauro Carvalho Chehab 	u16 invert_data_mask =
21079a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
21089a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
21099a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
21109a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
21119a0bf528SMauro Carvalho Chehab 
21129a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21139a0bf528SMauro Carvalho Chehab 
21149a0bf528SMauro Carvalho Chehab 	/* Control selective inversion of output bits */
2115cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
21165a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_data)
2117cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= invert_data_mask;
2118cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
21195a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_err)
2120cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2121cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
21225a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_str)
2123cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2124cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
21255a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_val)
2126cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2127cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
21285a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_clk)
2129cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
21309a0bf528SMauro Carvalho Chehab 
2131cd7a67a4SMauro Carvalho Chehab 	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
21329a0bf528SMauro Carvalho Chehab }
21339a0bf528SMauro Carvalho Chehab 
21349a0bf528SMauro Carvalho Chehab #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
21359a0bf528SMauro Carvalho Chehab 
2136cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state,
2137cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
21389a0bf528SMauro Carvalho Chehab {
21399a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
21409a0bf528SMauro Carvalho Chehab 	u16 data = 0;
2141cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_if_agc_settings;
21429a0bf528SMauro Carvalho Chehab 
21439a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21449a0bf528SMauro Carvalho Chehab 
2145cd7a67a4SMauro Carvalho Chehab 	if (p_agc_cfg == NULL)
21469a0bf528SMauro Carvalho Chehab 		goto error;
21479a0bf528SMauro Carvalho Chehab 
2148cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
21499a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
21509a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
21519a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
21529a0bf528SMauro Carvalho Chehab 		if (status < 0)
21539a0bf528SMauro Carvalho Chehab 			goto error;
21549a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
21559a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
21569a0bf528SMauro Carvalho Chehab 		if (status < 0)
21579a0bf528SMauro Carvalho Chehab 			goto error;
21589a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
21599a0bf528SMauro Carvalho Chehab 		if (status < 0)
21609a0bf528SMauro Carvalho Chehab 			goto error;
21619a0bf528SMauro Carvalho Chehab 
21629a0bf528SMauro Carvalho Chehab 		/* Enable SCU RF AGC loop */
21639a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
21649a0bf528SMauro Carvalho Chehab 
21659a0bf528SMauro Carvalho Chehab 		/* Polarity */
2166cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
21679a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21689a0bf528SMauro Carvalho Chehab 		else
21699a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21709a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
21719a0bf528SMauro Carvalho Chehab 		if (status < 0)
21729a0bf528SMauro Carvalho Chehab 			goto error;
21739a0bf528SMauro Carvalho Chehab 
21749a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
21759a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
21769a0bf528SMauro Carvalho Chehab 		if (status < 0)
21779a0bf528SMauro Carvalho Chehab 			goto error;
21789a0bf528SMauro Carvalho Chehab 
21799a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2180cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
21819a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
21829a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
21839a0bf528SMauro Carvalho Chehab 
21849a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
21859a0bf528SMauro Carvalho Chehab 		if (status < 0)
21869a0bf528SMauro Carvalho Chehab 			goto error;
21879a0bf528SMauro Carvalho Chehab 
2188cd7a67a4SMauro Carvalho Chehab 		if (is_dvbt(state))
2189cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2190cd7a67a4SMauro Carvalho Chehab 		else if (is_qam(state))
2191cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_qam_if_agc_cfg;
21929a0bf528SMauro Carvalho Chehab 		else
2193cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_atv_if_agc_cfg;
2194cd7a67a4SMauro Carvalho Chehab 		if (p_if_agc_settings == NULL) {
21959a0bf528SMauro Carvalho Chehab 			status = -EINVAL;
21969a0bf528SMauro Carvalho Chehab 			goto error;
21979a0bf528SMauro Carvalho Chehab 		}
21989a0bf528SMauro Carvalho Chehab 
21999a0bf528SMauro Carvalho Chehab 		/* Set TOP, only if IF-AGC is in AUTO mode */
220089fffac8SMauro Carvalho Chehab 		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
2201ab5060cdSMauro Carvalho Chehab 			status = write16(state,
2202ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2203ab5060cdSMauro Carvalho Chehab 					 p_agc_cfg->top);
22049a0bf528SMauro Carvalho Chehab 			if (status < 0)
22059a0bf528SMauro Carvalho Chehab 				goto error;
220689fffac8SMauro Carvalho Chehab 		}
22079a0bf528SMauro Carvalho Chehab 
22089a0bf528SMauro Carvalho Chehab 		/* Cut-Off current */
2209ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2210ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->cut_off_current);
22119a0bf528SMauro Carvalho Chehab 		if (status < 0)
22129a0bf528SMauro Carvalho Chehab 			goto error;
22139a0bf528SMauro Carvalho Chehab 
22149a0bf528SMauro Carvalho Chehab 		/* Max. output level */
2215ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2216ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->max_output_level);
22179a0bf528SMauro Carvalho Chehab 		if (status < 0)
22189a0bf528SMauro Carvalho Chehab 			goto error;
22199a0bf528SMauro Carvalho Chehab 
22209a0bf528SMauro Carvalho Chehab 		break;
22219a0bf528SMauro Carvalho Chehab 
22229a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
22239a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
22249a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22259a0bf528SMauro Carvalho Chehab 		if (status < 0)
22269a0bf528SMauro Carvalho Chehab 			goto error;
22279a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22289a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22299a0bf528SMauro Carvalho Chehab 		if (status < 0)
22309a0bf528SMauro Carvalho Chehab 			goto error;
22319a0bf528SMauro Carvalho Chehab 
22329a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22339a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22349a0bf528SMauro Carvalho Chehab 		if (status < 0)
22359a0bf528SMauro Carvalho Chehab 			goto error;
22369a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2237cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
22389a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22399a0bf528SMauro Carvalho Chehab 		else
22409a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22419a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22429a0bf528SMauro Carvalho Chehab 		if (status < 0)
22439a0bf528SMauro Carvalho Chehab 			goto error;
22449a0bf528SMauro Carvalho Chehab 
22459a0bf528SMauro Carvalho Chehab 		/* SCU c.o.c. to 0, enabling full control range */
22469a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
22479a0bf528SMauro Carvalho Chehab 		if (status < 0)
22489a0bf528SMauro Carvalho Chehab 			goto error;
22499a0bf528SMauro Carvalho Chehab 
22509a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2251ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2252ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
22539a0bf528SMauro Carvalho Chehab 		if (status < 0)
22549a0bf528SMauro Carvalho Chehab 			goto error;
22559a0bf528SMauro Carvalho Chehab 		break;
22569a0bf528SMauro Carvalho Chehab 
22579a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
22589a0bf528SMauro Carvalho Chehab 		/* Disable RF AGC DAC */
22599a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22609a0bf528SMauro Carvalho Chehab 		if (status < 0)
22619a0bf528SMauro Carvalho Chehab 			goto error;
22629a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22639a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22649a0bf528SMauro Carvalho Chehab 		if (status < 0)
22659a0bf528SMauro Carvalho Chehab 			goto error;
22669a0bf528SMauro Carvalho Chehab 
22679a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22689a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22699a0bf528SMauro Carvalho Chehab 		if (status < 0)
22709a0bf528SMauro Carvalho Chehab 			goto error;
22719a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22729a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22739a0bf528SMauro Carvalho Chehab 		if (status < 0)
22749a0bf528SMauro Carvalho Chehab 			goto error;
22759a0bf528SMauro Carvalho Chehab 		break;
22769a0bf528SMauro Carvalho Chehab 
22779a0bf528SMauro Carvalho Chehab 	default:
22789a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
22799a0bf528SMauro Carvalho Chehab 
22809a0bf528SMauro Carvalho Chehab 	}
22819a0bf528SMauro Carvalho Chehab error:
22829a0bf528SMauro Carvalho Chehab 	if (status < 0)
22833a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
22849a0bf528SMauro Carvalho Chehab 	return status;
22859a0bf528SMauro Carvalho Chehab }
22869a0bf528SMauro Carvalho Chehab 
22879a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
22889a0bf528SMauro Carvalho Chehab 
2289cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state,
2290cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
22919a0bf528SMauro Carvalho Chehab {
22929a0bf528SMauro Carvalho Chehab 	u16 data = 0;
22939a0bf528SMauro Carvalho Chehab 	int status = 0;
2294cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_rf_agc_settings;
22959a0bf528SMauro Carvalho Chehab 
22969a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
22979a0bf528SMauro Carvalho Chehab 
2298cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
22999a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
23009a0bf528SMauro Carvalho Chehab 
23019a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23029a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23039a0bf528SMauro Carvalho Chehab 		if (status < 0)
23049a0bf528SMauro Carvalho Chehab 			goto error;
23059a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23069a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23079a0bf528SMauro Carvalho Chehab 		if (status < 0)
23089a0bf528SMauro Carvalho Chehab 			goto error;
23099a0bf528SMauro Carvalho Chehab 
23109a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23119a0bf528SMauro Carvalho Chehab 		if (status < 0)
23129a0bf528SMauro Carvalho Chehab 			goto error;
23139a0bf528SMauro Carvalho Chehab 
23149a0bf528SMauro Carvalho Chehab 		/* Enable SCU IF AGC loop */
23159a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23169a0bf528SMauro Carvalho Chehab 
23179a0bf528SMauro Carvalho Chehab 		/* Polarity */
2318cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23199a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23209a0bf528SMauro Carvalho Chehab 		else
23219a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23229a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23239a0bf528SMauro Carvalho Chehab 		if (status < 0)
23249a0bf528SMauro Carvalho Chehab 			goto error;
23259a0bf528SMauro Carvalho Chehab 
23269a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
23279a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
23289a0bf528SMauro Carvalho Chehab 		if (status < 0)
23299a0bf528SMauro Carvalho Chehab 			goto error;
23309a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2331cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
23329a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
23339a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
23349a0bf528SMauro Carvalho Chehab 
23359a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
23369a0bf528SMauro Carvalho Chehab 		if (status < 0)
23379a0bf528SMauro Carvalho Chehab 			goto error;
23389a0bf528SMauro Carvalho Chehab 
2339cd7a67a4SMauro Carvalho Chehab 		if (is_qam(state))
2340cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
23419a0bf528SMauro Carvalho Chehab 		else
2342cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2343cd7a67a4SMauro Carvalho Chehab 		if (p_rf_agc_settings == NULL)
23449a0bf528SMauro Carvalho Chehab 			return -1;
23459a0bf528SMauro Carvalho Chehab 		/* Restore TOP */
2346ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2347ab5060cdSMauro Carvalho Chehab 				 p_rf_agc_settings->top);
23489a0bf528SMauro Carvalho Chehab 		if (status < 0)
23499a0bf528SMauro Carvalho Chehab 			goto error;
23509a0bf528SMauro Carvalho Chehab 		break;
23519a0bf528SMauro Carvalho Chehab 
23529a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
23539a0bf528SMauro Carvalho Chehab 
23549a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23559a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23569a0bf528SMauro Carvalho Chehab 		if (status < 0)
23579a0bf528SMauro Carvalho Chehab 			goto error;
23589a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23599a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23609a0bf528SMauro Carvalho Chehab 		if (status < 0)
23619a0bf528SMauro Carvalho Chehab 			goto error;
23629a0bf528SMauro Carvalho Chehab 
23639a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23649a0bf528SMauro Carvalho Chehab 		if (status < 0)
23659a0bf528SMauro Carvalho Chehab 			goto error;
23669a0bf528SMauro Carvalho Chehab 
23679a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23689a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23699a0bf528SMauro Carvalho Chehab 
23709a0bf528SMauro Carvalho Chehab 		/* Polarity */
2371cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23729a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23739a0bf528SMauro Carvalho Chehab 		else
23749a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23759a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23769a0bf528SMauro Carvalho Chehab 		if (status < 0)
23779a0bf528SMauro Carvalho Chehab 			goto error;
23789a0bf528SMauro Carvalho Chehab 
23799a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2380ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2381ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
23829a0bf528SMauro Carvalho Chehab 		if (status < 0)
23839a0bf528SMauro Carvalho Chehab 			goto error;
23849a0bf528SMauro Carvalho Chehab 		break;
23859a0bf528SMauro Carvalho Chehab 
23869a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
23879a0bf528SMauro Carvalho Chehab 
23889a0bf528SMauro Carvalho Chehab 		/* Disable If AGC DAC */
23899a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23909a0bf528SMauro Carvalho Chehab 		if (status < 0)
23919a0bf528SMauro Carvalho Chehab 			goto error;
23929a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23939a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23949a0bf528SMauro Carvalho Chehab 		if (status < 0)
23959a0bf528SMauro Carvalho Chehab 			goto error;
23969a0bf528SMauro Carvalho Chehab 
23979a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23989a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23999a0bf528SMauro Carvalho Chehab 		if (status < 0)
24009a0bf528SMauro Carvalho Chehab 			goto error;
24019a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24029a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24039a0bf528SMauro Carvalho Chehab 		if (status < 0)
24049a0bf528SMauro Carvalho Chehab 			goto error;
24059a0bf528SMauro Carvalho Chehab 		break;
2406cd7a67a4SMauro Carvalho Chehab 	}		/* switch (agcSettingsIf->ctrl_mode) */
24079a0bf528SMauro Carvalho Chehab 
24089a0bf528SMauro Carvalho Chehab 	/* always set the top to support
24099a0bf528SMauro Carvalho Chehab 		configurations without if-loop */
2410cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
24119a0bf528SMauro Carvalho Chehab error:
24129a0bf528SMauro Carvalho Chehab 	if (status < 0)
24133a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24149a0bf528SMauro Carvalho Chehab 	return status;
24159a0bf528SMauro Carvalho Chehab }
24169a0bf528SMauro Carvalho Chehab 
2417cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state,
2418cd7a67a4SMauro Carvalho Chehab 			       s32 *p_signal_to_noise)
24199a0bf528SMauro Carvalho Chehab {
24209a0bf528SMauro Carvalho Chehab 	int status = 0;
2421cd7a67a4SMauro Carvalho Chehab 	u16 qam_sl_err_power = 0;	/* accum. error between
24229a0bf528SMauro Carvalho Chehab 					raw and sliced symbols */
2423cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
24249a0bf528SMauro Carvalho Chehab 					QAM modulation */
2425cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_mer = 0;	/* QAM MER */
24269a0bf528SMauro Carvalho Chehab 
24279a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24289a0bf528SMauro Carvalho Chehab 
24299a0bf528SMauro Carvalho Chehab 	/* MER calculation */
24309a0bf528SMauro Carvalho Chehab 
24319a0bf528SMauro Carvalho Chehab 	/* get the register value needed for MER */
2432cd7a67a4SMauro Carvalho Chehab 	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
24339a0bf528SMauro Carvalho Chehab 	if (status < 0) {
24343a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24359a0bf528SMauro Carvalho Chehab 		return -EINVAL;
24369a0bf528SMauro Carvalho Chehab 	}
24379a0bf528SMauro Carvalho Chehab 
24389a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
24399a0bf528SMauro Carvalho Chehab 	case QAM_16:
2440cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
24419a0bf528SMauro Carvalho Chehab 		break;
24429a0bf528SMauro Carvalho Chehab 	case QAM_32:
2443cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
24449a0bf528SMauro Carvalho Chehab 		break;
24459a0bf528SMauro Carvalho Chehab 	case QAM_64:
2446cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
24479a0bf528SMauro Carvalho Chehab 		break;
24489a0bf528SMauro Carvalho Chehab 	case QAM_128:
2449cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
24509a0bf528SMauro Carvalho Chehab 		break;
24519a0bf528SMauro Carvalho Chehab 	default:
24529a0bf528SMauro Carvalho Chehab 	case QAM_256:
2453cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
24549a0bf528SMauro Carvalho Chehab 		break;
24559a0bf528SMauro Carvalho Chehab 	}
24569a0bf528SMauro Carvalho Chehab 
2457cd7a67a4SMauro Carvalho Chehab 	if (qam_sl_err_power > 0) {
2458cd7a67a4SMauro Carvalho Chehab 		qam_sl_mer = log10times100(qam_sl_sig_power) -
2459cd7a67a4SMauro Carvalho Chehab 			log10times100((u32) qam_sl_err_power);
24609a0bf528SMauro Carvalho Chehab 	}
2461cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = qam_sl_mer;
24629a0bf528SMauro Carvalho Chehab 
24639a0bf528SMauro Carvalho Chehab 	return status;
24649a0bf528SMauro Carvalho Chehab }
24659a0bf528SMauro Carvalho Chehab 
2466cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state,
2467cd7a67a4SMauro Carvalho Chehab 				s32 *p_signal_to_noise)
24689a0bf528SMauro Carvalho Chehab {
24699a0bf528SMauro Carvalho Chehab 	int status;
2470cd7a67a4SMauro Carvalho Chehab 	u16 reg_data = 0;
2471cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_i = 0;
2472cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_q = 0;
2473cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_sqr_err_exp = 0;
2474cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_tps_pwr_ofs = 0;
2475cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_req_smb_cnt = 0;
2476cd7a67a4SMauro Carvalho Chehab 	u32 tps_cnt = 0;
2477cd7a67a4SMauro Carvalho Chehab 	u32 sqr_err_iq = 0;
24789a0bf528SMauro Carvalho Chehab 	u32 a = 0;
24799a0bf528SMauro Carvalho Chehab 	u32 b = 0;
24809a0bf528SMauro Carvalho Chehab 	u32 c = 0;
2481cd7a67a4SMauro Carvalho Chehab 	u32 i_mer = 0;
2482cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
24839a0bf528SMauro Carvalho Chehab 
24849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24859a0bf528SMauro Carvalho Chehab 
2486ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2487ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_tps_pwr_ofs);
24889a0bf528SMauro Carvalho Chehab 	if (status < 0)
24899a0bf528SMauro Carvalho Chehab 		goto error;
2490ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2491ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_req_smb_cnt);
24929a0bf528SMauro Carvalho Chehab 	if (status < 0)
24939a0bf528SMauro Carvalho Chehab 		goto error;
2494ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2495ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_sqr_err_exp);
24969a0bf528SMauro Carvalho Chehab 	if (status < 0)
24979a0bf528SMauro Carvalho Chehab 		goto error;
2498ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2499ab5060cdSMauro Carvalho Chehab 			&reg_data);
25009a0bf528SMauro Carvalho Chehab 	if (status < 0)
25019a0bf528SMauro Carvalho Chehab 		goto error;
25029a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_I operational range */
2503cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_i = (u32) reg_data;
2504cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2505cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2506cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_i += 0x00010000UL;
25079a0bf528SMauro Carvalho Chehab 	}
2508cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
25099a0bf528SMauro Carvalho Chehab 	if (status < 0)
25109a0bf528SMauro Carvalho Chehab 		goto error;
25119a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_Q operational range */
2512cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_q = (u32) reg_data;
2513cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2514cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
2515cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_q += 0x00010000UL;
25169a0bf528SMauro Carvalho Chehab 
2517ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2518ab5060cdSMauro Carvalho Chehab 			&transmission_params);
25199a0bf528SMauro Carvalho Chehab 	if (status < 0)
25209a0bf528SMauro Carvalho Chehab 		goto error;
25219a0bf528SMauro Carvalho Chehab 
25229a0bf528SMauro Carvalho Chehab 	/* Check input data for MER */
25239a0bf528SMauro Carvalho Chehab 
25249a0bf528SMauro Carvalho Chehab 	/* MER calculation (in 0.1 dB) without math.h */
2525cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2526cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
2527cd7a67a4SMauro Carvalho Chehab 	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
25289a0bf528SMauro Carvalho Chehab 		/* No error at all, this must be the HW reset value
25299a0bf528SMauro Carvalho Chehab 			* Apparently no first measurement yet
25309a0bf528SMauro Carvalho Chehab 			* Set MER to 0.0 */
2531cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
25329a0bf528SMauro Carvalho Chehab 	} else {
2533cd7a67a4SMauro Carvalho Chehab 		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2534cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_sqr_err_exp;
2535cd7a67a4SMauro Carvalho Chehab 		if ((transmission_params &
25369a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
25379a0bf528SMauro Carvalho Chehab 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2538cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 17;
25399a0bf528SMauro Carvalho Chehab 		else
2540cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 68;
25419a0bf528SMauro Carvalho Chehab 
25429a0bf528SMauro Carvalho Chehab 		/* IMER = 100 * log10 (x)
2543cd7a67a4SMauro Carvalho Chehab 			where x = (eq_reg_td_tps_pwr_ofs^2 *
2544cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
25459a0bf528SMauro Carvalho Chehab 
25469a0bf528SMauro Carvalho Chehab 			=> IMER = a + b -c
2547cd7a67a4SMauro Carvalho Chehab 			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2548cd7a67a4SMauro Carvalho Chehab 			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2549cd7a67a4SMauro Carvalho Chehab 			c = 100 * log10 (sqr_err_iq)
25509a0bf528SMauro Carvalho Chehab 			*/
25519a0bf528SMauro Carvalho Chehab 
25529a0bf528SMauro Carvalho Chehab 		/* log(x) x = 9bits * 9bits->18 bits  */
2553cd7a67a4SMauro Carvalho Chehab 		a = log10times100(eq_reg_td_tps_pwr_ofs *
2554cd7a67a4SMauro Carvalho Chehab 					eq_reg_td_tps_pwr_ofs);
25559a0bf528SMauro Carvalho Chehab 		/* log(x) x = 16bits * 7bits->23 bits  */
2556cd7a67a4SMauro Carvalho Chehab 		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
25579a0bf528SMauro Carvalho Chehab 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
2558cd7a67a4SMauro Carvalho Chehab 		c = log10times100(sqr_err_iq);
25599a0bf528SMauro Carvalho Chehab 
2560cd7a67a4SMauro Carvalho Chehab 		i_mer = a + b - c;
25619a0bf528SMauro Carvalho Chehab 	}
2562cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = i_mer;
25639a0bf528SMauro Carvalho Chehab 
25649a0bf528SMauro Carvalho Chehab error:
25659a0bf528SMauro Carvalho Chehab 	if (status < 0)
25663a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
25679a0bf528SMauro Carvalho Chehab 	return status;
25689a0bf528SMauro Carvalho Chehab }
25699a0bf528SMauro Carvalho Chehab 
2570cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
25719a0bf528SMauro Carvalho Chehab {
25729a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25739a0bf528SMauro Carvalho Chehab 
2574cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = 0;
2575cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
25769a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2577cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
25789a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
25799a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2580cd7a67a4SMauro Carvalho Chehab 		return get_qam_signal_to_noise(state, p_signal_to_noise);
25819a0bf528SMauro Carvalho Chehab 	default:
25829a0bf528SMauro Carvalho Chehab 		break;
25839a0bf528SMauro Carvalho Chehab 	}
25849a0bf528SMauro Carvalho Chehab 	return 0;
25859a0bf528SMauro Carvalho Chehab }
25869a0bf528SMauro Carvalho Chehab 
25879a0bf528SMauro Carvalho Chehab #if 0
2588cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
25899a0bf528SMauro Carvalho Chehab {
25909a0bf528SMauro Carvalho Chehab 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
25919a0bf528SMauro Carvalho Chehab 	int status = 0;
25929a0bf528SMauro Carvalho Chehab 
25939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25949a0bf528SMauro Carvalho Chehab 
25959a0bf528SMauro Carvalho Chehab 	static s32 QE_SN[] = {
25969a0bf528SMauro Carvalho Chehab 		51,		/* QPSK 1/2 */
25979a0bf528SMauro Carvalho Chehab 		69,		/* QPSK 2/3 */
25989a0bf528SMauro Carvalho Chehab 		79,		/* QPSK 3/4 */
25999a0bf528SMauro Carvalho Chehab 		89,		/* QPSK 5/6 */
26009a0bf528SMauro Carvalho Chehab 		97,		/* QPSK 7/8 */
26019a0bf528SMauro Carvalho Chehab 		108,		/* 16-QAM 1/2 */
26029a0bf528SMauro Carvalho Chehab 		131,		/* 16-QAM 2/3 */
26039a0bf528SMauro Carvalho Chehab 		146,		/* 16-QAM 3/4 */
26049a0bf528SMauro Carvalho Chehab 		156,		/* 16-QAM 5/6 */
26059a0bf528SMauro Carvalho Chehab 		160,		/* 16-QAM 7/8 */
26069a0bf528SMauro Carvalho Chehab 		165,		/* 64-QAM 1/2 */
26079a0bf528SMauro Carvalho Chehab 		187,		/* 64-QAM 2/3 */
26089a0bf528SMauro Carvalho Chehab 		202,		/* 64-QAM 3/4 */
26099a0bf528SMauro Carvalho Chehab 		216,		/* 64-QAM 5/6 */
26109a0bf528SMauro Carvalho Chehab 		225,		/* 64-QAM 7/8 */
26119a0bf528SMauro Carvalho Chehab 	};
26129a0bf528SMauro Carvalho Chehab 
2613cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26149a0bf528SMauro Carvalho Chehab 
26159a0bf528SMauro Carvalho Chehab 	do {
2616cd7a67a4SMauro Carvalho Chehab 		s32 signal_to_noise = 0;
2617cd7a67a4SMauro Carvalho Chehab 		u16 constellation = 0;
2618cd7a67a4SMauro Carvalho Chehab 		u16 code_rate = 0;
2619cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel;
2620cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality;
26219a0bf528SMauro Carvalho Chehab 
2622cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
26239a0bf528SMauro Carvalho Chehab 		if (status < 0)
26249a0bf528SMauro Carvalho Chehab 			break;
2625ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2626ab5060cdSMauro Carvalho Chehab 				&constellation);
26279a0bf528SMauro Carvalho Chehab 		if (status < 0)
26289a0bf528SMauro Carvalho Chehab 			break;
2629cd7a67a4SMauro Carvalho Chehab 		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
26309a0bf528SMauro Carvalho Chehab 
2631ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2632ab5060cdSMauro Carvalho Chehab 				&code_rate);
26339a0bf528SMauro Carvalho Chehab 		if (status < 0)
26349a0bf528SMauro Carvalho Chehab 			break;
2635cd7a67a4SMauro Carvalho Chehab 		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
26369a0bf528SMauro Carvalho Chehab 
2637cd7a67a4SMauro Carvalho Chehab 		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2638cd7a67a4SMauro Carvalho Chehab 		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
26399a0bf528SMauro Carvalho Chehab 			break;
2640cd7a67a4SMauro Carvalho Chehab 		signal_to_noise_rel = signal_to_noise -
2641cd7a67a4SMauro Carvalho Chehab 		    QE_SN[constellation * 5 + code_rate];
2642cd7a67a4SMauro Carvalho Chehab 		ber_quality = 100;
26439a0bf528SMauro Carvalho Chehab 
2644cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2645cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2646cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2647cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2648cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26499a0bf528SMauro Carvalho Chehab 		else
2650cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26519a0bf528SMauro Carvalho Chehab 	} while (0);
26529a0bf528SMauro Carvalho Chehab 	return 0;
26539a0bf528SMauro Carvalho Chehab };
26549a0bf528SMauro Carvalho Chehab 
2655cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
26569a0bf528SMauro Carvalho Chehab {
26579a0bf528SMauro Carvalho Chehab 	int status = 0;
2658cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26599a0bf528SMauro Carvalho Chehab 
26609a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26619a0bf528SMauro Carvalho Chehab 
26629a0bf528SMauro Carvalho Chehab 	do {
2663cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise = 0;
2664cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality = 100;
2665cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel = 0;
26669a0bf528SMauro Carvalho Chehab 
2667cd7a67a4SMauro Carvalho Chehab 		status = get_qam_signal_to_noise(state, &signal_to_noise);
26689a0bf528SMauro Carvalho Chehab 		if (status < 0)
26699a0bf528SMauro Carvalho Chehab 			break;
26709a0bf528SMauro Carvalho Chehab 
26719a0bf528SMauro Carvalho Chehab 		switch (state->props.modulation) {
26729a0bf528SMauro Carvalho Chehab 		case QAM_16:
2673cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 200;
26749a0bf528SMauro Carvalho Chehab 			break;
26759a0bf528SMauro Carvalho Chehab 		case QAM_32:
2676cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 230;
26779a0bf528SMauro Carvalho Chehab 			break;	/* Not in NorDig */
26789a0bf528SMauro Carvalho Chehab 		case QAM_64:
2679cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 260;
26809a0bf528SMauro Carvalho Chehab 			break;
26819a0bf528SMauro Carvalho Chehab 		case QAM_128:
2682cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 290;
26839a0bf528SMauro Carvalho Chehab 			break;
26849a0bf528SMauro Carvalho Chehab 		default:
26859a0bf528SMauro Carvalho Chehab 		case QAM_256:
2686cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 320;
26879a0bf528SMauro Carvalho Chehab 			break;
26889a0bf528SMauro Carvalho Chehab 		}
26899a0bf528SMauro Carvalho Chehab 
2690cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2691cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2692cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2693cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2694cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26959a0bf528SMauro Carvalho Chehab 		else
2696cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26979a0bf528SMauro Carvalho Chehab 	} while (0);
26989a0bf528SMauro Carvalho Chehab 
26999a0bf528SMauro Carvalho Chehab 	return status;
27009a0bf528SMauro Carvalho Chehab }
27019a0bf528SMauro Carvalho Chehab 
2702cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality)
27039a0bf528SMauro Carvalho Chehab {
27049a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27059a0bf528SMauro Carvalho Chehab 
2706cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
27079a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2708cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_quality(state, p_quality);
27099a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
2710cd7a67a4SMauro Carvalho Chehab 		return get_dvbc_quality(state, p_quality);
27119a0bf528SMauro Carvalho Chehab 	default:
27129a0bf528SMauro Carvalho Chehab 		break;
27139a0bf528SMauro Carvalho Chehab 	}
27149a0bf528SMauro Carvalho Chehab 
27159a0bf528SMauro Carvalho Chehab 	return 0;
27169a0bf528SMauro Carvalho Chehab }
27179a0bf528SMauro Carvalho Chehab #endif
27189a0bf528SMauro Carvalho Chehab 
27199a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
27209a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
27219a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A   0x420060
27229a0bf528SMauro Carvalho Chehab 
27239a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
27249a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
27259a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
27269a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
27279a0bf528SMauro Carvalho Chehab 
27289a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
27299a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
27309a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
27319a0bf528SMauro Carvalho Chehab 
2732cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
27339a0bf528SMauro Carvalho Chehab {
27349a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27359a0bf528SMauro Carvalho Chehab 
27369a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27379a0bf528SMauro Carvalho Chehab 
2738cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
27399a0bf528SMauro Carvalho Chehab 		return 0;
2740cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_POWERED_DOWN)
27419a0bf528SMauro Carvalho Chehab 		goto error;
27429a0bf528SMauro Carvalho Chehab 
27439a0bf528SMauro Carvalho Chehab 	if (state->no_i2c_bridge)
27449a0bf528SMauro Carvalho Chehab 		return 0;
27459a0bf528SMauro Carvalho Chehab 
2746ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2747ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
27489a0bf528SMauro Carvalho Chehab 	if (status < 0)
27499a0bf528SMauro Carvalho Chehab 		goto error;
2750cd7a67a4SMauro Carvalho Chehab 	if (b_enable_bridge) {
2751ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2752ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
27539a0bf528SMauro Carvalho Chehab 		if (status < 0)
27549a0bf528SMauro Carvalho Chehab 			goto error;
27559a0bf528SMauro Carvalho Chehab 	} else {
2756ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2757ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
27589a0bf528SMauro Carvalho Chehab 		if (status < 0)
27599a0bf528SMauro Carvalho Chehab 			goto error;
27609a0bf528SMauro Carvalho Chehab 	}
27619a0bf528SMauro Carvalho Chehab 
2762b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
27639a0bf528SMauro Carvalho Chehab 
27649a0bf528SMauro Carvalho Chehab error:
27659a0bf528SMauro Carvalho Chehab 	if (status < 0)
27663a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27679a0bf528SMauro Carvalho Chehab 	return status;
27689a0bf528SMauro Carvalho Chehab }
27699a0bf528SMauro Carvalho Chehab 
2770cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state,
2771cd7a67a4SMauro Carvalho Chehab 		     struct s_cfg_pre_saw *p_pre_saw_cfg)
27729a0bf528SMauro Carvalho Chehab {
27739a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27749a0bf528SMauro Carvalho Chehab 
27759a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27769a0bf528SMauro Carvalho Chehab 
2777cd7a67a4SMauro Carvalho Chehab 	if ((p_pre_saw_cfg == NULL)
2778cd7a67a4SMauro Carvalho Chehab 	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
27799a0bf528SMauro Carvalho Chehab 		goto error;
27809a0bf528SMauro Carvalho Chehab 
2781cd7a67a4SMauro Carvalho Chehab 	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
27829a0bf528SMauro Carvalho Chehab error:
27839a0bf528SMauro Carvalho Chehab 	if (status < 0)
27843a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27859a0bf528SMauro Carvalho Chehab 	return status;
27869a0bf528SMauro Carvalho Chehab }
27879a0bf528SMauro Carvalho Chehab 
2788cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2789cd7a67a4SMauro Carvalho Chehab 		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
27909a0bf528SMauro Carvalho Chehab {
2791cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
2792cd7a67a4SMauro Carvalho Chehab 	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2793cd7a67a4SMauro Carvalho Chehab 	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
27949a0bf528SMauro Carvalho Chehab 	int status;
27959a0bf528SMauro Carvalho Chehab 	unsigned long end;
27969a0bf528SMauro Carvalho Chehab 
27979a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27989a0bf528SMauro Carvalho Chehab 
27999a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
28009a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
28019a0bf528SMauro Carvalho Chehab 	if (status < 0)
28029a0bf528SMauro Carvalho Chehab 		goto error;
28039a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
28049a0bf528SMauro Carvalho Chehab 	if (status < 0)
28059a0bf528SMauro Carvalho Chehab 		goto error;
28069a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
28079a0bf528SMauro Carvalho Chehab 	if (status < 0)
28089a0bf528SMauro Carvalho Chehab 		goto error;
2809cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
28109a0bf528SMauro Carvalho Chehab 	if (status < 0)
28119a0bf528SMauro Carvalho Chehab 		goto error;
2812cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
28139a0bf528SMauro Carvalho Chehab 	if (status < 0)
28149a0bf528SMauro Carvalho Chehab 		goto error;
28159a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
28169a0bf528SMauro Carvalho Chehab 	if (status < 0)
28179a0bf528SMauro Carvalho Chehab 		goto error;
28189a0bf528SMauro Carvalho Chehab 
2819cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
28209a0bf528SMauro Carvalho Chehab 	do {
2821cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
28229a0bf528SMauro Carvalho Chehab 		if (status < 0)
28239a0bf528SMauro Carvalho Chehab 			goto error;
2824cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
2825cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
28263a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
28279a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
28289a0bf528SMauro Carvalho Chehab 		goto error2;
28299a0bf528SMauro Carvalho Chehab 	}
28309a0bf528SMauro Carvalho Chehab error:
28319a0bf528SMauro Carvalho Chehab 	if (status < 0)
28323a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28339a0bf528SMauro Carvalho Chehab error2:
28349a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
28359a0bf528SMauro Carvalho Chehab 	return status;
28369a0bf528SMauro Carvalho Chehab 
28379a0bf528SMauro Carvalho Chehab }
28389a0bf528SMauro Carvalho Chehab 
2839cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count)
28409a0bf528SMauro Carvalho Chehab {
28419a0bf528SMauro Carvalho Chehab 	u16 data = 0;
28429a0bf528SMauro Carvalho Chehab 	int status;
28439a0bf528SMauro Carvalho Chehab 
28449a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28459a0bf528SMauro Carvalho Chehab 
2846cd7a67a4SMauro Carvalho Chehab 	/* start measurement */
28479a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
28489a0bf528SMauro Carvalho Chehab 	if (status < 0)
28499a0bf528SMauro Carvalho Chehab 		goto error;
28509a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 1);
28519a0bf528SMauro Carvalho Chehab 	if (status < 0)
28529a0bf528SMauro Carvalho Chehab 		goto error;
28539a0bf528SMauro Carvalho Chehab 
28549a0bf528SMauro Carvalho Chehab 	*count = 0;
28559a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE0__A, &data);
28569a0bf528SMauro Carvalho Chehab 	if (status < 0)
28579a0bf528SMauro Carvalho Chehab 		goto error;
28589a0bf528SMauro Carvalho Chehab 	if (data == 127)
28599a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28609a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE1__A, &data);
28619a0bf528SMauro Carvalho Chehab 	if (status < 0)
28629a0bf528SMauro Carvalho Chehab 		goto error;
28639a0bf528SMauro Carvalho Chehab 	if (data == 127)
28649a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28659a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE2__A, &data);
28669a0bf528SMauro Carvalho Chehab 	if (status < 0)
28679a0bf528SMauro Carvalho Chehab 		goto error;
28689a0bf528SMauro Carvalho Chehab 	if (data == 127)
28699a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28709a0bf528SMauro Carvalho Chehab 
28719a0bf528SMauro Carvalho Chehab error:
28729a0bf528SMauro Carvalho Chehab 	if (status < 0)
28733a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28749a0bf528SMauro Carvalho Chehab 	return status;
28759a0bf528SMauro Carvalho Chehab }
28769a0bf528SMauro Carvalho Chehab 
2877cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state)
28789a0bf528SMauro Carvalho Chehab {
28799a0bf528SMauro Carvalho Chehab 	u16 count = 0;
28809a0bf528SMauro Carvalho Chehab 	int status;
28819a0bf528SMauro Carvalho Chehab 
28829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28839a0bf528SMauro Carvalho Chehab 
2884cd7a67a4SMauro Carvalho Chehab 	status = adc_sync_measurement(state, &count);
28859a0bf528SMauro Carvalho Chehab 	if (status < 0)
28869a0bf528SMauro Carvalho Chehab 		goto error;
28879a0bf528SMauro Carvalho Chehab 
28889a0bf528SMauro Carvalho Chehab 	if (count == 1) {
288939c1cb2bSJonathan McCrohan 		/* Try sampling on a different edge */
2890cd7a67a4SMauro Carvalho Chehab 		u16 clk_neg = 0;
28919a0bf528SMauro Carvalho Chehab 
2892cd7a67a4SMauro Carvalho Chehab 		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
28939a0bf528SMauro Carvalho Chehab 		if (status < 0)
28949a0bf528SMauro Carvalho Chehab 			goto error;
2895cd7a67a4SMauro Carvalho Chehab 		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
28969a0bf528SMauro Carvalho Chehab 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2897cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2898cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
28999a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
29009a0bf528SMauro Carvalho Chehab 		} else {
2901cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2902cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
29039a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
29049a0bf528SMauro Carvalho Chehab 		}
2905cd7a67a4SMauro Carvalho Chehab 		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
29069a0bf528SMauro Carvalho Chehab 		if (status < 0)
29079a0bf528SMauro Carvalho Chehab 			goto error;
2908cd7a67a4SMauro Carvalho Chehab 		status = adc_sync_measurement(state, &count);
29099a0bf528SMauro Carvalho Chehab 		if (status < 0)
29109a0bf528SMauro Carvalho Chehab 			goto error;
29119a0bf528SMauro Carvalho Chehab 	}
29129a0bf528SMauro Carvalho Chehab 
29139a0bf528SMauro Carvalho Chehab 	if (count < 2)
29149a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
29159a0bf528SMauro Carvalho Chehab error:
29169a0bf528SMauro Carvalho Chehab 	if (status < 0)
29173a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
29189a0bf528SMauro Carvalho Chehab 	return status;
29199a0bf528SMauro Carvalho Chehab }
29209a0bf528SMauro Carvalho Chehab 
2921cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state,
2922cd7a67a4SMauro Carvalho Chehab 			       u16 intermediate_freqk_hz,
2923cd7a67a4SMauro Carvalho Chehab 			       s32 tuner_freq_offset, bool is_dtv)
29249a0bf528SMauro Carvalho Chehab {
2925cd7a67a4SMauro Carvalho Chehab 	bool select_pos_image = false;
2926cd7a67a4SMauro Carvalho Chehab 	u32 rf_freq_residual = tuner_freq_offset;
2927cd7a67a4SMauro Carvalho Chehab 	u32 fm_frequency_shift = 0;
2928cd7a67a4SMauro Carvalho Chehab 	bool tuner_mirror = !state->m_b_mirror_freq_spect;
2929cd7a67a4SMauro Carvalho Chehab 	u32 adc_freq;
2930cd7a67a4SMauro Carvalho Chehab 	bool adc_flip;
29319a0bf528SMauro Carvalho Chehab 	int status;
2932cd7a67a4SMauro Carvalho Chehab 	u32 if_freq_actual;
2933cd7a67a4SMauro Carvalho Chehab 	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2934cd7a67a4SMauro Carvalho Chehab 	u32 frequency_shift;
2935cd7a67a4SMauro Carvalho Chehab 	bool image_to_select;
29369a0bf528SMauro Carvalho Chehab 
29379a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29389a0bf528SMauro Carvalho Chehab 
29399a0bf528SMauro Carvalho Chehab 	/*
29409a0bf528SMauro Carvalho Chehab 	   Program frequency shifter
29419a0bf528SMauro Carvalho Chehab 	   No need to account for mirroring on RF
29429a0bf528SMauro Carvalho Chehab 	 */
2943cd7a67a4SMauro Carvalho Chehab 	if (is_dtv) {
2944cd7a67a4SMauro Carvalho Chehab 		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2945cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_QAM_ITU_C) ||
2946cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_DVBT))
2947cd7a67a4SMauro Carvalho Chehab 			select_pos_image = true;
29489a0bf528SMauro Carvalho Chehab 		else
2949cd7a67a4SMauro Carvalho Chehab 			select_pos_image = false;
29509a0bf528SMauro Carvalho Chehab 	}
2951cd7a67a4SMauro Carvalho Chehab 	if (tuner_mirror)
29529a0bf528SMauro Carvalho Chehab 		/* tuner doesn't mirror */
2953cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz +
2954cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual + fm_frequency_shift;
29559a0bf528SMauro Carvalho Chehab 	else
29569a0bf528SMauro Carvalho Chehab 		/* tuner mirrors */
2957cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz -
2958cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual - fm_frequency_shift;
2959cd7a67a4SMauro Carvalho Chehab 	if (if_freq_actual > sampling_frequency / 2) {
29609a0bf528SMauro Carvalho Chehab 		/* adc mirrors */
2961cd7a67a4SMauro Carvalho Chehab 		adc_freq = sampling_frequency - if_freq_actual;
2962cd7a67a4SMauro Carvalho Chehab 		adc_flip = true;
29639a0bf528SMauro Carvalho Chehab 	} else {
29649a0bf528SMauro Carvalho Chehab 		/* adc doesn't mirror */
2965cd7a67a4SMauro Carvalho Chehab 		adc_freq = if_freq_actual;
2966cd7a67a4SMauro Carvalho Chehab 		adc_flip = false;
29679a0bf528SMauro Carvalho Chehab 	}
29689a0bf528SMauro Carvalho Chehab 
2969cd7a67a4SMauro Carvalho Chehab 	frequency_shift = adc_freq;
2970cd7a67a4SMauro Carvalho Chehab 	image_to_select = state->m_rfmirror ^ tuner_mirror ^
2971cd7a67a4SMauro Carvalho Chehab 	    adc_flip ^ select_pos_image;
2972cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_fs_rate_ofs =
2973cd7a67a4SMauro Carvalho Chehab 	    Frac28a((frequency_shift), sampling_frequency);
29749a0bf528SMauro Carvalho Chehab 
2975cd7a67a4SMauro Carvalho Chehab 	if (image_to_select)
2976cd7a67a4SMauro Carvalho Chehab 		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
29779a0bf528SMauro Carvalho Chehab 
29789a0bf528SMauro Carvalho Chehab 	/* Program frequency shifter with tuner offset compensation */
2979cd7a67a4SMauro Carvalho Chehab 	/* frequency_shift += tuner_freq_offset; TODO */
29809a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
2981cd7a67a4SMauro Carvalho Chehab 			 state->m_iqm_fs_rate_ofs);
29829a0bf528SMauro Carvalho Chehab 	if (status < 0)
29833a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
29849a0bf528SMauro Carvalho Chehab 	return status;
29859a0bf528SMauro Carvalho Chehab }
29869a0bf528SMauro Carvalho Chehab 
2987cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv)
29889a0bf528SMauro Carvalho Chehab {
2989cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt = 0;
2990cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_min = 0;
2991cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_max = 0;
2992cd7a67a4SMauro Carvalho Chehab 	u16 clp_cyclen = 0;
2993cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_min = 0;
2994cd7a67a4SMauro Carvalho Chehab 	u16 clp_dir_to = 0;
2995cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_min = 0;
2996cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_max = 0;
2997cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_max = 0;
2998cd7a67a4SMauro Carvalho Chehab 	u16 sns_dir_to = 0;
2999cd7a67a4SMauro Carvalho Chehab 	u16 ki_innergain_min = 0;
3000cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt = 0;
3001cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_min = 0;
3002cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_max = 0;
30039a0bf528SMauro Carvalho Chehab 	u16 data = 0;
3004cd7a67a4SMauro Carvalho Chehab 	u16 fast_clp_ctrl_delay = 0;
3005cd7a67a4SMauro Carvalho Chehab 	u16 clp_ctrl_mode = 0;
30069a0bf528SMauro Carvalho Chehab 	int status = 0;
30079a0bf528SMauro Carvalho Chehab 
30089a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
30099a0bf528SMauro Carvalho Chehab 
30109a0bf528SMauro Carvalho Chehab 	/* Common settings */
3011cd7a67a4SMauro Carvalho Chehab 	sns_sum_max = 1023;
3012cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_min = 2047;
3013cd7a67a4SMauro Carvalho Chehab 	clp_cyclen = 500;
3014cd7a67a4SMauro Carvalho Chehab 	clp_sum_max = 1023;
30159a0bf528SMauro Carvalho Chehab 
30169a0bf528SMauro Carvalho Chehab 	/* AGCInit() not available for DVBT; init done in microcode */
3017cd7a67a4SMauro Carvalho Chehab 	if (!is_qam(state)) {
30183a4398f5SMauro Carvalho Chehab 		pr_err("%s: mode %d is not DVB-C\n",
30193a4398f5SMauro Carvalho Chehab 		       __func__, state->m_operation_mode);
30209a0bf528SMauro Carvalho Chehab 		return -EINVAL;
30219a0bf528SMauro Carvalho Chehab 	}
30229a0bf528SMauro Carvalho Chehab 
30239a0bf528SMauro Carvalho Chehab 	/* FIXME: Analog TV AGC require different settings */
30249a0bf528SMauro Carvalho Chehab 
30259a0bf528SMauro Carvalho Chehab 	/* Standard specific settings */
3026cd7a67a4SMauro Carvalho Chehab 	clp_sum_min = 8;
3027cd7a67a4SMauro Carvalho Chehab 	clp_dir_to = (u16) -9;
3028cd7a67a4SMauro Carvalho Chehab 	clp_ctrl_mode = 0;
3029cd7a67a4SMauro Carvalho Chehab 	sns_sum_min = 8;
3030cd7a67a4SMauro Carvalho Chehab 	sns_dir_to = (u16) -9;
3031cd7a67a4SMauro Carvalho Chehab 	ki_innergain_min = (u16) -1030;
3032cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_max = 0x2380;
3033cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt = 0x2380;
3034cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_min = 0x0511;
3035cd7a67a4SMauro Carvalho Chehab 	ingain_tgt = 0x0511;
3036cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_max = 5119;
3037cd7a67a4SMauro Carvalho Chehab 	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
30389a0bf528SMauro Carvalho Chehab 
3039ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3040ab5060cdSMauro Carvalho Chehab 			 fast_clp_ctrl_delay);
30419a0bf528SMauro Carvalho Chehab 	if (status < 0)
30429a0bf528SMauro Carvalho Chehab 		goto error;
30439a0bf528SMauro Carvalho Chehab 
3044cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
30459a0bf528SMauro Carvalho Chehab 	if (status < 0)
30469a0bf528SMauro Carvalho Chehab 		goto error;
3047cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
30489a0bf528SMauro Carvalho Chehab 	if (status < 0)
30499a0bf528SMauro Carvalho Chehab 		goto error;
3050cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
30519a0bf528SMauro Carvalho Chehab 	if (status < 0)
30529a0bf528SMauro Carvalho Chehab 		goto error;
3053cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
30549a0bf528SMauro Carvalho Chehab 	if (status < 0)
30559a0bf528SMauro Carvalho Chehab 		goto error;
3056ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3057ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_min);
30589a0bf528SMauro Carvalho Chehab 	if (status < 0)
30599a0bf528SMauro Carvalho Chehab 		goto error;
3060ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3061ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_max);
30629a0bf528SMauro Carvalho Chehab 	if (status < 0)
30639a0bf528SMauro Carvalho Chehab 		goto error;
30649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
30659a0bf528SMauro Carvalho Chehab 	if (status < 0)
30669a0bf528SMauro Carvalho Chehab 		goto error;
30679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
30689a0bf528SMauro Carvalho Chehab 	if (status < 0)
30699a0bf528SMauro Carvalho Chehab 		goto error;
30709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
30719a0bf528SMauro Carvalho Chehab 	if (status < 0)
30729a0bf528SMauro Carvalho Chehab 		goto error;
30739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
30749a0bf528SMauro Carvalho Chehab 	if (status < 0)
30759a0bf528SMauro Carvalho Chehab 		goto error;
3076cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
30779a0bf528SMauro Carvalho Chehab 	if (status < 0)
30789a0bf528SMauro Carvalho Chehab 		goto error;
3079cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
30809a0bf528SMauro Carvalho Chehab 	if (status < 0)
30819a0bf528SMauro Carvalho Chehab 		goto error;
30829a0bf528SMauro Carvalho Chehab 
3083ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3084ab5060cdSMauro Carvalho Chehab 			 ki_innergain_min);
30859a0bf528SMauro Carvalho Chehab 	if (status < 0)
30869a0bf528SMauro Carvalho Chehab 		goto error;
3087ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3088ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt);
30899a0bf528SMauro Carvalho Chehab 	if (status < 0)
30909a0bf528SMauro Carvalho Chehab 		goto error;
3091cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
30929a0bf528SMauro Carvalho Chehab 	if (status < 0)
30939a0bf528SMauro Carvalho Chehab 		goto error;
30949a0bf528SMauro Carvalho Chehab 
30959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
30969a0bf528SMauro Carvalho Chehab 	if (status < 0)
30979a0bf528SMauro Carvalho Chehab 		goto error;
30989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
30999a0bf528SMauro Carvalho Chehab 	if (status < 0)
31009a0bf528SMauro Carvalho Chehab 		goto error;
31019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
31029a0bf528SMauro Carvalho Chehab 	if (status < 0)
31039a0bf528SMauro Carvalho Chehab 		goto error;
31049a0bf528SMauro Carvalho Chehab 
31059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
31069a0bf528SMauro Carvalho Chehab 	if (status < 0)
31079a0bf528SMauro Carvalho Chehab 		goto error;
3108cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
31099a0bf528SMauro Carvalho Chehab 	if (status < 0)
31109a0bf528SMauro Carvalho Chehab 		goto error;
3111cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
31129a0bf528SMauro Carvalho Chehab 	if (status < 0)
31139a0bf528SMauro Carvalho Chehab 		goto error;
3114cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
31159a0bf528SMauro Carvalho Chehab 	if (status < 0)
31169a0bf528SMauro Carvalho Chehab 		goto error;
3117cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
31189a0bf528SMauro Carvalho Chehab 	if (status < 0)
31199a0bf528SMauro Carvalho Chehab 		goto error;
31209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
31219a0bf528SMauro Carvalho Chehab 	if (status < 0)
31229a0bf528SMauro Carvalho Chehab 		goto error;
31239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
31249a0bf528SMauro Carvalho Chehab 	if (status < 0)
31259a0bf528SMauro Carvalho Chehab 		goto error;
31269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
31279a0bf528SMauro Carvalho Chehab 	if (status < 0)
31289a0bf528SMauro Carvalho Chehab 		goto error;
31299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
31309a0bf528SMauro Carvalho Chehab 	if (status < 0)
31319a0bf528SMauro Carvalho Chehab 		goto error;
31329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
31339a0bf528SMauro Carvalho Chehab 	if (status < 0)
31349a0bf528SMauro Carvalho Chehab 		goto error;
31359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
31369a0bf528SMauro Carvalho Chehab 	if (status < 0)
31379a0bf528SMauro Carvalho Chehab 		goto error;
31389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
31399a0bf528SMauro Carvalho Chehab 	if (status < 0)
31409a0bf528SMauro Carvalho Chehab 		goto error;
31419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
31429a0bf528SMauro Carvalho Chehab 	if (status < 0)
31439a0bf528SMauro Carvalho Chehab 		goto error;
31449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
31459a0bf528SMauro Carvalho Chehab 	if (status < 0)
31469a0bf528SMauro Carvalho Chehab 		goto error;
31479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
31489a0bf528SMauro Carvalho Chehab 	if (status < 0)
31499a0bf528SMauro Carvalho Chehab 		goto error;
31509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
31519a0bf528SMauro Carvalho Chehab 	if (status < 0)
31529a0bf528SMauro Carvalho Chehab 		goto error;
31539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
31549a0bf528SMauro Carvalho Chehab 	if (status < 0)
31559a0bf528SMauro Carvalho Chehab 		goto error;
31569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
31579a0bf528SMauro Carvalho Chehab 	if (status < 0)
31589a0bf528SMauro Carvalho Chehab 		goto error;
31599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
31609a0bf528SMauro Carvalho Chehab 	if (status < 0)
31619a0bf528SMauro Carvalho Chehab 		goto error;
31629a0bf528SMauro Carvalho Chehab 
31639a0bf528SMauro Carvalho Chehab 	/* Initialize inner-loop KI gain factors */
31649a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_AGC_KI__A, &data);
31659a0bf528SMauro Carvalho Chehab 	if (status < 0)
31669a0bf528SMauro Carvalho Chehab 		goto error;
31679a0bf528SMauro Carvalho Chehab 
31689a0bf528SMauro Carvalho Chehab 	data = 0x0657;
31699a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_RF__M;
31709a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
31719a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_IF__M;
31729a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
31739a0bf528SMauro Carvalho Chehab 
31749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI__A, data);
31759a0bf528SMauro Carvalho Chehab error:
31769a0bf528SMauro Carvalho Chehab 	if (status < 0)
31773a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
31789a0bf528SMauro Carvalho Chehab 	return status;
31799a0bf528SMauro Carvalho Chehab }
31809a0bf528SMauro Carvalho Chehab 
3181cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
31829a0bf528SMauro Carvalho Chehab {
31839a0bf528SMauro Carvalho Chehab 	int status;
31849a0bf528SMauro Carvalho Chehab 
31859a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3186cd7a67a4SMauro Carvalho Chehab 	if (packet_err == NULL)
31879a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
31889a0bf528SMauro Carvalho Chehab 	else
3189ab5060cdSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3190ab5060cdSMauro Carvalho Chehab 				packet_err);
31919a0bf528SMauro Carvalho Chehab 	if (status < 0)
31923a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
31939a0bf528SMauro Carvalho Chehab 	return status;
31949a0bf528SMauro Carvalho Chehab }
31959a0bf528SMauro Carvalho Chehab 
3196cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state,
31979a0bf528SMauro Carvalho Chehab 			 u16 cmd, u16 subcmd,
31989a0bf528SMauro Carvalho Chehab 			 u16 param0, u16 param1, u16 param2,
31999a0bf528SMauro Carvalho Chehab 			 u16 param3, u16 param4)
32009a0bf528SMauro Carvalho Chehab {
3201cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
3202cd7a67a4SMauro Carvalho Chehab 	u16 err_code = 0;
3203cd7a67a4SMauro Carvalho Chehab 	u16 retry_cnt = 0;
3204cd7a67a4SMauro Carvalho Chehab 	u16 sc_exec = 0;
32059a0bf528SMauro Carvalho Chehab 	int status;
32069a0bf528SMauro Carvalho Chehab 
32079a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3208cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3209cd7a67a4SMauro Carvalho Chehab 	if (sc_exec != 1) {
32109a0bf528SMauro Carvalho Chehab 		/* SC is not running */
32119a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32129a0bf528SMauro Carvalho Chehab 	}
32139a0bf528SMauro Carvalho Chehab 	if (status < 0)
32149a0bf528SMauro Carvalho Chehab 		goto error;
32159a0bf528SMauro Carvalho Chehab 
32169a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready to receive command */
3217cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32189a0bf528SMauro Carvalho Chehab 	do {
3219b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3220cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3221cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3222cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3223cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32249a0bf528SMauro Carvalho Chehab 		goto error;
32259a0bf528SMauro Carvalho Chehab 
32269a0bf528SMauro Carvalho Chehab 	/* Write sub-command */
32279a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32289a0bf528SMauro Carvalho Chehab 		/* All commands using sub-cmd */
32299a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32309a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32319a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32329a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
32339a0bf528SMauro Carvalho Chehab 		if (status < 0)
32349a0bf528SMauro Carvalho Chehab 			goto error;
32359a0bf528SMauro Carvalho Chehab 		break;
32369a0bf528SMauro Carvalho Chehab 	default:
32379a0bf528SMauro Carvalho Chehab 		/* Do nothing */
32389a0bf528SMauro Carvalho Chehab 		break;
32399a0bf528SMauro Carvalho Chehab 	}
32409a0bf528SMauro Carvalho Chehab 
32419a0bf528SMauro Carvalho Chehab 	/* Write needed parameters and the command */
32422f60f13cSMauro Carvalho Chehab 	status = 0;
32439a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32449a0bf528SMauro Carvalho Chehab 		/* All commands using 5 parameters */
32459a0bf528SMauro Carvalho Chehab 		/* All commands using 4 parameters */
32469a0bf528SMauro Carvalho Chehab 		/* All commands using 3 parameters */
32479a0bf528SMauro Carvalho Chehab 		/* All commands using 2 parameters */
32489a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32499a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32509a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32512f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
3252df561f66SGustavo A. R. Silva 		fallthrough;	/* All commands using 1 parameters */
32539a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32549a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32552f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
3256df561f66SGustavo A. R. Silva 		fallthrough;	/* All commands using 0 parameters */
32579a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32589a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
32599a0bf528SMauro Carvalho Chehab 		/* Write command */
32602f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
32619a0bf528SMauro Carvalho Chehab 		break;
32629a0bf528SMauro Carvalho Chehab 	default:
32639a0bf528SMauro Carvalho Chehab 		/* Unknown command */
32649a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32659a0bf528SMauro Carvalho Chehab 	}
32669a0bf528SMauro Carvalho Chehab 	if (status < 0)
32679a0bf528SMauro Carvalho Chehab 		goto error;
32689a0bf528SMauro Carvalho Chehab 
32699a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready processing command */
3270cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32719a0bf528SMauro Carvalho Chehab 	do {
3272b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3273cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3274cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3275cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3276cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32779a0bf528SMauro Carvalho Chehab 		goto error;
32789a0bf528SMauro Carvalho Chehab 
32799a0bf528SMauro Carvalho Chehab 	/* Check for illegal cmd */
3280cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3281cd7a67a4SMauro Carvalho Chehab 	if (err_code == 0xFFFF) {
32829a0bf528SMauro Carvalho Chehab 		/* illegal command */
32839a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32849a0bf528SMauro Carvalho Chehab 	}
32859a0bf528SMauro Carvalho Chehab 	if (status < 0)
32869a0bf528SMauro Carvalho Chehab 		goto error;
32879a0bf528SMauro Carvalho Chehab 
328839c1cb2bSJonathan McCrohan 	/* Retrieve results parameters from SC */
32899a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32909a0bf528SMauro Carvalho Chehab 		/* All commands yielding 5 results */
32919a0bf528SMauro Carvalho Chehab 		/* All commands yielding 4 results */
32929a0bf528SMauro Carvalho Chehab 		/* All commands yielding 3 results */
32939a0bf528SMauro Carvalho Chehab 		/* All commands yielding 2 results */
32949a0bf528SMauro Carvalho Chehab 		/* All commands yielding 1 result */
32959a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32969a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32979a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
32989a0bf528SMauro Carvalho Chehab 		/* All commands yielding 0 results */
32999a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
33009a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_TIMER:
33019a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
33029a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
33039a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
33049a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
33059a0bf528SMauro Carvalho Chehab 		break;
33069a0bf528SMauro Carvalho Chehab 	default:
33079a0bf528SMauro Carvalho Chehab 		/* Unknown command */
33089a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33099a0bf528SMauro Carvalho Chehab 		break;
33109a0bf528SMauro Carvalho Chehab 	}			/* switch (cmd->cmd) */
33119a0bf528SMauro Carvalho Chehab error:
33129a0bf528SMauro Carvalho Chehab 	if (status < 0)
33133a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33149a0bf528SMauro Carvalho Chehab 	return status;
33159a0bf528SMauro Carvalho Chehab }
33169a0bf528SMauro Carvalho Chehab 
3317cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state)
33189a0bf528SMauro Carvalho Chehab {
3319cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRX_POWER_UP;
33209a0bf528SMauro Carvalho Chehab 	int status;
33219a0bf528SMauro Carvalho Chehab 
33229a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3323cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
33249a0bf528SMauro Carvalho Chehab 	if (status < 0)
33253a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33269a0bf528SMauro Carvalho Chehab 	return status;
33279a0bf528SMauro Carvalho Chehab }
33289a0bf528SMauro Carvalho Chehab 
3329cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
33309a0bf528SMauro Carvalho Chehab {
33319a0bf528SMauro Carvalho Chehab 	int status;
33329a0bf528SMauro Carvalho Chehab 
33339a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33345a7f7b79SMauro Carvalho Chehab 	if (*enabled)
33359a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
33369a0bf528SMauro Carvalho Chehab 	else
33379a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
33389a0bf528SMauro Carvalho Chehab 	if (status < 0)
33393a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33409a0bf528SMauro Carvalho Chehab 	return status;
33419a0bf528SMauro Carvalho Chehab }
33429a0bf528SMauro Carvalho Chehab 
33439a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K     4000
3344cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
33459a0bf528SMauro Carvalho Chehab {
33469a0bf528SMauro Carvalho Chehab 
33479a0bf528SMauro Carvalho Chehab 	int status;
33489a0bf528SMauro Carvalho Chehab 
33499a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33505a7f7b79SMauro Carvalho Chehab 	if (*enabled) {
33519a0bf528SMauro Carvalho Chehab 		/* write mask to 1 */
33529a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
33539a0bf528SMauro Carvalho Chehab 				   DEFAULT_FR_THRES_8K);
33549a0bf528SMauro Carvalho Chehab 	} else {
33559a0bf528SMauro Carvalho Chehab 		/* write mask to 0 */
33569a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
33579a0bf528SMauro Carvalho Chehab 	}
33589a0bf528SMauro Carvalho Chehab 	if (status < 0)
33593a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33609a0bf528SMauro Carvalho Chehab 
33619a0bf528SMauro Carvalho Chehab 	return status;
33629a0bf528SMauro Carvalho Chehab }
33639a0bf528SMauro Carvalho Chehab 
3364cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3365cd7a67a4SMauro Carvalho Chehab 				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
33669a0bf528SMauro Carvalho Chehab {
33679a0bf528SMauro Carvalho Chehab 	u16 data = 0;
33689a0bf528SMauro Carvalho Chehab 	int status;
33699a0bf528SMauro Carvalho Chehab 
33709a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33719a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
33729a0bf528SMauro Carvalho Chehab 	if (status < 0)
33739a0bf528SMauro Carvalho Chehab 		goto error;
33749a0bf528SMauro Carvalho Chehab 
3375cd7a67a4SMauro Carvalho Chehab 	switch (echo_thres->fft_mode) {
33769a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_2K:
33779a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3378cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
33799a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
33809a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
33819a0bf528SMauro Carvalho Chehab 		break;
33829a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_8K:
33839a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3384cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
33859a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
33869a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
33879a0bf528SMauro Carvalho Chehab 		break;
33889a0bf528SMauro Carvalho Chehab 	default:
33899a0bf528SMauro Carvalho Chehab 		return -EINVAL;
33909a0bf528SMauro Carvalho Chehab 	}
33919a0bf528SMauro Carvalho Chehab 
33929a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
33939a0bf528SMauro Carvalho Chehab error:
33949a0bf528SMauro Carvalho Chehab 	if (status < 0)
33953a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33969a0bf528SMauro Carvalho Chehab 	return status;
33979a0bf528SMauro Carvalho Chehab }
33989a0bf528SMauro Carvalho Chehab 
3399cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3400cd7a67a4SMauro Carvalho Chehab 			       enum drxk_cfg_dvbt_sqi_speed *speed)
34019a0bf528SMauro Carvalho Chehab {
34029a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
34039a0bf528SMauro Carvalho Chehab 
34049a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34059a0bf528SMauro Carvalho Chehab 
34069a0bf528SMauro Carvalho Chehab 	switch (*speed) {
34079a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_FAST:
34089a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_MEDIUM:
34099a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_SLOW:
34109a0bf528SMauro Carvalho Chehab 		break;
34119a0bf528SMauro Carvalho Chehab 	default:
34129a0bf528SMauro Carvalho Chehab 		goto error;
34139a0bf528SMauro Carvalho Chehab 	}
34149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
34159a0bf528SMauro Carvalho Chehab 			   (u16) *speed);
34169a0bf528SMauro Carvalho Chehab error:
34179a0bf528SMauro Carvalho Chehab 	if (status < 0)
34183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34199a0bf528SMauro Carvalho Chehab 	return status;
34209a0bf528SMauro Carvalho Chehab }
34219a0bf528SMauro Carvalho Chehab 
34229a0bf528SMauro Carvalho Chehab /*============================================================================*/
34239a0bf528SMauro Carvalho Chehab 
342434eb9751SMauro Carvalho Chehab /*
34259a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
34269a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34279a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34289a0bf528SMauro Carvalho Chehab *
34299a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
34309a0bf528SMauro Carvalho Chehab *
34319a0bf528SMauro Carvalho Chehab */
3432cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state)
34339a0bf528SMauro Carvalho Chehab {
34349a0bf528SMauro Carvalho Chehab 	int status;
34359a0bf528SMauro Carvalho Chehab 	bool setincenable = false;
34369a0bf528SMauro Carvalho Chehab 	bool setfrenable = true;
34379a0bf528SMauro Carvalho Chehab 
3438cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3439cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
34409a0bf528SMauro Carvalho Chehab 
34419a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3442cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
34439a0bf528SMauro Carvalho Chehab 	if (status < 0)
34449a0bf528SMauro Carvalho Chehab 		goto error;
3445cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
34469a0bf528SMauro Carvalho Chehab 	if (status < 0)
34479a0bf528SMauro Carvalho Chehab 		goto error;
3448cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
34499a0bf528SMauro Carvalho Chehab 	if (status < 0)
34509a0bf528SMauro Carvalho Chehab 		goto error;
3451cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
34529a0bf528SMauro Carvalho Chehab 	if (status < 0)
34539a0bf528SMauro Carvalho Chehab 		goto error;
3454ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3455ab5060cdSMauro Carvalho Chehab 			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
34569a0bf528SMauro Carvalho Chehab error:
34579a0bf528SMauro Carvalho Chehab 	if (status < 0)
34583a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34599a0bf528SMauro Carvalho Chehab 	return status;
34609a0bf528SMauro Carvalho Chehab }
34619a0bf528SMauro Carvalho Chehab 
34629a0bf528SMauro Carvalho Chehab /*============================================================================*/
34639a0bf528SMauro Carvalho Chehab 
346434eb9751SMauro Carvalho Chehab /*
34659a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
34669a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34679a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34689a0bf528SMauro Carvalho Chehab *
34699a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
34709a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
34719a0bf528SMauro Carvalho Chehab */
3472cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
3473cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode)
34749a0bf528SMauro Carvalho Chehab {
3475cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
34769a0bf528SMauro Carvalho Chehab 	u16 data = 0;
34779a0bf528SMauro Carvalho Chehab 	int status;
34789a0bf528SMauro Carvalho Chehab 
34799a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34809a0bf528SMauro Carvalho Chehab 
3481cd7a67a4SMauro Carvalho Chehab 	power_up_dvbt(state);
34829a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
3483cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_dvbt(state);
34849a0bf528SMauro Carvalho Chehab 	/* send OFDM reset command */
3485ab5060cdSMauro Carvalho Chehab 	status = scu_command(state,
3486ab5060cdSMauro Carvalho Chehab 			     SCU_RAM_COMMAND_STANDARD_OFDM
3487ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3488ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
34899a0bf528SMauro Carvalho Chehab 	if (status < 0)
34909a0bf528SMauro Carvalho Chehab 		goto error;
34919a0bf528SMauro Carvalho Chehab 
34929a0bf528SMauro Carvalho Chehab 	/* send OFDM setenv command */
3493ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3494ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3495ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
34969a0bf528SMauro Carvalho Chehab 	if (status < 0)
34979a0bf528SMauro Carvalho Chehab 		goto error;
34989a0bf528SMauro Carvalho Chehab 
34999a0bf528SMauro Carvalho Chehab 	/* reset datapath for OFDM, processors first */
35009a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
35019a0bf528SMauro Carvalho Chehab 	if (status < 0)
35029a0bf528SMauro Carvalho Chehab 		goto error;
35039a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
35049a0bf528SMauro Carvalho Chehab 	if (status < 0)
35059a0bf528SMauro Carvalho Chehab 		goto error;
35069a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
35079a0bf528SMauro Carvalho Chehab 	if (status < 0)
35089a0bf528SMauro Carvalho Chehab 		goto error;
35099a0bf528SMauro Carvalho Chehab 
35109a0bf528SMauro Carvalho Chehab 	/* IQM setup */
35119a0bf528SMauro Carvalho Chehab 	/* synchronize on ofdstate->m_festart */
35129a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 1);
35139a0bf528SMauro Carvalho Chehab 	if (status < 0)
35149a0bf528SMauro Carvalho Chehab 		goto error;
35159a0bf528SMauro Carvalho Chehab 	/* window size for clipping ADC detection */
35169a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
35179a0bf528SMauro Carvalho Chehab 	if (status < 0)
35189a0bf528SMauro Carvalho Chehab 		goto error;
35199a0bf528SMauro Carvalho Chehab 	/* window size for for sense pre-SAW detection */
35209a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
35219a0bf528SMauro Carvalho Chehab 	if (status < 0)
35229a0bf528SMauro Carvalho Chehab 		goto error;
35239a0bf528SMauro Carvalho Chehab 	/* sense threshold for sense pre-SAW detection */
35249a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
35259a0bf528SMauro Carvalho Chehab 	if (status < 0)
35269a0bf528SMauro Carvalho Chehab 		goto error;
3527cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
35289a0bf528SMauro Carvalho Chehab 	if (status < 0)
35299a0bf528SMauro Carvalho Chehab 		goto error;
35309a0bf528SMauro Carvalho Chehab 
35319a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AGC_RF__A, 0);
35329a0bf528SMauro Carvalho Chehab 	if (status < 0)
35339a0bf528SMauro Carvalho Chehab 		goto error;
35349a0bf528SMauro Carvalho Chehab 
35359a0bf528SMauro Carvalho Chehab 	/* Impulse noise cruncher setup */
35369a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_LCT__A, 0);	/* crunch in IQM_CF */
35379a0bf528SMauro Carvalho Chehab 	if (status < 0)
35389a0bf528SMauro Carvalho Chehab 		goto error;
35399a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);	/* detect in IQM_CF */
35409a0bf528SMauro Carvalho Chehab 	if (status < 0)
35419a0bf528SMauro Carvalho Chehab 		goto error;
35429a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 3);	/* peak detector window length */
35439a0bf528SMauro Carvalho Chehab 	if (status < 0)
35449a0bf528SMauro Carvalho Chehab 		goto error;
35459a0bf528SMauro Carvalho Chehab 
35469a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 16);
35479a0bf528SMauro Carvalho Chehab 	if (status < 0)
35489a0bf528SMauro Carvalho Chehab 		goto error;
35499a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
35509a0bf528SMauro Carvalho Chehab 	if (status < 0)
35519a0bf528SMauro Carvalho Chehab 		goto error;
35529a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
35539a0bf528SMauro Carvalho Chehab 	if (status < 0)
35549a0bf528SMauro Carvalho Chehab 		goto error;
35559a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE__A, 1600);
35569a0bf528SMauro Carvalho Chehab 	if (status < 0)
35579a0bf528SMauro Carvalho Chehab 		goto error;
35589a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, 0);
35599a0bf528SMauro Carvalho Chehab 	if (status < 0)
35609a0bf528SMauro Carvalho Chehab 		goto error;
35619a0bf528SMauro Carvalho Chehab 
35629a0bf528SMauro Carvalho Chehab 	/* virtual clipping threshold for clipping ADC detection */
35639a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
35649a0bf528SMauro Carvalho Chehab 	if (status < 0)
35659a0bf528SMauro Carvalho Chehab 		goto error;
35669a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 495);	/* crunching threshold */
35679a0bf528SMauro Carvalho Chehab 	if (status < 0)
35689a0bf528SMauro Carvalho Chehab 		goto error;
35699a0bf528SMauro Carvalho Chehab 
3570ab5060cdSMauro Carvalho Chehab 	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3571ab5060cdSMauro Carvalho Chehab 			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
35729a0bf528SMauro Carvalho Chehab 	if (status < 0)
35739a0bf528SMauro Carvalho Chehab 		goto error;
35749a0bf528SMauro Carvalho Chehab 
35759a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 2);	/* peak detector threshold */
35769a0bf528SMauro Carvalho Chehab 	if (status < 0)
35779a0bf528SMauro Carvalho Chehab 		goto error;
35789a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
35799a0bf528SMauro Carvalho Chehab 	if (status < 0)
35809a0bf528SMauro Carvalho Chehab 		goto error;
35819a0bf528SMauro Carvalho Chehab 	/* enable power measurement interrupt */
35829a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
35839a0bf528SMauro Carvalho Chehab 	if (status < 0)
35849a0bf528SMauro Carvalho Chehab 		goto error;
35859a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
35869a0bf528SMauro Carvalho Chehab 	if (status < 0)
35879a0bf528SMauro Carvalho Chehab 		goto error;
35889a0bf528SMauro Carvalho Chehab 
35899a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
3590cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
35919a0bf528SMauro Carvalho Chehab 	if (status < 0)
35929a0bf528SMauro Carvalho Chehab 		goto error;
3593cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
35949a0bf528SMauro Carvalho Chehab 	if (status < 0)
35959a0bf528SMauro Carvalho Chehab 		goto error;
35969a0bf528SMauro Carvalho Chehab 
35979a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
35989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
35999a0bf528SMauro Carvalho Chehab 	if (status < 0)
36009a0bf528SMauro Carvalho Chehab 		goto error;
36019a0bf528SMauro Carvalho Chehab 
3602cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
36039a0bf528SMauro Carvalho Chehab 	if (status < 0)
36049a0bf528SMauro Carvalho Chehab 		goto error;
3605cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
36069a0bf528SMauro Carvalho Chehab 	if (status < 0)
36079a0bf528SMauro Carvalho Chehab 		goto error;
36089a0bf528SMauro Carvalho Chehab 
36099a0bf528SMauro Carvalho Chehab 	/* Set Noise Estimation notch width and enable DC fix */
36109a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
36119a0bf528SMauro Carvalho Chehab 	if (status < 0)
36129a0bf528SMauro Carvalho Chehab 		goto error;
36139a0bf528SMauro Carvalho Chehab 	data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
36149a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
36159a0bf528SMauro Carvalho Chehab 	if (status < 0)
36169a0bf528SMauro Carvalho Chehab 		goto error;
36179a0bf528SMauro Carvalho Chehab 
36189a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
36199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
36209a0bf528SMauro Carvalho Chehab 	if (status < 0)
36219a0bf528SMauro Carvalho Chehab 		goto error;
36229a0bf528SMauro Carvalho Chehab 
3623cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code) {
3624cd7a67a4SMauro Carvalho Chehab 		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
3625ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3626ab5060cdSMauro Carvalho Chehab 				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
36279a0bf528SMauro Carvalho Chehab 		if (status < 0)
36289a0bf528SMauro Carvalho Chehab 			goto error;
36299a0bf528SMauro Carvalho Chehab 	}
36309a0bf528SMauro Carvalho Chehab 
36319a0bf528SMauro Carvalho Chehab 	/* OFDM_SC setup */
36329a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36339a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
36349a0bf528SMauro Carvalho Chehab 	if (status < 0)
36359a0bf528SMauro Carvalho Chehab 		goto error;
36369a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
36379a0bf528SMauro Carvalho Chehab 	if (status < 0)
36389a0bf528SMauro Carvalho Chehab 		goto error;
36399a0bf528SMauro Carvalho Chehab #endif
36409a0bf528SMauro Carvalho Chehab 
36419a0bf528SMauro Carvalho Chehab 	/* FEC setup */
36429a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_INPUT_CTL__A, 1);	/* OFDM input */
36439a0bf528SMauro Carvalho Chehab 	if (status < 0)
36449a0bf528SMauro Carvalho Chehab 		goto error;
36459a0bf528SMauro Carvalho Chehab 
36469a0bf528SMauro Carvalho Chehab 
36479a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36489a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
36499a0bf528SMauro Carvalho Chehab 	if (status < 0)
36509a0bf528SMauro Carvalho Chehab 		goto error;
36519a0bf528SMauro Carvalho Chehab #else
36529a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
36539a0bf528SMauro Carvalho Chehab 	if (status < 0)
36549a0bf528SMauro Carvalho Chehab 		goto error;
36559a0bf528SMauro Carvalho Chehab #endif
36569a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
36579a0bf528SMauro Carvalho Chehab 	if (status < 0)
36589a0bf528SMauro Carvalho Chehab 		goto error;
36599a0bf528SMauro Carvalho Chehab 
36609a0bf528SMauro Carvalho Chehab 	/* Setup MPEG bus */
3661cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, OM_DVBT);
36629a0bf528SMauro Carvalho Chehab 	if (status < 0)
36639a0bf528SMauro Carvalho Chehab 		goto error;
36649a0bf528SMauro Carvalho Chehab 	/* Set DVBT Presets */
3665cd7a67a4SMauro Carvalho Chehab 	status = dvbt_activate_presets(state);
36669a0bf528SMauro Carvalho Chehab 	if (status < 0)
36679a0bf528SMauro Carvalho Chehab 		goto error;
36689a0bf528SMauro Carvalho Chehab 
36699a0bf528SMauro Carvalho Chehab error:
36709a0bf528SMauro Carvalho Chehab 	if (status < 0)
36713a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
36729a0bf528SMauro Carvalho Chehab 	return status;
36739a0bf528SMauro Carvalho Chehab }
36749a0bf528SMauro Carvalho Chehab 
36759a0bf528SMauro Carvalho Chehab /*============================================================================*/
367634eb9751SMauro Carvalho Chehab /*
3677cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel.
36789a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
36799a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
36809a0bf528SMauro Carvalho Chehab */
3681cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state)
36829a0bf528SMauro Carvalho Chehab {
36839a0bf528SMauro Carvalho Chehab 	u16 param1;
36849a0bf528SMauro Carvalho Chehab 	int status;
3685cd7a67a4SMauro Carvalho Chehab 	/* drxk_ofdm_sc_cmd_t scCmd; */
36869a0bf528SMauro Carvalho Chehab 
36879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3688cd7a67a4SMauro Carvalho Chehab 	/* start correct processes to get in lock */
36899a0bf528SMauro Carvalho Chehab 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
36909a0bf528SMauro Carvalho Chehab 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3691ab5060cdSMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3692ab5060cdSMauro Carvalho Chehab 				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3693ab5060cdSMauro Carvalho Chehab 				 0, 0, 0);
36949a0bf528SMauro Carvalho Chehab 	if (status < 0)
36959a0bf528SMauro Carvalho Chehab 		goto error;
3696cd7a67a4SMauro Carvalho Chehab 	/* start FEC OC */
3697cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
36989a0bf528SMauro Carvalho Chehab 	if (status < 0)
36999a0bf528SMauro Carvalho Chehab 		goto error;
37009a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
37019a0bf528SMauro Carvalho Chehab 	if (status < 0)
37029a0bf528SMauro Carvalho Chehab 		goto error;
37039a0bf528SMauro Carvalho Chehab error:
37049a0bf528SMauro Carvalho Chehab 	if (status < 0)
37053a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
37069a0bf528SMauro Carvalho Chehab 	return status;
37079a0bf528SMauro Carvalho Chehab }
37089a0bf528SMauro Carvalho Chehab 
37099a0bf528SMauro Carvalho Chehab 
37109a0bf528SMauro Carvalho Chehab /*============================================================================*/
37119a0bf528SMauro Carvalho Chehab 
371234eb9751SMauro Carvalho Chehab /*
37139a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
37149a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37159a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37169a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
37179a0bf528SMauro Carvalho Chehab */
3718cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3719cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset)
37209a0bf528SMauro Carvalho Chehab {
3721cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
3722cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
3723cd7a67a4SMauro Carvalho Chehab 	u16 operation_mode = 0;
3724cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate_ofs = 0;
37259a0bf528SMauro Carvalho Chehab 	u32 bandwidth = 0;
37269a0bf528SMauro Carvalho Chehab 	u16 param1;
37279a0bf528SMauro Carvalho Chehab 	int status;
37289a0bf528SMauro Carvalho Chehab 
3729ab5060cdSMauro Carvalho Chehab 	dprintk(1, "IF =%d, TFO = %d\n",
3730ab5060cdSMauro Carvalho Chehab 		intermediate_freqk_hz, tuner_freq_offset);
37319a0bf528SMauro Carvalho Chehab 
3732ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3733ab5060cdSMauro Carvalho Chehab 			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3734ab5060cdSMauro Carvalho Chehab 			    0, NULL, 1, &cmd_result);
37359a0bf528SMauro Carvalho Chehab 	if (status < 0)
37369a0bf528SMauro Carvalho Chehab 		goto error;
37379a0bf528SMauro Carvalho Chehab 
37389a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
37399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
37409a0bf528SMauro Carvalho Chehab 	if (status < 0)
37419a0bf528SMauro Carvalho Chehab 		goto error;
37429a0bf528SMauro Carvalho Chehab 
37439a0bf528SMauro Carvalho Chehab 	/* Stop processors */
37449a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
37459a0bf528SMauro Carvalho Chehab 	if (status < 0)
37469a0bf528SMauro Carvalho Chehab 		goto error;
37479a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
37489a0bf528SMauro Carvalho Chehab 	if (status < 0)
37499a0bf528SMauro Carvalho Chehab 		goto error;
37509a0bf528SMauro Carvalho Chehab 
37519a0bf528SMauro Carvalho Chehab 	/* Mandatory fix, always stop CP, required to set spl offset back to
37529a0bf528SMauro Carvalho Chehab 		hardware default (is set to 0 by ucode during pilot detection */
37539a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
37549a0bf528SMauro Carvalho Chehab 	if (status < 0)
37559a0bf528SMauro Carvalho Chehab 		goto error;
37569a0bf528SMauro Carvalho Chehab 
3757ab5060cdSMauro Carvalho Chehab 	/*== Write channel settings to device ================================*/
37589a0bf528SMauro Carvalho Chehab 
37599a0bf528SMauro Carvalho Chehab 	/* mode */
37609a0bf528SMauro Carvalho Chehab 	switch (state->props.transmission_mode) {
37619a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_AUTO:
37629a0bf528SMauro Carvalho Chehab 	default:
3763cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3764df561f66SGustavo A. R. Silva 		fallthrough;	/* try first guess DRX_FFTMODE_8K */
37659a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_8K:
3766cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
37679a0bf528SMauro Carvalho Chehab 		break;
37689a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_2K:
3769cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
37709a0bf528SMauro Carvalho Chehab 		break;
37719a0bf528SMauro Carvalho Chehab 	}
37729a0bf528SMauro Carvalho Chehab 
37739a0bf528SMauro Carvalho Chehab 	/* guard */
37749a0bf528SMauro Carvalho Chehab 	switch (state->props.guard_interval) {
37759a0bf528SMauro Carvalho Chehab 	default:
37769a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_AUTO:
3777cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3778df561f66SGustavo A. R. Silva 		fallthrough;	/* try first guess DRX_GUARD_1DIV4 */
37799a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_4:
3780cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
37819a0bf528SMauro Carvalho Chehab 		break;
37829a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_32:
3783cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
37849a0bf528SMauro Carvalho Chehab 		break;
37859a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_16:
3786cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
37879a0bf528SMauro Carvalho Chehab 		break;
37889a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_8:
3789cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
37909a0bf528SMauro Carvalho Chehab 		break;
37919a0bf528SMauro Carvalho Chehab 	}
37929a0bf528SMauro Carvalho Chehab 
37939a0bf528SMauro Carvalho Chehab 	/* hierarchy */
37949a0bf528SMauro Carvalho Chehab 	switch (state->props.hierarchy) {
37959a0bf528SMauro Carvalho Chehab 	case HIERARCHY_AUTO:
37969a0bf528SMauro Carvalho Chehab 	case HIERARCHY_NONE:
37979a0bf528SMauro Carvalho Chehab 	default:
3798cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
379906eeefe8SMauro Carvalho Chehab 		/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3800cd7a67a4SMauro Carvalho Chehab 		/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3801df561f66SGustavo A. R. Silva 		fallthrough;
38029a0bf528SMauro Carvalho Chehab 	case HIERARCHY_1:
3803cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
38049a0bf528SMauro Carvalho Chehab 		break;
38059a0bf528SMauro Carvalho Chehab 	case HIERARCHY_2:
3806cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
38079a0bf528SMauro Carvalho Chehab 		break;
38089a0bf528SMauro Carvalho Chehab 	case HIERARCHY_4:
3809cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
38109a0bf528SMauro Carvalho Chehab 		break;
38119a0bf528SMauro Carvalho Chehab 	}
38129a0bf528SMauro Carvalho Chehab 
38139a0bf528SMauro Carvalho Chehab 
38149a0bf528SMauro Carvalho Chehab 	/* modulation */
38159a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
38169a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
38179a0bf528SMauro Carvalho Chehab 	default:
3818cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3819df561f66SGustavo A. R. Silva 		fallthrough;	/* try first guess DRX_CONSTELLATION_QAM64 */
38209a0bf528SMauro Carvalho Chehab 	case QAM_64:
3821cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
38229a0bf528SMauro Carvalho Chehab 		break;
38239a0bf528SMauro Carvalho Chehab 	case QPSK:
3824cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
38259a0bf528SMauro Carvalho Chehab 		break;
38269a0bf528SMauro Carvalho Chehab 	case QAM_16:
3827cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
38289a0bf528SMauro Carvalho Chehab 		break;
38299a0bf528SMauro Carvalho Chehab 	}
38309a0bf528SMauro Carvalho Chehab #if 0
383139c1cb2bSJonathan McCrohan 	/* No hierarchical channels support in BDA */
38329a0bf528SMauro Carvalho Chehab 	/* Priority (only for hierarchical channels) */
38339a0bf528SMauro Carvalho Chehab 	switch (channel->priority) {
38349a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_LOW:
3835cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3836cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38379a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_LO);
38389a0bf528SMauro Carvalho Chehab 		break;
38399a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_HIGH:
3840cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3841cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38429a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_HI));
38439a0bf528SMauro Carvalho Chehab 		break;
3844df561f66SGustavo A. R. Silva 	case DRX_PRIORITY_UNKNOWN:
38459a0bf528SMauro Carvalho Chehab 	default:
38469a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
38479a0bf528SMauro Carvalho Chehab 		goto error;
38489a0bf528SMauro Carvalho Chehab 	}
38499a0bf528SMauro Carvalho Chehab #else
3850868c9a17SMauro Carvalho Chehab 	/* Set Priority high */
3851cd7a67a4SMauro Carvalho Chehab 	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
38529a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
38539a0bf528SMauro Carvalho Chehab 	if (status < 0)
38549a0bf528SMauro Carvalho Chehab 		goto error;
38559a0bf528SMauro Carvalho Chehab #endif
38569a0bf528SMauro Carvalho Chehab 
38579a0bf528SMauro Carvalho Chehab 	/* coderate */
38589a0bf528SMauro Carvalho Chehab 	switch (state->props.code_rate_HP) {
38599a0bf528SMauro Carvalho Chehab 	case FEC_AUTO:
38609a0bf528SMauro Carvalho Chehab 	default:
3861cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3862df561f66SGustavo A. R. Silva 		fallthrough;	/* try first guess DRX_CODERATE_2DIV3 */
38639a0bf528SMauro Carvalho Chehab 	case FEC_2_3:
3864cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
38659a0bf528SMauro Carvalho Chehab 		break;
38669a0bf528SMauro Carvalho Chehab 	case FEC_1_2:
3867cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
38689a0bf528SMauro Carvalho Chehab 		break;
38699a0bf528SMauro Carvalho Chehab 	case FEC_3_4:
3870cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
38719a0bf528SMauro Carvalho Chehab 		break;
38729a0bf528SMauro Carvalho Chehab 	case FEC_5_6:
3873cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
38749a0bf528SMauro Carvalho Chehab 		break;
38759a0bf528SMauro Carvalho Chehab 	case FEC_7_8:
3876cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
38779a0bf528SMauro Carvalho Chehab 		break;
38789a0bf528SMauro Carvalho Chehab 	}
38799a0bf528SMauro Carvalho Chehab 
3880ab5060cdSMauro Carvalho Chehab 	/*
3881868c9a17SMauro Carvalho Chehab 	 * SAW filter selection: normally not necessary, but if wanted
3882ab5060cdSMauro Carvalho Chehab 	 * the application can select a SAW filter via the driver by
3883ab5060cdSMauro Carvalho Chehab 	 * using UIOs
3884ab5060cdSMauro Carvalho Chehab 	 */
3885ab5060cdSMauro Carvalho Chehab 
38869a0bf528SMauro Carvalho Chehab 	/* First determine real bandwidth (Hz) */
38879a0bf528SMauro Carvalho Chehab 	/* Also set delay for impulse noise cruncher */
3888ab5060cdSMauro Carvalho Chehab 	/*
3889ab5060cdSMauro Carvalho Chehab 	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3890ab5060cdSMauro Carvalho Chehab 	 * changed by SC for fix for some 8K,1/8 guard but is restored by
3891ab5060cdSMauro Carvalho Chehab 	 * InitEC and ResetEC functions
3892ab5060cdSMauro Carvalho Chehab 	 */
38939a0bf528SMauro Carvalho Chehab 	switch (state->props.bandwidth_hz) {
38949a0bf528SMauro Carvalho Chehab 	case 0:
38959a0bf528SMauro Carvalho Chehab 		state->props.bandwidth_hz = 8000000;
3896df561f66SGustavo A. R. Silva 		fallthrough;
38979a0bf528SMauro Carvalho Chehab 	case 8000000:
38989a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3899ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3900ab5060cdSMauro Carvalho Chehab 				 3052);
39019a0bf528SMauro Carvalho Chehab 		if (status < 0)
39029a0bf528SMauro Carvalho Chehab 			goto error;
39039a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 8 MHz */
3904ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3905ab5060cdSMauro Carvalho Chehab 				 7);
39069a0bf528SMauro Carvalho Chehab 		if (status < 0)
39079a0bf528SMauro Carvalho Chehab 			goto error;
3908ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3909ab5060cdSMauro Carvalho Chehab 				 7);
39109a0bf528SMauro Carvalho Chehab 		if (status < 0)
39119a0bf528SMauro Carvalho Chehab 			goto error;
3912ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3913ab5060cdSMauro Carvalho Chehab 				 7);
39149a0bf528SMauro Carvalho Chehab 		if (status < 0)
39159a0bf528SMauro Carvalho Chehab 			goto error;
3916ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3917ab5060cdSMauro Carvalho Chehab 				 1);
39189a0bf528SMauro Carvalho Chehab 		if (status < 0)
39199a0bf528SMauro Carvalho Chehab 			goto error;
39209a0bf528SMauro Carvalho Chehab 		break;
39219a0bf528SMauro Carvalho Chehab 	case 7000000:
39229a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3923ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3924ab5060cdSMauro Carvalho Chehab 				 3491);
39259a0bf528SMauro Carvalho Chehab 		if (status < 0)
39269a0bf528SMauro Carvalho Chehab 			goto error;
39279a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 7 MHz */
3928ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3929ab5060cdSMauro Carvalho Chehab 				 8);
39309a0bf528SMauro Carvalho Chehab 		if (status < 0)
39319a0bf528SMauro Carvalho Chehab 			goto error;
3932ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3933ab5060cdSMauro Carvalho Chehab 				 8);
39349a0bf528SMauro Carvalho Chehab 		if (status < 0)
39359a0bf528SMauro Carvalho Chehab 			goto error;
3936ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3937ab5060cdSMauro Carvalho Chehab 				 4);
39389a0bf528SMauro Carvalho Chehab 		if (status < 0)
39399a0bf528SMauro Carvalho Chehab 			goto error;
3940ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3941ab5060cdSMauro Carvalho Chehab 				 1);
39429a0bf528SMauro Carvalho Chehab 		if (status < 0)
39439a0bf528SMauro Carvalho Chehab 			goto error;
39449a0bf528SMauro Carvalho Chehab 		break;
39459a0bf528SMauro Carvalho Chehab 	case 6000000:
39469a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3947ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3948ab5060cdSMauro Carvalho Chehab 				 4073);
39499a0bf528SMauro Carvalho Chehab 		if (status < 0)
39509a0bf528SMauro Carvalho Chehab 			goto error;
39519a0bf528SMauro Carvalho Chehab 		/* cochannel protection for NTSC 6 MHz */
3952ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3953ab5060cdSMauro Carvalho Chehab 				 19);
39549a0bf528SMauro Carvalho Chehab 		if (status < 0)
39559a0bf528SMauro Carvalho Chehab 			goto error;
3956ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3957ab5060cdSMauro Carvalho Chehab 				 19);
39589a0bf528SMauro Carvalho Chehab 		if (status < 0)
39599a0bf528SMauro Carvalho Chehab 			goto error;
3960ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3961ab5060cdSMauro Carvalho Chehab 				 14);
39629a0bf528SMauro Carvalho Chehab 		if (status < 0)
39639a0bf528SMauro Carvalho Chehab 			goto error;
3964ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3965ab5060cdSMauro Carvalho Chehab 				 1);
39669a0bf528SMauro Carvalho Chehab 		if (status < 0)
39679a0bf528SMauro Carvalho Chehab 			goto error;
39689a0bf528SMauro Carvalho Chehab 		break;
39699a0bf528SMauro Carvalho Chehab 	default:
39709a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
39719a0bf528SMauro Carvalho Chehab 		goto error;
39729a0bf528SMauro Carvalho Chehab 	}
39739a0bf528SMauro Carvalho Chehab 
3974cd7a67a4SMauro Carvalho Chehab 	if (iqm_rc_rate_ofs == 0) {
39759a0bf528SMauro Carvalho Chehab 		/* Now compute IQM_RC_RATE_OFS
39769a0bf528SMauro Carvalho Chehab 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
39779a0bf528SMauro Carvalho Chehab 			=>
39789a0bf528SMauro Carvalho Chehab 			((SysFreq / BandWidth) * (2^21)) - (2^23)
39799a0bf528SMauro Carvalho Chehab 			*/
39809a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^28)  */
3981ab5060cdSMauro Carvalho Chehab 		/*
3982ab5060cdSMauro Carvalho Chehab 		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
3983ab5060cdSMauro Carvalho Chehab 		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
3984ab5060cdSMauro Carvalho Chehab 		 *	=> assert(109714272 > 48000000) = true
3985ab5060cdSMauro Carvalho Chehab 		 * so Frac 28 can be used
3986ab5060cdSMauro Carvalho Chehab 		 */
3987cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = Frac28a((u32)
3988cd7a67a4SMauro Carvalho Chehab 					((state->m_sys_clock_freq *
39899a0bf528SMauro Carvalho Chehab 						1000) / 3), bandwidth);
39909a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3991cd7a67a4SMauro Carvalho Chehab 		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
3992cd7a67a4SMauro Carvalho Chehab 			iqm_rc_rate_ofs += 0x80L;
3993cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
39949a0bf528SMauro Carvalho Chehab 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
3995cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
39969a0bf528SMauro Carvalho Chehab 	}
39979a0bf528SMauro Carvalho Chehab 
3998cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate_ofs &=
39999a0bf528SMauro Carvalho Chehab 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
40009a0bf528SMauro Carvalho Chehab 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4001cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
40029a0bf528SMauro Carvalho Chehab 	if (status < 0)
40039a0bf528SMauro Carvalho Chehab 		goto error;
40049a0bf528SMauro Carvalho Chehab 
40059a0bf528SMauro Carvalho Chehab 	/* Bandwidth setting done */
40069a0bf528SMauro Carvalho Chehab 
40079a0bf528SMauro Carvalho Chehab #if 0
4008cd7a67a4SMauro Carvalho Chehab 	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
40099a0bf528SMauro Carvalho Chehab 	if (status < 0)
40109a0bf528SMauro Carvalho Chehab 		goto error;
40119a0bf528SMauro Carvalho Chehab #endif
4012ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
4013ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
40149a0bf528SMauro Carvalho Chehab 	if (status < 0)
40159a0bf528SMauro Carvalho Chehab 		goto error;
40169a0bf528SMauro Carvalho Chehab 
4017ab5060cdSMauro Carvalho Chehab 	/*== start SC, write channel settings to SC ==========================*/
40189a0bf528SMauro Carvalho Chehab 
40199a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
40209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
40219a0bf528SMauro Carvalho Chehab 	if (status < 0)
40229a0bf528SMauro Carvalho Chehab 		goto error;
40239a0bf528SMauro Carvalho Chehab 
40249a0bf528SMauro Carvalho Chehab 	/* Enable SC after setting all other parameters */
40259a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_STATE__A, 0);
40269a0bf528SMauro Carvalho Chehab 	if (status < 0)
40279a0bf528SMauro Carvalho Chehab 		goto error;
40289a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
40299a0bf528SMauro Carvalho Chehab 	if (status < 0)
40309a0bf528SMauro Carvalho Chehab 		goto error;
40319a0bf528SMauro Carvalho Chehab 
40329a0bf528SMauro Carvalho Chehab 
4033ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4034ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
4035ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
40369a0bf528SMauro Carvalho Chehab 	if (status < 0)
40379a0bf528SMauro Carvalho Chehab 		goto error;
40389a0bf528SMauro Carvalho Chehab 
40399a0bf528SMauro Carvalho Chehab 	/* Write SC parameter registers, set all AUTO flags in operation mode */
40409a0bf528SMauro Carvalho Chehab 	param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
40419a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
40429a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
40439a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
40449a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4045cd7a67a4SMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4046cd7a67a4SMauro Carvalho Chehab 				0, transmission_params, param1, 0, 0, 0);
40479a0bf528SMauro Carvalho Chehab 	if (status < 0)
40489a0bf528SMauro Carvalho Chehab 		goto error;
40499a0bf528SMauro Carvalho Chehab 
4050cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code)
4051cd7a67a4SMauro Carvalho Chehab 		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
40529a0bf528SMauro Carvalho Chehab error:
40539a0bf528SMauro Carvalho Chehab 	if (status < 0)
40543a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40559a0bf528SMauro Carvalho Chehab 
40569a0bf528SMauro Carvalho Chehab 	return status;
40579a0bf528SMauro Carvalho Chehab }
40589a0bf528SMauro Carvalho Chehab 
40599a0bf528SMauro Carvalho Chehab 
40609a0bf528SMauro Carvalho Chehab /*============================================================================*/
40619a0bf528SMauro Carvalho Chehab 
406234eb9751SMauro Carvalho Chehab /*
406339c1cb2bSJonathan McCrohan * \brief Retrieve lock status .
40649a0bf528SMauro Carvalho Chehab * \param demod    Pointer to demodulator instance.
40659a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
40669a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
40679a0bf528SMauro Carvalho Chehab *
40689a0bf528SMauro Carvalho Chehab */
4069cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
40709a0bf528SMauro Carvalho Chehab {
40719a0bf528SMauro Carvalho Chehab 	int status;
40729a0bf528SMauro Carvalho Chehab 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
40739a0bf528SMauro Carvalho Chehab 				    OFDM_SC_RA_RAM_LOCK_FEC__M);
40749a0bf528SMauro Carvalho Chehab 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
40759a0bf528SMauro Carvalho Chehab 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
40769a0bf528SMauro Carvalho Chehab 
4077cd7a67a4SMauro Carvalho Chehab 	u16 sc_ra_ram_lock = 0;
4078cd7a67a4SMauro Carvalho Chehab 	u16 sc_comm_exec = 0;
40799a0bf528SMauro Carvalho Chehab 
40809a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
40819a0bf528SMauro Carvalho Chehab 
4082cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
40839a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
40849a0bf528SMauro Carvalho Chehab 	/* Check if SC is running */
4085cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
40869a0bf528SMauro Carvalho Chehab 	if (status < 0)
40879a0bf528SMauro Carvalho Chehab 		goto end;
4088cd7a67a4SMauro Carvalho Chehab 	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
40899a0bf528SMauro Carvalho Chehab 		goto end;
40909a0bf528SMauro Carvalho Chehab 
4091cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
40929a0bf528SMauro Carvalho Chehab 	if (status < 0)
40939a0bf528SMauro Carvalho Chehab 		goto end;
40949a0bf528SMauro Carvalho Chehab 
4095cd7a67a4SMauro Carvalho Chehab 	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4096cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
4097cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4098cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = FEC_LOCK;
4099cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4100cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
4101cd7a67a4SMauro Carvalho Chehab 	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4102cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
41039a0bf528SMauro Carvalho Chehab end:
41049a0bf528SMauro Carvalho Chehab 	if (status < 0)
41053a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41069a0bf528SMauro Carvalho Chehab 
41079a0bf528SMauro Carvalho Chehab 	return status;
41089a0bf528SMauro Carvalho Chehab }
41099a0bf528SMauro Carvalho Chehab 
4110cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state)
41119a0bf528SMauro Carvalho Chehab {
4112cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
41139a0bf528SMauro Carvalho Chehab 	int status;
41149a0bf528SMauro Carvalho Chehab 
41159a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4116cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
41179a0bf528SMauro Carvalho Chehab 	if (status < 0)
41183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41199a0bf528SMauro Carvalho Chehab 
41209a0bf528SMauro Carvalho Chehab 	return status;
41219a0bf528SMauro Carvalho Chehab }
41229a0bf528SMauro Carvalho Chehab 
41239a0bf528SMauro Carvalho Chehab 
412434eb9751SMauro Carvalho Chehab /* Power Down QAM */
4125cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state)
41269a0bf528SMauro Carvalho Chehab {
41279a0bf528SMauro Carvalho Chehab 	u16 data = 0;
4128cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
41299a0bf528SMauro Carvalho Chehab 	int status = 0;
41309a0bf528SMauro Carvalho Chehab 
41319a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41329a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
41339a0bf528SMauro Carvalho Chehab 	if (status < 0)
41349a0bf528SMauro Carvalho Chehab 		goto error;
41359a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
41369a0bf528SMauro Carvalho Chehab 		/*
41379a0bf528SMauro Carvalho Chehab 			STOP demodulator
41389a0bf528SMauro Carvalho Chehab 			QAM and HW blocks
41399a0bf528SMauro Carvalho Chehab 			*/
41409a0bf528SMauro Carvalho Chehab 		/* stop all comstate->m_exec */
41419a0bf528SMauro Carvalho Chehab 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
41429a0bf528SMauro Carvalho Chehab 		if (status < 0)
41439a0bf528SMauro Carvalho Chehab 			goto error;
4144ab5060cdSMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4145ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4146ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
41479a0bf528SMauro Carvalho Chehab 		if (status < 0)
41489a0bf528SMauro Carvalho Chehab 			goto error;
41499a0bf528SMauro Carvalho Chehab 	}
41509a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
4151cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
41529a0bf528SMauro Carvalho Chehab 
41539a0bf528SMauro Carvalho Chehab error:
41549a0bf528SMauro Carvalho Chehab 	if (status < 0)
41553a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41569a0bf528SMauro Carvalho Chehab 
41579a0bf528SMauro Carvalho Chehab 	return status;
41589a0bf528SMauro Carvalho Chehab }
41599a0bf528SMauro Carvalho Chehab 
41609a0bf528SMauro Carvalho Chehab /*============================================================================*/
41619a0bf528SMauro Carvalho Chehab 
416234eb9751SMauro Carvalho Chehab /*
41639a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
41649a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
41659a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
41669a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41679a0bf528SMauro Carvalho Chehab *
41689a0bf528SMauro Carvalho Chehab *  NOTE:
41699a0bf528SMauro Carvalho Chehab *  Take into account that for certain settings the errorcounters can overflow.
41709a0bf528SMauro Carvalho Chehab *  The implementation does not check this.
41719a0bf528SMauro Carvalho Chehab *
41729a0bf528SMauro Carvalho Chehab */
4173cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state,
4174cd7a67a4SMauro Carvalho Chehab 			     enum e_drxk_constellation modulation,
4175cd7a67a4SMauro Carvalho Chehab 			     u32 symbol_rate)
41769a0bf528SMauro Carvalho Chehab {
4177cd7a67a4SMauro Carvalho Chehab 	u32 fec_bits_desired = 0;	/* BER accounting period */
4178cd7a67a4SMauro Carvalho Chehab 	u32 fec_rs_period_total = 0;	/* Total period */
4179cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
4180cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
41819a0bf528SMauro Carvalho Chehab 	int status = 0;
41829a0bf528SMauro Carvalho Chehab 
41839a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41849a0bf528SMauro Carvalho Chehab 
4185cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1;
4186cd7a67a4SMauro Carvalho Chehab 	/* fec_bits_desired = symbol_rate [kHz] *
41879a0bf528SMauro Carvalho Chehab 		FrameLenght [ms] *
41889a0bf528SMauro Carvalho Chehab 		(modulation + 1) *
41899a0bf528SMauro Carvalho Chehab 		SyncLoss (== 1) *
41909a0bf528SMauro Carvalho Chehab 		ViterbiLoss (==1)
41919a0bf528SMauro Carvalho Chehab 		*/
41929a0bf528SMauro Carvalho Chehab 	switch (modulation) {
41939a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM16:
4194cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 4 * symbol_rate;
41959a0bf528SMauro Carvalho Chehab 		break;
41969a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM32:
4197cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 5 * symbol_rate;
41989a0bf528SMauro Carvalho Chehab 		break;
41999a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM64:
4200cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 6 * symbol_rate;
42019a0bf528SMauro Carvalho Chehab 		break;
42029a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM128:
4203cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 7 * symbol_rate;
42049a0bf528SMauro Carvalho Chehab 		break;
42059a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM256:
4206cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 8 * symbol_rate;
42079a0bf528SMauro Carvalho Chehab 		break;
42089a0bf528SMauro Carvalho Chehab 	default:
42099a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42109a0bf528SMauro Carvalho Chehab 	}
42119a0bf528SMauro Carvalho Chehab 	if (status < 0)
42129a0bf528SMauro Carvalho Chehab 		goto error;
42139a0bf528SMauro Carvalho Chehab 
4214cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
4215cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired *= 500;	/* meas. period [ms] */
42169a0bf528SMauro Carvalho Chehab 
42179a0bf528SMauro Carvalho Chehab 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4218cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total = fec_bits_desired / 1632 */
4219cd7a67a4SMauro Carvalho Chehab 	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
42209a0bf528SMauro Carvalho Chehab 
4221cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
4222cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4223cd7a67a4SMauro Carvalho Chehab 	if (fec_rs_prescale == 0) {
42249a0bf528SMauro Carvalho Chehab 		/* Divide by zero (though impossible) */
42259a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42269a0bf528SMauro Carvalho Chehab 		if (status < 0)
42279a0bf528SMauro Carvalho Chehab 			goto error;
42289a0bf528SMauro Carvalho Chehab 	}
4229cd7a67a4SMauro Carvalho Chehab 	fec_rs_period =
4230cd7a67a4SMauro Carvalho Chehab 		((u16) fec_rs_period_total +
4231cd7a67a4SMauro Carvalho Chehab 		(fec_rs_prescale >> 1)) / fec_rs_prescale;
42329a0bf528SMauro Carvalho Chehab 
42339a0bf528SMauro Carvalho Chehab 	/* write corresponding registers */
4234cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
42359a0bf528SMauro Carvalho Chehab 	if (status < 0)
42369a0bf528SMauro Carvalho Chehab 		goto error;
4237ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4238ab5060cdSMauro Carvalho Chehab 			 fec_rs_prescale);
42399a0bf528SMauro Carvalho Chehab 	if (status < 0)
42409a0bf528SMauro Carvalho Chehab 		goto error;
4241cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
42429a0bf528SMauro Carvalho Chehab error:
42439a0bf528SMauro Carvalho Chehab 	if (status < 0)
42443a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
42459a0bf528SMauro Carvalho Chehab 	return status;
42469a0bf528SMauro Carvalho Chehab }
42479a0bf528SMauro Carvalho Chehab 
4248cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state)
42499a0bf528SMauro Carvalho Chehab {
42509a0bf528SMauro Carvalho Chehab 	int status = 0;
42519a0bf528SMauro Carvalho Chehab 
42529a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42539a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
42549a0bf528SMauro Carvalho Chehab 	/* Equalizer */
42559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
42569a0bf528SMauro Carvalho Chehab 	if (status < 0)
42579a0bf528SMauro Carvalho Chehab 		goto error;
42589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
42599a0bf528SMauro Carvalho Chehab 	if (status < 0)
42609a0bf528SMauro Carvalho Chehab 		goto error;
42619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
42629a0bf528SMauro Carvalho Chehab 	if (status < 0)
42639a0bf528SMauro Carvalho Chehab 		goto error;
42649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
42659a0bf528SMauro Carvalho Chehab 	if (status < 0)
42669a0bf528SMauro Carvalho Chehab 		goto error;
42679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
42689a0bf528SMauro Carvalho Chehab 	if (status < 0)
42699a0bf528SMauro Carvalho Chehab 		goto error;
42709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
42719a0bf528SMauro Carvalho Chehab 	if (status < 0)
42729a0bf528SMauro Carvalho Chehab 		goto error;
42739a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
42749a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
42759a0bf528SMauro Carvalho Chehab 	if (status < 0)
42769a0bf528SMauro Carvalho Chehab 		goto error;
42779a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
42789a0bf528SMauro Carvalho Chehab 	if (status < 0)
42799a0bf528SMauro Carvalho Chehab 		goto error;
42809a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
42819a0bf528SMauro Carvalho Chehab 	if (status < 0)
42829a0bf528SMauro Carvalho Chehab 		goto error;
42839a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
42849a0bf528SMauro Carvalho Chehab 	if (status < 0)
42859a0bf528SMauro Carvalho Chehab 		goto error;
42869a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
42879a0bf528SMauro Carvalho Chehab 	if (status < 0)
42889a0bf528SMauro Carvalho Chehab 		goto error;
42899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
42909a0bf528SMauro Carvalho Chehab 	if (status < 0)
42919a0bf528SMauro Carvalho Chehab 		goto error;
42929a0bf528SMauro Carvalho Chehab 
42939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
42949a0bf528SMauro Carvalho Chehab 	if (status < 0)
42959a0bf528SMauro Carvalho Chehab 		goto error;
42969a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
42979a0bf528SMauro Carvalho Chehab 	if (status < 0)
42989a0bf528SMauro Carvalho Chehab 		goto error;
42999a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
43009a0bf528SMauro Carvalho Chehab 	if (status < 0)
43019a0bf528SMauro Carvalho Chehab 		goto error;
43029a0bf528SMauro Carvalho Chehab 
43039a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4304ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4305ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM16);
43069a0bf528SMauro Carvalho Chehab 	if (status < 0)
43079a0bf528SMauro Carvalho Chehab 		goto error;
43089a0bf528SMauro Carvalho Chehab 
43099a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
43109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
43119a0bf528SMauro Carvalho Chehab 	if (status < 0)
43129a0bf528SMauro Carvalho Chehab 		goto error;
43139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
43149a0bf528SMauro Carvalho Chehab 	if (status < 0)
43159a0bf528SMauro Carvalho Chehab 		goto error;
43169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
43179a0bf528SMauro Carvalho Chehab 	if (status < 0)
43189a0bf528SMauro Carvalho Chehab 		goto error;
43199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
43209a0bf528SMauro Carvalho Chehab 	if (status < 0)
43219a0bf528SMauro Carvalho Chehab 		goto error;
43229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
43239a0bf528SMauro Carvalho Chehab 	if (status < 0)
43249a0bf528SMauro Carvalho Chehab 		goto error;
43259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
43269a0bf528SMauro Carvalho Chehab 	if (status < 0)
43279a0bf528SMauro Carvalho Chehab 		goto error;
43289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
43299a0bf528SMauro Carvalho Chehab 	if (status < 0)
43309a0bf528SMauro Carvalho Chehab 		goto error;
43319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43329a0bf528SMauro Carvalho Chehab 	if (status < 0)
43339a0bf528SMauro Carvalho Chehab 		goto error;
43349a0bf528SMauro Carvalho Chehab 
43359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43369a0bf528SMauro Carvalho Chehab 	if (status < 0)
43379a0bf528SMauro Carvalho Chehab 		goto error;
43389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43399a0bf528SMauro Carvalho Chehab 	if (status < 0)
43409a0bf528SMauro Carvalho Chehab 		goto error;
43419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
43429a0bf528SMauro Carvalho Chehab 	if (status < 0)
43439a0bf528SMauro Carvalho Chehab 		goto error;
43449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
43459a0bf528SMauro Carvalho Chehab 	if (status < 0)
43469a0bf528SMauro Carvalho Chehab 		goto error;
43479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
43489a0bf528SMauro Carvalho Chehab 	if (status < 0)
43499a0bf528SMauro Carvalho Chehab 		goto error;
43509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
43519a0bf528SMauro Carvalho Chehab 	if (status < 0)
43529a0bf528SMauro Carvalho Chehab 		goto error;
43539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
43549a0bf528SMauro Carvalho Chehab 	if (status < 0)
43559a0bf528SMauro Carvalho Chehab 		goto error;
43569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
43579a0bf528SMauro Carvalho Chehab 	if (status < 0)
43589a0bf528SMauro Carvalho Chehab 		goto error;
43599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
43609a0bf528SMauro Carvalho Chehab 	if (status < 0)
43619a0bf528SMauro Carvalho Chehab 		goto error;
43629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
43639a0bf528SMauro Carvalho Chehab 	if (status < 0)
43649a0bf528SMauro Carvalho Chehab 		goto error;
43659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
43669a0bf528SMauro Carvalho Chehab 	if (status < 0)
43679a0bf528SMauro Carvalho Chehab 		goto error;
43689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
43699a0bf528SMauro Carvalho Chehab 	if (status < 0)
43709a0bf528SMauro Carvalho Chehab 		goto error;
43719a0bf528SMauro Carvalho Chehab 
43729a0bf528SMauro Carvalho Chehab 
43739a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
43749a0bf528SMauro Carvalho Chehab 
43759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
43769a0bf528SMauro Carvalho Chehab 	if (status < 0)
43779a0bf528SMauro Carvalho Chehab 		goto error;
43789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
43799a0bf528SMauro Carvalho Chehab 	if (status < 0)
43809a0bf528SMauro Carvalho Chehab 		goto error;
43819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
43829a0bf528SMauro Carvalho Chehab 	if (status < 0)
43839a0bf528SMauro Carvalho Chehab 		goto error;
43849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
43859a0bf528SMauro Carvalho Chehab 	if (status < 0)
43869a0bf528SMauro Carvalho Chehab 		goto error;
43879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
43889a0bf528SMauro Carvalho Chehab 	if (status < 0)
43899a0bf528SMauro Carvalho Chehab 		goto error;
43909a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
43919a0bf528SMauro Carvalho Chehab 	if (status < 0)
43929a0bf528SMauro Carvalho Chehab 		goto error;
43939a0bf528SMauro Carvalho Chehab 
43949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
43959a0bf528SMauro Carvalho Chehab 	if (status < 0)
43969a0bf528SMauro Carvalho Chehab 		goto error;
43979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
43989a0bf528SMauro Carvalho Chehab 	if (status < 0)
43999a0bf528SMauro Carvalho Chehab 		goto error;
44009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
44019a0bf528SMauro Carvalho Chehab 	if (status < 0)
44029a0bf528SMauro Carvalho Chehab 		goto error;
44039a0bf528SMauro Carvalho Chehab 
44049a0bf528SMauro Carvalho Chehab 
44059a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
44069a0bf528SMauro Carvalho Chehab 
44079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
44089a0bf528SMauro Carvalho Chehab 	if (status < 0)
44099a0bf528SMauro Carvalho Chehab 		goto error;
44109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
44119a0bf528SMauro Carvalho Chehab 	if (status < 0)
44129a0bf528SMauro Carvalho Chehab 		goto error;
44139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
44149a0bf528SMauro Carvalho Chehab 	if (status < 0)
44159a0bf528SMauro Carvalho Chehab 		goto error;
44169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
44179a0bf528SMauro Carvalho Chehab 	if (status < 0)
44189a0bf528SMauro Carvalho Chehab 		goto error;
44199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
44209a0bf528SMauro Carvalho Chehab 	if (status < 0)
44219a0bf528SMauro Carvalho Chehab 		goto error;
44229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
44239a0bf528SMauro Carvalho Chehab 	if (status < 0)
44249a0bf528SMauro Carvalho Chehab 		goto error;
44259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
44269a0bf528SMauro Carvalho Chehab 	if (status < 0)
44279a0bf528SMauro Carvalho Chehab 		goto error;
44289a0bf528SMauro Carvalho Chehab 
44299a0bf528SMauro Carvalho Chehab error:
44309a0bf528SMauro Carvalho Chehab 	if (status < 0)
44313a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
44329a0bf528SMauro Carvalho Chehab 	return status;
44339a0bf528SMauro Carvalho Chehab }
44349a0bf528SMauro Carvalho Chehab 
44359a0bf528SMauro Carvalho Chehab /*============================================================================*/
44369a0bf528SMauro Carvalho Chehab 
443734eb9751SMauro Carvalho Chehab /*
44389a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44399a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
44409a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
44419a0bf528SMauro Carvalho Chehab */
4442cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state)
44439a0bf528SMauro Carvalho Chehab {
44449a0bf528SMauro Carvalho Chehab 	int status = 0;
44459a0bf528SMauro Carvalho Chehab 
44469a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
44479a0bf528SMauro Carvalho Chehab 
44489a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
44499a0bf528SMauro Carvalho Chehab 	/* Equalizer */
44509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
44519a0bf528SMauro Carvalho Chehab 	if (status < 0)
44529a0bf528SMauro Carvalho Chehab 		goto error;
44539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
44549a0bf528SMauro Carvalho Chehab 	if (status < 0)
44559a0bf528SMauro Carvalho Chehab 		goto error;
44569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
44579a0bf528SMauro Carvalho Chehab 	if (status < 0)
44589a0bf528SMauro Carvalho Chehab 		goto error;
44599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
44609a0bf528SMauro Carvalho Chehab 	if (status < 0)
44619a0bf528SMauro Carvalho Chehab 		goto error;
44629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
44639a0bf528SMauro Carvalho Chehab 	if (status < 0)
44649a0bf528SMauro Carvalho Chehab 		goto error;
44659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
44669a0bf528SMauro Carvalho Chehab 	if (status < 0)
44679a0bf528SMauro Carvalho Chehab 		goto error;
44689a0bf528SMauro Carvalho Chehab 
44699a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
44709a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
44719a0bf528SMauro Carvalho Chehab 	if (status < 0)
44729a0bf528SMauro Carvalho Chehab 		goto error;
44739a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
44749a0bf528SMauro Carvalho Chehab 	if (status < 0)
44759a0bf528SMauro Carvalho Chehab 		goto error;
44769a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
44779a0bf528SMauro Carvalho Chehab 	if (status < 0)
44789a0bf528SMauro Carvalho Chehab 		goto error;
44799a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
44809a0bf528SMauro Carvalho Chehab 	if (status < 0)
44819a0bf528SMauro Carvalho Chehab 		goto error;
44829a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
44839a0bf528SMauro Carvalho Chehab 	if (status < 0)
44849a0bf528SMauro Carvalho Chehab 		goto error;
44859a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
44869a0bf528SMauro Carvalho Chehab 	if (status < 0)
44879a0bf528SMauro Carvalho Chehab 		goto error;
44889a0bf528SMauro Carvalho Chehab 
44899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
44909a0bf528SMauro Carvalho Chehab 	if (status < 0)
44919a0bf528SMauro Carvalho Chehab 		goto error;
44929a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
44939a0bf528SMauro Carvalho Chehab 	if (status < 0)
44949a0bf528SMauro Carvalho Chehab 		goto error;
44959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
44969a0bf528SMauro Carvalho Chehab 	if (status < 0)
44979a0bf528SMauro Carvalho Chehab 		goto error;
44989a0bf528SMauro Carvalho Chehab 
44999a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
45009a0bf528SMauro Carvalho Chehab 
4501ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4502ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM32);
45039a0bf528SMauro Carvalho Chehab 	if (status < 0)
45049a0bf528SMauro Carvalho Chehab 		goto error;
45059a0bf528SMauro Carvalho Chehab 
45069a0bf528SMauro Carvalho Chehab 
45079a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
45089a0bf528SMauro Carvalho Chehab 
45099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
45109a0bf528SMauro Carvalho Chehab 	if (status < 0)
45119a0bf528SMauro Carvalho Chehab 		goto error;
45129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
45139a0bf528SMauro Carvalho Chehab 	if (status < 0)
45149a0bf528SMauro Carvalho Chehab 		goto error;
45159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
45169a0bf528SMauro Carvalho Chehab 	if (status < 0)
45179a0bf528SMauro Carvalho Chehab 		goto error;
45189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
45199a0bf528SMauro Carvalho Chehab 	if (status < 0)
45209a0bf528SMauro Carvalho Chehab 		goto error;
45219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
45229a0bf528SMauro Carvalho Chehab 	if (status < 0)
45239a0bf528SMauro Carvalho Chehab 		goto error;
45249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
45259a0bf528SMauro Carvalho Chehab 	if (status < 0)
45269a0bf528SMauro Carvalho Chehab 		goto error;
45279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
45289a0bf528SMauro Carvalho Chehab 	if (status < 0)
45299a0bf528SMauro Carvalho Chehab 		goto error;
45309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
45319a0bf528SMauro Carvalho Chehab 	if (status < 0)
45329a0bf528SMauro Carvalho Chehab 		goto error;
45339a0bf528SMauro Carvalho Chehab 
45349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45359a0bf528SMauro Carvalho Chehab 	if (status < 0)
45369a0bf528SMauro Carvalho Chehab 		goto error;
45379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45389a0bf528SMauro Carvalho Chehab 	if (status < 0)
45399a0bf528SMauro Carvalho Chehab 		goto error;
45409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
45419a0bf528SMauro Carvalho Chehab 	if (status < 0)
45429a0bf528SMauro Carvalho Chehab 		goto error;
45439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
45449a0bf528SMauro Carvalho Chehab 	if (status < 0)
45459a0bf528SMauro Carvalho Chehab 		goto error;
45469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
45479a0bf528SMauro Carvalho Chehab 	if (status < 0)
45489a0bf528SMauro Carvalho Chehab 		goto error;
45499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
45509a0bf528SMauro Carvalho Chehab 	if (status < 0)
45519a0bf528SMauro Carvalho Chehab 		goto error;
45529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
45539a0bf528SMauro Carvalho Chehab 	if (status < 0)
45549a0bf528SMauro Carvalho Chehab 		goto error;
45559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
45569a0bf528SMauro Carvalho Chehab 	if (status < 0)
45579a0bf528SMauro Carvalho Chehab 		goto error;
45589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
45599a0bf528SMauro Carvalho Chehab 	if (status < 0)
45609a0bf528SMauro Carvalho Chehab 		goto error;
45619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
45629a0bf528SMauro Carvalho Chehab 	if (status < 0)
45639a0bf528SMauro Carvalho Chehab 		goto error;
45649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
45659a0bf528SMauro Carvalho Chehab 	if (status < 0)
45669a0bf528SMauro Carvalho Chehab 		goto error;
45679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
45689a0bf528SMauro Carvalho Chehab 	if (status < 0)
45699a0bf528SMauro Carvalho Chehab 		goto error;
45709a0bf528SMauro Carvalho Chehab 
45719a0bf528SMauro Carvalho Chehab 
45729a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
45739a0bf528SMauro Carvalho Chehab 
45749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
45759a0bf528SMauro Carvalho Chehab 	if (status < 0)
45769a0bf528SMauro Carvalho Chehab 		goto error;
45779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
45789a0bf528SMauro Carvalho Chehab 	if (status < 0)
45799a0bf528SMauro Carvalho Chehab 		goto error;
45809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
45819a0bf528SMauro Carvalho Chehab 	if (status < 0)
45829a0bf528SMauro Carvalho Chehab 		goto error;
45839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
45849a0bf528SMauro Carvalho Chehab 	if (status < 0)
45859a0bf528SMauro Carvalho Chehab 		goto error;
45869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
45879a0bf528SMauro Carvalho Chehab 	if (status < 0)
45889a0bf528SMauro Carvalho Chehab 		goto error;
45899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
45909a0bf528SMauro Carvalho Chehab 	if (status < 0)
45919a0bf528SMauro Carvalho Chehab 		goto error;
45929a0bf528SMauro Carvalho Chehab 
45939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
45949a0bf528SMauro Carvalho Chehab 	if (status < 0)
45959a0bf528SMauro Carvalho Chehab 		goto error;
45969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
45979a0bf528SMauro Carvalho Chehab 	if (status < 0)
45989a0bf528SMauro Carvalho Chehab 		goto error;
45999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
46009a0bf528SMauro Carvalho Chehab 	if (status < 0)
46019a0bf528SMauro Carvalho Chehab 		goto error;
46029a0bf528SMauro Carvalho Chehab 
46039a0bf528SMauro Carvalho Chehab 
46049a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
46059a0bf528SMauro Carvalho Chehab 
46069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
46079a0bf528SMauro Carvalho Chehab 	if (status < 0)
46089a0bf528SMauro Carvalho Chehab 		goto error;
46099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
46109a0bf528SMauro Carvalho Chehab 	if (status < 0)
46119a0bf528SMauro Carvalho Chehab 		goto error;
46129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
46139a0bf528SMauro Carvalho Chehab 	if (status < 0)
46149a0bf528SMauro Carvalho Chehab 		goto error;
46159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
46169a0bf528SMauro Carvalho Chehab 	if (status < 0)
46179a0bf528SMauro Carvalho Chehab 		goto error;
46189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
46199a0bf528SMauro Carvalho Chehab 	if (status < 0)
46209a0bf528SMauro Carvalho Chehab 		goto error;
46219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
46229a0bf528SMauro Carvalho Chehab 	if (status < 0)
46239a0bf528SMauro Carvalho Chehab 		goto error;
46249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
46259a0bf528SMauro Carvalho Chehab error:
46269a0bf528SMauro Carvalho Chehab 	if (status < 0)
46273a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
46289a0bf528SMauro Carvalho Chehab 	return status;
46299a0bf528SMauro Carvalho Chehab }
46309a0bf528SMauro Carvalho Chehab 
46319a0bf528SMauro Carvalho Chehab /*============================================================================*/
46329a0bf528SMauro Carvalho Chehab 
463334eb9751SMauro Carvalho Chehab /*
46349a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46359a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46369a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46379a0bf528SMauro Carvalho Chehab */
4638cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state)
46399a0bf528SMauro Carvalho Chehab {
46409a0bf528SMauro Carvalho Chehab 	int status = 0;
46419a0bf528SMauro Carvalho Chehab 
46429a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
46439a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
46449a0bf528SMauro Carvalho Chehab 	/* Equalizer */
46459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
46469a0bf528SMauro Carvalho Chehab 	if (status < 0)
46479a0bf528SMauro Carvalho Chehab 		goto error;
46489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
46499a0bf528SMauro Carvalho Chehab 	if (status < 0)
46509a0bf528SMauro Carvalho Chehab 		goto error;
46519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
46529a0bf528SMauro Carvalho Chehab 	if (status < 0)
46539a0bf528SMauro Carvalho Chehab 		goto error;
46549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
46559a0bf528SMauro Carvalho Chehab 	if (status < 0)
46569a0bf528SMauro Carvalho Chehab 		goto error;
46579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
46589a0bf528SMauro Carvalho Chehab 	if (status < 0)
46599a0bf528SMauro Carvalho Chehab 		goto error;
46609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
46619a0bf528SMauro Carvalho Chehab 	if (status < 0)
46629a0bf528SMauro Carvalho Chehab 		goto error;
46639a0bf528SMauro Carvalho Chehab 
46649a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
46659a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
46669a0bf528SMauro Carvalho Chehab 	if (status < 0)
46679a0bf528SMauro Carvalho Chehab 		goto error;
46689a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
46699a0bf528SMauro Carvalho Chehab 	if (status < 0)
46709a0bf528SMauro Carvalho Chehab 		goto error;
46719a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
46729a0bf528SMauro Carvalho Chehab 	if (status < 0)
46739a0bf528SMauro Carvalho Chehab 		goto error;
46749a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
46759a0bf528SMauro Carvalho Chehab 	if (status < 0)
46769a0bf528SMauro Carvalho Chehab 		goto error;
46779a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
46789a0bf528SMauro Carvalho Chehab 	if (status < 0)
46799a0bf528SMauro Carvalho Chehab 		goto error;
46809a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
46819a0bf528SMauro Carvalho Chehab 	if (status < 0)
46829a0bf528SMauro Carvalho Chehab 		goto error;
46839a0bf528SMauro Carvalho Chehab 
46849a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
46859a0bf528SMauro Carvalho Chehab 	if (status < 0)
46869a0bf528SMauro Carvalho Chehab 		goto error;
46879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
46889a0bf528SMauro Carvalho Chehab 	if (status < 0)
46899a0bf528SMauro Carvalho Chehab 		goto error;
46909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
46919a0bf528SMauro Carvalho Chehab 	if (status < 0)
46929a0bf528SMauro Carvalho Chehab 		goto error;
46939a0bf528SMauro Carvalho Chehab 
46949a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4695ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4696ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM64);
46979a0bf528SMauro Carvalho Chehab 	if (status < 0)
46989a0bf528SMauro Carvalho Chehab 		goto error;
46999a0bf528SMauro Carvalho Chehab 
47009a0bf528SMauro Carvalho Chehab 
47019a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
47029a0bf528SMauro Carvalho Chehab 
47039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
47049a0bf528SMauro Carvalho Chehab 	if (status < 0)
47059a0bf528SMauro Carvalho Chehab 		goto error;
47069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
47079a0bf528SMauro Carvalho Chehab 	if (status < 0)
47089a0bf528SMauro Carvalho Chehab 		goto error;
47099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
47109a0bf528SMauro Carvalho Chehab 	if (status < 0)
47119a0bf528SMauro Carvalho Chehab 		goto error;
47129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
47139a0bf528SMauro Carvalho Chehab 	if (status < 0)
47149a0bf528SMauro Carvalho Chehab 		goto error;
47159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
47169a0bf528SMauro Carvalho Chehab 	if (status < 0)
47179a0bf528SMauro Carvalho Chehab 		goto error;
47189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
47199a0bf528SMauro Carvalho Chehab 	if (status < 0)
47209a0bf528SMauro Carvalho Chehab 		goto error;
47219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
47229a0bf528SMauro Carvalho Chehab 	if (status < 0)
47239a0bf528SMauro Carvalho Chehab 		goto error;
47249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
47259a0bf528SMauro Carvalho Chehab 	if (status < 0)
47269a0bf528SMauro Carvalho Chehab 		goto error;
47279a0bf528SMauro Carvalho Chehab 
47289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
47299a0bf528SMauro Carvalho Chehab 	if (status < 0)
47309a0bf528SMauro Carvalho Chehab 		goto error;
47319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47329a0bf528SMauro Carvalho Chehab 	if (status < 0)
47339a0bf528SMauro Carvalho Chehab 		goto error;
47349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47359a0bf528SMauro Carvalho Chehab 	if (status < 0)
47369a0bf528SMauro Carvalho Chehab 		goto error;
47379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47389a0bf528SMauro Carvalho Chehab 	if (status < 0)
47399a0bf528SMauro Carvalho Chehab 		goto error;
47409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47419a0bf528SMauro Carvalho Chehab 	if (status < 0)
47429a0bf528SMauro Carvalho Chehab 		goto error;
47439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
47449a0bf528SMauro Carvalho Chehab 	if (status < 0)
47459a0bf528SMauro Carvalho Chehab 		goto error;
47469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
47479a0bf528SMauro Carvalho Chehab 	if (status < 0)
47489a0bf528SMauro Carvalho Chehab 		goto error;
47499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
47509a0bf528SMauro Carvalho Chehab 	if (status < 0)
47519a0bf528SMauro Carvalho Chehab 		goto error;
47529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
47539a0bf528SMauro Carvalho Chehab 	if (status < 0)
47549a0bf528SMauro Carvalho Chehab 		goto error;
47559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
47569a0bf528SMauro Carvalho Chehab 	if (status < 0)
47579a0bf528SMauro Carvalho Chehab 		goto error;
47589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
47599a0bf528SMauro Carvalho Chehab 	if (status < 0)
47609a0bf528SMauro Carvalho Chehab 		goto error;
47619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
47629a0bf528SMauro Carvalho Chehab 	if (status < 0)
47639a0bf528SMauro Carvalho Chehab 		goto error;
47649a0bf528SMauro Carvalho Chehab 
47659a0bf528SMauro Carvalho Chehab 
47669a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
47679a0bf528SMauro Carvalho Chehab 
47689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
47699a0bf528SMauro Carvalho Chehab 	if (status < 0)
47709a0bf528SMauro Carvalho Chehab 		goto error;
47719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
47729a0bf528SMauro Carvalho Chehab 	if (status < 0)
47739a0bf528SMauro Carvalho Chehab 		goto error;
47749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
47759a0bf528SMauro Carvalho Chehab 	if (status < 0)
47769a0bf528SMauro Carvalho Chehab 		goto error;
47779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
47789a0bf528SMauro Carvalho Chehab 	if (status < 0)
47799a0bf528SMauro Carvalho Chehab 		goto error;
47809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
47819a0bf528SMauro Carvalho Chehab 	if (status < 0)
47829a0bf528SMauro Carvalho Chehab 		goto error;
47839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
47849a0bf528SMauro Carvalho Chehab 	if (status < 0)
47859a0bf528SMauro Carvalho Chehab 		goto error;
47869a0bf528SMauro Carvalho Chehab 
47879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
47889a0bf528SMauro Carvalho Chehab 	if (status < 0)
47899a0bf528SMauro Carvalho Chehab 		goto error;
47909a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
47919a0bf528SMauro Carvalho Chehab 	if (status < 0)
47929a0bf528SMauro Carvalho Chehab 		goto error;
47939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
47949a0bf528SMauro Carvalho Chehab 	if (status < 0)
47959a0bf528SMauro Carvalho Chehab 		goto error;
47969a0bf528SMauro Carvalho Chehab 
47979a0bf528SMauro Carvalho Chehab 
47989a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
47999a0bf528SMauro Carvalho Chehab 
48009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
48019a0bf528SMauro Carvalho Chehab 	if (status < 0)
48029a0bf528SMauro Carvalho Chehab 		goto error;
48039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
48049a0bf528SMauro Carvalho Chehab 	if (status < 0)
48059a0bf528SMauro Carvalho Chehab 		goto error;
48069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
48079a0bf528SMauro Carvalho Chehab 	if (status < 0)
48089a0bf528SMauro Carvalho Chehab 		goto error;
48099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
48109a0bf528SMauro Carvalho Chehab 	if (status < 0)
48119a0bf528SMauro Carvalho Chehab 		goto error;
48129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
48139a0bf528SMauro Carvalho Chehab 	if (status < 0)
48149a0bf528SMauro Carvalho Chehab 		goto error;
48159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
48169a0bf528SMauro Carvalho Chehab 	if (status < 0)
48179a0bf528SMauro Carvalho Chehab 		goto error;
48189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
48199a0bf528SMauro Carvalho Chehab error:
48209a0bf528SMauro Carvalho Chehab 	if (status < 0)
48213a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
48229a0bf528SMauro Carvalho Chehab 
48239a0bf528SMauro Carvalho Chehab 	return status;
48249a0bf528SMauro Carvalho Chehab }
48259a0bf528SMauro Carvalho Chehab 
48269a0bf528SMauro Carvalho Chehab /*============================================================================*/
48279a0bf528SMauro Carvalho Chehab 
482834eb9751SMauro Carvalho Chehab /*
48299a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
48309a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
48319a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48329a0bf528SMauro Carvalho Chehab */
4833cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state)
48349a0bf528SMauro Carvalho Chehab {
48359a0bf528SMauro Carvalho Chehab 	int status = 0;
48369a0bf528SMauro Carvalho Chehab 
48379a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
48389a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
48399a0bf528SMauro Carvalho Chehab 	/* Equalizer */
48409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48419a0bf528SMauro Carvalho Chehab 	if (status < 0)
48429a0bf528SMauro Carvalho Chehab 		goto error;
48439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
48449a0bf528SMauro Carvalho Chehab 	if (status < 0)
48459a0bf528SMauro Carvalho Chehab 		goto error;
48469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
48479a0bf528SMauro Carvalho Chehab 	if (status < 0)
48489a0bf528SMauro Carvalho Chehab 		goto error;
48499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
48509a0bf528SMauro Carvalho Chehab 	if (status < 0)
48519a0bf528SMauro Carvalho Chehab 		goto error;
48529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
48539a0bf528SMauro Carvalho Chehab 	if (status < 0)
48549a0bf528SMauro Carvalho Chehab 		goto error;
48559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
48569a0bf528SMauro Carvalho Chehab 	if (status < 0)
48579a0bf528SMauro Carvalho Chehab 		goto error;
48589a0bf528SMauro Carvalho Chehab 
48599a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
48609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
48619a0bf528SMauro Carvalho Chehab 	if (status < 0)
48629a0bf528SMauro Carvalho Chehab 		goto error;
48639a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
48649a0bf528SMauro Carvalho Chehab 	if (status < 0)
48659a0bf528SMauro Carvalho Chehab 		goto error;
48669a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
48679a0bf528SMauro Carvalho Chehab 	if (status < 0)
48689a0bf528SMauro Carvalho Chehab 		goto error;
48699a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
48709a0bf528SMauro Carvalho Chehab 	if (status < 0)
48719a0bf528SMauro Carvalho Chehab 		goto error;
48729a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
48739a0bf528SMauro Carvalho Chehab 	if (status < 0)
48749a0bf528SMauro Carvalho Chehab 		goto error;
48759a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
48769a0bf528SMauro Carvalho Chehab 	if (status < 0)
48779a0bf528SMauro Carvalho Chehab 		goto error;
48789a0bf528SMauro Carvalho Chehab 
48799a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
48809a0bf528SMauro Carvalho Chehab 	if (status < 0)
48819a0bf528SMauro Carvalho Chehab 		goto error;
48829a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
48839a0bf528SMauro Carvalho Chehab 	if (status < 0)
48849a0bf528SMauro Carvalho Chehab 		goto error;
48859a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
48869a0bf528SMauro Carvalho Chehab 	if (status < 0)
48879a0bf528SMauro Carvalho Chehab 		goto error;
48889a0bf528SMauro Carvalho Chehab 
48899a0bf528SMauro Carvalho Chehab 
48909a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
48919a0bf528SMauro Carvalho Chehab 
4892ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4893ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM128);
48949a0bf528SMauro Carvalho Chehab 	if (status < 0)
48959a0bf528SMauro Carvalho Chehab 		goto error;
48969a0bf528SMauro Carvalho Chehab 
48979a0bf528SMauro Carvalho Chehab 
48989a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
48999a0bf528SMauro Carvalho Chehab 
49009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
49019a0bf528SMauro Carvalho Chehab 	if (status < 0)
49029a0bf528SMauro Carvalho Chehab 		goto error;
49039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
49049a0bf528SMauro Carvalho Chehab 	if (status < 0)
49059a0bf528SMauro Carvalho Chehab 		goto error;
49069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
49079a0bf528SMauro Carvalho Chehab 	if (status < 0)
49089a0bf528SMauro Carvalho Chehab 		goto error;
49099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
49109a0bf528SMauro Carvalho Chehab 	if (status < 0)
49119a0bf528SMauro Carvalho Chehab 		goto error;
49129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
49139a0bf528SMauro Carvalho Chehab 	if (status < 0)
49149a0bf528SMauro Carvalho Chehab 		goto error;
49159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
49169a0bf528SMauro Carvalho Chehab 	if (status < 0)
49179a0bf528SMauro Carvalho Chehab 		goto error;
49189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
49199a0bf528SMauro Carvalho Chehab 	if (status < 0)
49209a0bf528SMauro Carvalho Chehab 		goto error;
49219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
49229a0bf528SMauro Carvalho Chehab 	if (status < 0)
49239a0bf528SMauro Carvalho Chehab 		goto error;
49249a0bf528SMauro Carvalho Chehab 
49259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
49269a0bf528SMauro Carvalho Chehab 	if (status < 0)
49279a0bf528SMauro Carvalho Chehab 		goto error;
49289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
49299a0bf528SMauro Carvalho Chehab 	if (status < 0)
49309a0bf528SMauro Carvalho Chehab 		goto error;
49319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49329a0bf528SMauro Carvalho Chehab 	if (status < 0)
49339a0bf528SMauro Carvalho Chehab 		goto error;
49349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49359a0bf528SMauro Carvalho Chehab 	if (status < 0)
49369a0bf528SMauro Carvalho Chehab 		goto error;
49379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49389a0bf528SMauro Carvalho Chehab 	if (status < 0)
49399a0bf528SMauro Carvalho Chehab 		goto error;
49409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49419a0bf528SMauro Carvalho Chehab 	if (status < 0)
49429a0bf528SMauro Carvalho Chehab 		goto error;
49439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
49449a0bf528SMauro Carvalho Chehab 	if (status < 0)
49459a0bf528SMauro Carvalho Chehab 		goto error;
49469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
49479a0bf528SMauro Carvalho Chehab 	if (status < 0)
49489a0bf528SMauro Carvalho Chehab 		goto error;
49499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
49509a0bf528SMauro Carvalho Chehab 	if (status < 0)
49519a0bf528SMauro Carvalho Chehab 		goto error;
49529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
49539a0bf528SMauro Carvalho Chehab 	if (status < 0)
49549a0bf528SMauro Carvalho Chehab 		goto error;
49559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
49569a0bf528SMauro Carvalho Chehab 	if (status < 0)
49579a0bf528SMauro Carvalho Chehab 		goto error;
49589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
49599a0bf528SMauro Carvalho Chehab 	if (status < 0)
49609a0bf528SMauro Carvalho Chehab 		goto error;
49619a0bf528SMauro Carvalho Chehab 
49629a0bf528SMauro Carvalho Chehab 
49639a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
49649a0bf528SMauro Carvalho Chehab 
49659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
49669a0bf528SMauro Carvalho Chehab 	if (status < 0)
49679a0bf528SMauro Carvalho Chehab 		goto error;
49689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
49699a0bf528SMauro Carvalho Chehab 	if (status < 0)
49709a0bf528SMauro Carvalho Chehab 		goto error;
49719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
49729a0bf528SMauro Carvalho Chehab 	if (status < 0)
49739a0bf528SMauro Carvalho Chehab 		goto error;
49749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
49759a0bf528SMauro Carvalho Chehab 	if (status < 0)
49769a0bf528SMauro Carvalho Chehab 		goto error;
49779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
49789a0bf528SMauro Carvalho Chehab 	if (status < 0)
49799a0bf528SMauro Carvalho Chehab 		goto error;
49809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
49819a0bf528SMauro Carvalho Chehab 	if (status < 0)
49829a0bf528SMauro Carvalho Chehab 		goto error;
49839a0bf528SMauro Carvalho Chehab 
49849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
49859a0bf528SMauro Carvalho Chehab 	if (status < 0)
49869a0bf528SMauro Carvalho Chehab 		goto error;
49879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
49889a0bf528SMauro Carvalho Chehab 	if (status < 0)
49899a0bf528SMauro Carvalho Chehab 		goto error;
49909a0bf528SMauro Carvalho Chehab 
49919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
49929a0bf528SMauro Carvalho Chehab 	if (status < 0)
49939a0bf528SMauro Carvalho Chehab 		goto error;
49949a0bf528SMauro Carvalho Chehab 
49959a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
49969a0bf528SMauro Carvalho Chehab 
49979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
49989a0bf528SMauro Carvalho Chehab 	if (status < 0)
49999a0bf528SMauro Carvalho Chehab 		goto error;
50009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
50019a0bf528SMauro Carvalho Chehab 	if (status < 0)
50029a0bf528SMauro Carvalho Chehab 		goto error;
50039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
50049a0bf528SMauro Carvalho Chehab 	if (status < 0)
50059a0bf528SMauro Carvalho Chehab 		goto error;
50069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
50079a0bf528SMauro Carvalho Chehab 	if (status < 0)
50089a0bf528SMauro Carvalho Chehab 		goto error;
50099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
50109a0bf528SMauro Carvalho Chehab 	if (status < 0)
50119a0bf528SMauro Carvalho Chehab 		goto error;
50129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
50139a0bf528SMauro Carvalho Chehab 	if (status < 0)
50149a0bf528SMauro Carvalho Chehab 		goto error;
50159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
50169a0bf528SMauro Carvalho Chehab error:
50179a0bf528SMauro Carvalho Chehab 	if (status < 0)
50183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
50199a0bf528SMauro Carvalho Chehab 
50209a0bf528SMauro Carvalho Chehab 	return status;
50219a0bf528SMauro Carvalho Chehab }
50229a0bf528SMauro Carvalho Chehab 
50239a0bf528SMauro Carvalho Chehab /*============================================================================*/
50249a0bf528SMauro Carvalho Chehab 
502534eb9751SMauro Carvalho Chehab /*
50269a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
50279a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
50289a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
50299a0bf528SMauro Carvalho Chehab */
5030cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state)
50319a0bf528SMauro Carvalho Chehab {
50329a0bf528SMauro Carvalho Chehab 	int status = 0;
50339a0bf528SMauro Carvalho Chehab 
50349a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
50359a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
50369a0bf528SMauro Carvalho Chehab 	/* Equalizer */
50379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50389a0bf528SMauro Carvalho Chehab 	if (status < 0)
50399a0bf528SMauro Carvalho Chehab 		goto error;
50409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50419a0bf528SMauro Carvalho Chehab 	if (status < 0)
50429a0bf528SMauro Carvalho Chehab 		goto error;
50439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
50449a0bf528SMauro Carvalho Chehab 	if (status < 0)
50459a0bf528SMauro Carvalho Chehab 		goto error;
50469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
50479a0bf528SMauro Carvalho Chehab 	if (status < 0)
50489a0bf528SMauro Carvalho Chehab 		goto error;
50499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
50509a0bf528SMauro Carvalho Chehab 	if (status < 0)
50519a0bf528SMauro Carvalho Chehab 		goto error;
50529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
50539a0bf528SMauro Carvalho Chehab 	if (status < 0)
50549a0bf528SMauro Carvalho Chehab 		goto error;
50559a0bf528SMauro Carvalho Chehab 
50569a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
50579a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
50589a0bf528SMauro Carvalho Chehab 	if (status < 0)
50599a0bf528SMauro Carvalho Chehab 		goto error;
50609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
50619a0bf528SMauro Carvalho Chehab 	if (status < 0)
50629a0bf528SMauro Carvalho Chehab 		goto error;
50639a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
50649a0bf528SMauro Carvalho Chehab 	if (status < 0)
50659a0bf528SMauro Carvalho Chehab 		goto error;
50669a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
50679a0bf528SMauro Carvalho Chehab 	if (status < 0)
50689a0bf528SMauro Carvalho Chehab 		goto error;
50699a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
50709a0bf528SMauro Carvalho Chehab 	if (status < 0)
50719a0bf528SMauro Carvalho Chehab 		goto error;
50729a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
50739a0bf528SMauro Carvalho Chehab 	if (status < 0)
50749a0bf528SMauro Carvalho Chehab 		goto error;
50759a0bf528SMauro Carvalho Chehab 
50769a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
50779a0bf528SMauro Carvalho Chehab 	if (status < 0)
50789a0bf528SMauro Carvalho Chehab 		goto error;
50799a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
50809a0bf528SMauro Carvalho Chehab 	if (status < 0)
50819a0bf528SMauro Carvalho Chehab 		goto error;
50829a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
50839a0bf528SMauro Carvalho Chehab 	if (status < 0)
50849a0bf528SMauro Carvalho Chehab 		goto error;
50859a0bf528SMauro Carvalho Chehab 
50869a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
50879a0bf528SMauro Carvalho Chehab 
5088ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5089ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM256);
50909a0bf528SMauro Carvalho Chehab 	if (status < 0)
50919a0bf528SMauro Carvalho Chehab 		goto error;
50929a0bf528SMauro Carvalho Chehab 
50939a0bf528SMauro Carvalho Chehab 
50949a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
50959a0bf528SMauro Carvalho Chehab 
50969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
50979a0bf528SMauro Carvalho Chehab 	if (status < 0)
50989a0bf528SMauro Carvalho Chehab 		goto error;
50999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
51009a0bf528SMauro Carvalho Chehab 	if (status < 0)
51019a0bf528SMauro Carvalho Chehab 		goto error;
51029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
51039a0bf528SMauro Carvalho Chehab 	if (status < 0)
51049a0bf528SMauro Carvalho Chehab 		goto error;
51059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
51069a0bf528SMauro Carvalho Chehab 	if (status < 0)
51079a0bf528SMauro Carvalho Chehab 		goto error;
51089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
51099a0bf528SMauro Carvalho Chehab 	if (status < 0)
51109a0bf528SMauro Carvalho Chehab 		goto error;
51119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
51129a0bf528SMauro Carvalho Chehab 	if (status < 0)
51139a0bf528SMauro Carvalho Chehab 		goto error;
51149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
51159a0bf528SMauro Carvalho Chehab 	if (status < 0)
51169a0bf528SMauro Carvalho Chehab 		goto error;
51179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
51189a0bf528SMauro Carvalho Chehab 	if (status < 0)
51199a0bf528SMauro Carvalho Chehab 		goto error;
51209a0bf528SMauro Carvalho Chehab 
51219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
51229a0bf528SMauro Carvalho Chehab 	if (status < 0)
51239a0bf528SMauro Carvalho Chehab 		goto error;
51249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
51259a0bf528SMauro Carvalho Chehab 	if (status < 0)
51269a0bf528SMauro Carvalho Chehab 		goto error;
51279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
51289a0bf528SMauro Carvalho Chehab 	if (status < 0)
51299a0bf528SMauro Carvalho Chehab 		goto error;
51309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
51319a0bf528SMauro Carvalho Chehab 	if (status < 0)
51329a0bf528SMauro Carvalho Chehab 		goto error;
51339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51349a0bf528SMauro Carvalho Chehab 	if (status < 0)
51359a0bf528SMauro Carvalho Chehab 		goto error;
51369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51379a0bf528SMauro Carvalho Chehab 	if (status < 0)
51389a0bf528SMauro Carvalho Chehab 		goto error;
51399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51409a0bf528SMauro Carvalho Chehab 	if (status < 0)
51419a0bf528SMauro Carvalho Chehab 		goto error;
51429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51439a0bf528SMauro Carvalho Chehab 	if (status < 0)
51449a0bf528SMauro Carvalho Chehab 		goto error;
51459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
51469a0bf528SMauro Carvalho Chehab 	if (status < 0)
51479a0bf528SMauro Carvalho Chehab 		goto error;
51489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
51499a0bf528SMauro Carvalho Chehab 	if (status < 0)
51509a0bf528SMauro Carvalho Chehab 		goto error;
51519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
51529a0bf528SMauro Carvalho Chehab 	if (status < 0)
51539a0bf528SMauro Carvalho Chehab 		goto error;
51549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
51559a0bf528SMauro Carvalho Chehab 	if (status < 0)
51569a0bf528SMauro Carvalho Chehab 		goto error;
51579a0bf528SMauro Carvalho Chehab 
51589a0bf528SMauro Carvalho Chehab 
51599a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
51609a0bf528SMauro Carvalho Chehab 
51619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
51629a0bf528SMauro Carvalho Chehab 	if (status < 0)
51639a0bf528SMauro Carvalho Chehab 		goto error;
51649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
51659a0bf528SMauro Carvalho Chehab 	if (status < 0)
51669a0bf528SMauro Carvalho Chehab 		goto error;
51679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
51689a0bf528SMauro Carvalho Chehab 	if (status < 0)
51699a0bf528SMauro Carvalho Chehab 		goto error;
51709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
51719a0bf528SMauro Carvalho Chehab 	if (status < 0)
51729a0bf528SMauro Carvalho Chehab 		goto error;
51739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
51749a0bf528SMauro Carvalho Chehab 	if (status < 0)
51759a0bf528SMauro Carvalho Chehab 		goto error;
51769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
51779a0bf528SMauro Carvalho Chehab 	if (status < 0)
51789a0bf528SMauro Carvalho Chehab 		goto error;
51799a0bf528SMauro Carvalho Chehab 
51809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
51819a0bf528SMauro Carvalho Chehab 	if (status < 0)
51829a0bf528SMauro Carvalho Chehab 		goto error;
51839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
51849a0bf528SMauro Carvalho Chehab 	if (status < 0)
51859a0bf528SMauro Carvalho Chehab 		goto error;
51869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
51879a0bf528SMauro Carvalho Chehab 	if (status < 0)
51889a0bf528SMauro Carvalho Chehab 		goto error;
51899a0bf528SMauro Carvalho Chehab 
51909a0bf528SMauro Carvalho Chehab 
51919a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
51929a0bf528SMauro Carvalho Chehab 
51939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
51949a0bf528SMauro Carvalho Chehab 	if (status < 0)
51959a0bf528SMauro Carvalho Chehab 		goto error;
51969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
51979a0bf528SMauro Carvalho Chehab 	if (status < 0)
51989a0bf528SMauro Carvalho Chehab 		goto error;
51999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
52009a0bf528SMauro Carvalho Chehab 	if (status < 0)
52019a0bf528SMauro Carvalho Chehab 		goto error;
52029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
52039a0bf528SMauro Carvalho Chehab 	if (status < 0)
52049a0bf528SMauro Carvalho Chehab 		goto error;
52059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
52069a0bf528SMauro Carvalho Chehab 	if (status < 0)
52079a0bf528SMauro Carvalho Chehab 		goto error;
52089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
52099a0bf528SMauro Carvalho Chehab 	if (status < 0)
52109a0bf528SMauro Carvalho Chehab 		goto error;
52119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
52129a0bf528SMauro Carvalho Chehab error:
52139a0bf528SMauro Carvalho Chehab 	if (status < 0)
52143a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52159a0bf528SMauro Carvalho Chehab 	return status;
52169a0bf528SMauro Carvalho Chehab }
52179a0bf528SMauro Carvalho Chehab 
52189a0bf528SMauro Carvalho Chehab 
52199a0bf528SMauro Carvalho Chehab /*============================================================================*/
522034eb9751SMauro Carvalho Chehab /*
52219a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
52229a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52239a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52249a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52259a0bf528SMauro Carvalho Chehab */
5226cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state)
52279a0bf528SMauro Carvalho Chehab {
52289a0bf528SMauro Carvalho Chehab 	int status;
5229cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
52309a0bf528SMauro Carvalho Chehab 
52319a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52329a0bf528SMauro Carvalho Chehab 	/* Stop QAM comstate->m_exec */
52339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52349a0bf528SMauro Carvalho Chehab 	if (status < 0)
52359a0bf528SMauro Carvalho Chehab 		goto error;
52369a0bf528SMauro Carvalho Chehab 
5237ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5238ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5239ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
52409a0bf528SMauro Carvalho Chehab error:
52419a0bf528SMauro Carvalho Chehab 	if (status < 0)
52423a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52439a0bf528SMauro Carvalho Chehab 	return status;
52449a0bf528SMauro Carvalho Chehab }
52459a0bf528SMauro Carvalho Chehab 
52469a0bf528SMauro Carvalho Chehab /*============================================================================*/
52479a0bf528SMauro Carvalho Chehab 
524834eb9751SMauro Carvalho Chehab /*
52499a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
52509a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52519a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52529a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52539a0bf528SMauro Carvalho Chehab */
5254cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state)
52559a0bf528SMauro Carvalho Chehab {
5256cd7a67a4SMauro Carvalho Chehab 	u32 adc_frequency = 0;
5257cd7a67a4SMauro Carvalho Chehab 	u32 symb_freq = 0;
5258cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate = 0;
52599a0bf528SMauro Carvalho Chehab 	u16 ratesel = 0;
5260cd7a67a4SMauro Carvalho Chehab 	u32 lc_symb_rate = 0;
52619a0bf528SMauro Carvalho Chehab 	int status;
52629a0bf528SMauro Carvalho Chehab 
52639a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52649a0bf528SMauro Carvalho Chehab 	/* Select & calculate correct IQM rate */
5265cd7a67a4SMauro Carvalho Chehab 	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
52669a0bf528SMauro Carvalho Chehab 	ratesel = 0;
52679a0bf528SMauro Carvalho Chehab 	if (state->props.symbol_rate <= 1188750)
52689a0bf528SMauro Carvalho Chehab 		ratesel = 3;
52699a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 2377500)
52709a0bf528SMauro Carvalho Chehab 		ratesel = 2;
52719a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 4755000)
52729a0bf528SMauro Carvalho Chehab 		ratesel = 1;
52739a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FD_RATESEL__A, ratesel);
52749a0bf528SMauro Carvalho Chehab 	if (status < 0)
52759a0bf528SMauro Carvalho Chehab 		goto error;
52769a0bf528SMauro Carvalho Chehab 
52779a0bf528SMauro Carvalho Chehab 	/*
52789a0bf528SMauro Carvalho Chehab 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
52799a0bf528SMauro Carvalho Chehab 		*/
5280cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate * (1 << ratesel);
5281cd7a67a4SMauro Carvalho Chehab 	if (symb_freq == 0) {
52829a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
52839a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
52849a0bf528SMauro Carvalho Chehab 		goto error;
52859a0bf528SMauro Carvalho Chehab 	}
5286cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5287cd7a67a4SMauro Carvalho Chehab 		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
52889a0bf528SMauro Carvalho Chehab 		(1 << 23);
5289cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
52909a0bf528SMauro Carvalho Chehab 	if (status < 0)
52919a0bf528SMauro Carvalho Chehab 		goto error;
5292cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_rc_rate = iqm_rc_rate;
52939a0bf528SMauro Carvalho Chehab 	/*
5294cd7a67a4SMauro Carvalho Chehab 		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
52959a0bf528SMauro Carvalho Chehab 		*/
5296cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate;
5297cd7a67a4SMauro Carvalho Chehab 	if (adc_frequency == 0) {
52989a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
52999a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53009a0bf528SMauro Carvalho Chehab 		goto error;
53019a0bf528SMauro Carvalho Chehab 	}
5302cd7a67a4SMauro Carvalho Chehab 	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5303cd7a67a4SMauro Carvalho Chehab 		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
53049a0bf528SMauro Carvalho Chehab 		16);
5305cd7a67a4SMauro Carvalho Chehab 	if (lc_symb_rate > 511)
5306cd7a67a4SMauro Carvalho Chehab 		lc_symb_rate = 511;
5307cd7a67a4SMauro Carvalho Chehab 	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
53089a0bf528SMauro Carvalho Chehab 
53099a0bf528SMauro Carvalho Chehab error:
53109a0bf528SMauro Carvalho Chehab 	if (status < 0)
53113a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53129a0bf528SMauro Carvalho Chehab 	return status;
53139a0bf528SMauro Carvalho Chehab }
53149a0bf528SMauro Carvalho Chehab 
53159a0bf528SMauro Carvalho Chehab /*============================================================================*/
53169a0bf528SMauro Carvalho Chehab 
531734eb9751SMauro Carvalho Chehab /*
53189a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
53199a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
53209a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
53219a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
53229a0bf528SMauro Carvalho Chehab */
53239a0bf528SMauro Carvalho Chehab 
5324cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
53259a0bf528SMauro Carvalho Chehab {
53269a0bf528SMauro Carvalho Chehab 	int status;
5327cd7a67a4SMauro Carvalho Chehab 	u16 result[2] = { 0, 0 };
53289a0bf528SMauro Carvalho Chehab 
53299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5330cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
53319a0bf528SMauro Carvalho Chehab 	status = scu_command(state,
53329a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_STANDARD_QAM |
53339a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5334cd7a67a4SMauro Carvalho Chehab 			result);
53359a0bf528SMauro Carvalho Chehab 	if (status < 0)
53363a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53379a0bf528SMauro Carvalho Chehab 
5338cd7a67a4SMauro Carvalho Chehab 	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53399a0bf528SMauro Carvalho Chehab 		/* 0x0000 NOT LOCKED */
5340cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53419a0bf528SMauro Carvalho Chehab 		/* 0x4000 DEMOD LOCKED */
5342cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
5343cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53449a0bf528SMauro Carvalho Chehab 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
5345cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
53469a0bf528SMauro Carvalho Chehab 	} else {
53479a0bf528SMauro Carvalho Chehab 		/* 0xC000 NEVER LOCKED */
53489a0bf528SMauro Carvalho Chehab 		/* (system will never be able to lock to the signal) */
5349ab5060cdSMauro Carvalho Chehab 		/*
5350ab5060cdSMauro Carvalho Chehab 		 * TODO: check this, intermediate & standard specific lock
5351ab5060cdSMauro Carvalho Chehab 		 * states are not taken into account here
5352ab5060cdSMauro Carvalho Chehab 		 */
5353cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
53549a0bf528SMauro Carvalho Chehab 	}
53559a0bf528SMauro Carvalho Chehab 	return status;
53569a0bf528SMauro Carvalho Chehab }
53579a0bf528SMauro Carvalho Chehab 
53589a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M         0x03
53599a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL     0x00
53609a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED          0x01
53619a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON    0x02
53629a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M      0x10
53639a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL  0x10
53649a0bf528SMauro Carvalho Chehab 
5365cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state,
5366cd7a67a4SMauro Carvalho Chehab 				 int number_of_parameters)
53679a0bf528SMauro Carvalho Chehab {
53689a0bf528SMauro Carvalho Chehab 	int status;
5369cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5370cd7a67a4SMauro Carvalho Chehab 	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
53719a0bf528SMauro Carvalho Chehab 
5372cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[0] = state->m_constellation;	/* modulation     */
5373cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
53749a0bf528SMauro Carvalho Chehab 
5375cd7a67a4SMauro Carvalho Chehab 	if (number_of_parameters == 2) {
5376cd7a67a4SMauro Carvalho Chehab 		u16 set_env_parameters[1] = { 0 };
53779a0bf528SMauro Carvalho Chehab 
5378cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5379cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_C;
53809a0bf528SMauro Carvalho Chehab 		else
5381cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_A;
53829a0bf528SMauro Carvalho Chehab 
53839a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5384ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5385ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5386cd7a67a4SMauro Carvalho Chehab 				     1, set_env_parameters, 1, &cmd_result);
53879a0bf528SMauro Carvalho Chehab 		if (status < 0)
53889a0bf528SMauro Carvalho Chehab 			goto error;
53899a0bf528SMauro Carvalho Chehab 
53909a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5391ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5392ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5393cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5394cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
5395cd7a67a4SMauro Carvalho Chehab 	} else if (number_of_parameters == 4) {
5396cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5397cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_C;
53989a0bf528SMauro Carvalho Chehab 		else
5399cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_A;
54009a0bf528SMauro Carvalho Chehab 
5401cd7a67a4SMauro Carvalho Chehab 		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
54029a0bf528SMauro Carvalho Chehab 		/* Env parameters */
5403868c9a17SMauro Carvalho Chehab 		/* check for LOCKRANGE Extended */
5404cd7a67a4SMauro Carvalho Chehab 		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
54059a0bf528SMauro Carvalho Chehab 
54069a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5407ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5408ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5409cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5410cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
54119a0bf528SMauro Carvalho Chehab 	} else {
54123a4398f5SMauro Carvalho Chehab 		pr_warn("Unknown QAM demodulator parameter count %d\n",
54133a4398f5SMauro Carvalho Chehab 			number_of_parameters);
541494af1b63SMauro Carvalho Chehab 		status = -EINVAL;
54159a0bf528SMauro Carvalho Chehab 	}
54169a0bf528SMauro Carvalho Chehab 
54179a0bf528SMauro Carvalho Chehab error:
54189a0bf528SMauro Carvalho Chehab 	if (status < 0)
54193a4398f5SMauro Carvalho Chehab 		pr_warn("Warning %d on %s\n", status, __func__);
54209a0bf528SMauro Carvalho Chehab 	return status;
54219a0bf528SMauro Carvalho Chehab }
54229a0bf528SMauro Carvalho Chehab 
5423cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5424cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset)
54259a0bf528SMauro Carvalho Chehab {
54269a0bf528SMauro Carvalho Chehab 	int status;
5427cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5428cd7a67a4SMauro Carvalho Chehab 	int qam_demod_param_count = state->qam_demod_parameter_count;
54299a0bf528SMauro Carvalho Chehab 
54309a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
54319a0bf528SMauro Carvalho Chehab 	/*
54329a0bf528SMauro Carvalho Chehab 	 * STEP 1: reset demodulator
54339a0bf528SMauro Carvalho Chehab 	 *	resets FEC DI and FEC RS
54349a0bf528SMauro Carvalho Chehab 	 *	resets QAM block
54359a0bf528SMauro Carvalho Chehab 	 *	resets SCU variables
54369a0bf528SMauro Carvalho Chehab 	 */
54379a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54389a0bf528SMauro Carvalho Chehab 	if (status < 0)
54399a0bf528SMauro Carvalho Chehab 		goto error;
54409a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54419a0bf528SMauro Carvalho Chehab 	if (status < 0)
54429a0bf528SMauro Carvalho Chehab 		goto error;
5443cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
54449a0bf528SMauro Carvalho Chehab 	if (status < 0)
54459a0bf528SMauro Carvalho Chehab 		goto error;
54469a0bf528SMauro Carvalho Chehab 
54479a0bf528SMauro Carvalho Chehab 	/*
54489a0bf528SMauro Carvalho Chehab 	 * STEP 2: configure demodulator
54499a0bf528SMauro Carvalho Chehab 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
54509a0bf528SMauro Carvalho Chehab 	 *       SCU variables
54519a0bf528SMauro Carvalho Chehab 	 */
5452cd7a67a4SMauro Carvalho Chehab 	status = qam_set_symbolrate(state);
54539a0bf528SMauro Carvalho Chehab 	if (status < 0)
54549a0bf528SMauro Carvalho Chehab 		goto error;
54559a0bf528SMauro Carvalho Chehab 
54569a0bf528SMauro Carvalho Chehab 	/* Set params */
54579a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
54589a0bf528SMauro Carvalho Chehab 	case QAM_256:
5459cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM256;
54609a0bf528SMauro Carvalho Chehab 		break;
54619a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
54629a0bf528SMauro Carvalho Chehab 	case QAM_64:
5463cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM64;
54649a0bf528SMauro Carvalho Chehab 		break;
54659a0bf528SMauro Carvalho Chehab 	case QAM_16:
5466cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM16;
54679a0bf528SMauro Carvalho Chehab 		break;
54689a0bf528SMauro Carvalho Chehab 	case QAM_32:
5469cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM32;
54709a0bf528SMauro Carvalho Chehab 		break;
54719a0bf528SMauro Carvalho Chehab 	case QAM_128:
5472cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM128;
54739a0bf528SMauro Carvalho Chehab 		break;
54749a0bf528SMauro Carvalho Chehab 	default:
54759a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
54769a0bf528SMauro Carvalho Chehab 		break;
54779a0bf528SMauro Carvalho Chehab 	}
54789a0bf528SMauro Carvalho Chehab 	if (status < 0)
54799a0bf528SMauro Carvalho Chehab 		goto error;
54809a0bf528SMauro Carvalho Chehab 
54819a0bf528SMauro Carvalho Chehab 	/* Use the 4-parameter if it's requested or we're probing for
54829a0bf528SMauro Carvalho Chehab 	 * the correct command. */
54839a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 4
54849a0bf528SMauro Carvalho Chehab 		|| !state->qam_demod_parameter_count) {
5485cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 4;
5486cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
54879a0bf528SMauro Carvalho Chehab 	}
54889a0bf528SMauro Carvalho Chehab 
54899a0bf528SMauro Carvalho Chehab 	/* Use the 2-parameter command if it was requested or if we're
54909a0bf528SMauro Carvalho Chehab 	 * probing for the correct command and the 4-parameter command
54919a0bf528SMauro Carvalho Chehab 	 * failed. */
54929a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 2
54939a0bf528SMauro Carvalho Chehab 		|| (!state->qam_demod_parameter_count && status < 0)) {
5494cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 2;
5495cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
54969a0bf528SMauro Carvalho Chehab 	}
54979a0bf528SMauro Carvalho Chehab 
54989a0bf528SMauro Carvalho Chehab 	if (status < 0) {
54990fb220f2SMauro Carvalho Chehab 		dprintk(1, "Could not set demodulator parameters.\n");
55000fb220f2SMauro Carvalho Chehab 		dprintk(1,
55010fb220f2SMauro Carvalho Chehab 			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
55029a0bf528SMauro Carvalho Chehab 			state->qam_demod_parameter_count,
55039a0bf528SMauro Carvalho Chehab 			state->microcode_name);
55049a0bf528SMauro Carvalho Chehab 		goto error;
55059a0bf528SMauro Carvalho Chehab 	} else if (!state->qam_demod_parameter_count) {
55060fb220f2SMauro Carvalho Chehab 		dprintk(1,
55070fb220f2SMauro Carvalho Chehab 			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
5508cd7a67a4SMauro Carvalho Chehab 			qam_demod_param_count);
55099a0bf528SMauro Carvalho Chehab 
55109a0bf528SMauro Carvalho Chehab 		/*
55119a0bf528SMauro Carvalho Chehab 		 * One of our commands was successful. We don't need to
55129a0bf528SMauro Carvalho Chehab 		 * auto-probe anymore, now that we got the correct command.
55139a0bf528SMauro Carvalho Chehab 		 */
5514cd7a67a4SMauro Carvalho Chehab 		state->qam_demod_parameter_count = qam_demod_param_count;
55159a0bf528SMauro Carvalho Chehab 	}
55169a0bf528SMauro Carvalho Chehab 
55179a0bf528SMauro Carvalho Chehab 	/*
55189a0bf528SMauro Carvalho Chehab 	 * STEP 3: enable the system in a mode where the ADC provides valid
55199a0bf528SMauro Carvalho Chehab 	 * signal setup modulation independent registers
55209a0bf528SMauro Carvalho Chehab 	 */
55219a0bf528SMauro Carvalho Chehab #if 0
5522cd7a67a4SMauro Carvalho Chehab 	status = set_frequency(channel, tuner_freq_offset));
55239a0bf528SMauro Carvalho Chehab 	if (status < 0)
55249a0bf528SMauro Carvalho Chehab 		goto error;
55259a0bf528SMauro Carvalho Chehab #endif
5526ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
5527ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
55289a0bf528SMauro Carvalho Chehab 	if (status < 0)
55299a0bf528SMauro Carvalho Chehab 		goto error;
55309a0bf528SMauro Carvalho Chehab 
55319a0bf528SMauro Carvalho Chehab 	/* Setup BER measurement */
5532ab5060cdSMauro Carvalho Chehab 	status = set_qam_measurement(state, state->m_constellation,
5533ab5060cdSMauro Carvalho Chehab 				     state->props.symbol_rate);
55349a0bf528SMauro Carvalho Chehab 	if (status < 0)
55359a0bf528SMauro Carvalho Chehab 		goto error;
55369a0bf528SMauro Carvalho Chehab 
55379a0bf528SMauro Carvalho Chehab 	/* Reset default values */
55389a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55399a0bf528SMauro Carvalho Chehab 	if (status < 0)
55409a0bf528SMauro Carvalho Chehab 		goto error;
55419a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55429a0bf528SMauro Carvalho Chehab 	if (status < 0)
55439a0bf528SMauro Carvalho Chehab 		goto error;
55449a0bf528SMauro Carvalho Chehab 
55459a0bf528SMauro Carvalho Chehab 	/* Reset default LC values */
55469a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55479a0bf528SMauro Carvalho Chehab 	if (status < 0)
55489a0bf528SMauro Carvalho Chehab 		goto error;
55499a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55509a0bf528SMauro Carvalho Chehab 	if (status < 0)
55519a0bf528SMauro Carvalho Chehab 		goto error;
55529a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
55539a0bf528SMauro Carvalho Chehab 	if (status < 0)
55549a0bf528SMauro Carvalho Chehab 		goto error;
55559a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_MODE__A, 7);
55569a0bf528SMauro Carvalho Chehab 	if (status < 0)
55579a0bf528SMauro Carvalho Chehab 		goto error;
55589a0bf528SMauro Carvalho Chehab 
55599a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
55609a0bf528SMauro Carvalho Chehab 	if (status < 0)
55619a0bf528SMauro Carvalho Chehab 		goto error;
55629a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
55639a0bf528SMauro Carvalho Chehab 	if (status < 0)
55649a0bf528SMauro Carvalho Chehab 		goto error;
55659a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
55669a0bf528SMauro Carvalho Chehab 	if (status < 0)
55679a0bf528SMauro Carvalho Chehab 		goto error;
55689a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
55699a0bf528SMauro Carvalho Chehab 	if (status < 0)
55709a0bf528SMauro Carvalho Chehab 		goto error;
55719a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
55729a0bf528SMauro Carvalho Chehab 	if (status < 0)
55739a0bf528SMauro Carvalho Chehab 		goto error;
55749a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
55759a0bf528SMauro Carvalho Chehab 	if (status < 0)
55769a0bf528SMauro Carvalho Chehab 		goto error;
55779a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
55789a0bf528SMauro Carvalho Chehab 	if (status < 0)
55799a0bf528SMauro Carvalho Chehab 		goto error;
55809a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
55819a0bf528SMauro Carvalho Chehab 	if (status < 0)
55829a0bf528SMauro Carvalho Chehab 		goto error;
55839a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
55849a0bf528SMauro Carvalho Chehab 	if (status < 0)
55859a0bf528SMauro Carvalho Chehab 		goto error;
55869a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
55879a0bf528SMauro Carvalho Chehab 	if (status < 0)
55889a0bf528SMauro Carvalho Chehab 		goto error;
55899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
55909a0bf528SMauro Carvalho Chehab 	if (status < 0)
55919a0bf528SMauro Carvalho Chehab 		goto error;
55929a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
55939a0bf528SMauro Carvalho Chehab 	if (status < 0)
55949a0bf528SMauro Carvalho Chehab 		goto error;
55959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
55969a0bf528SMauro Carvalho Chehab 	if (status < 0)
55979a0bf528SMauro Carvalho Chehab 		goto error;
55989a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
55999a0bf528SMauro Carvalho Chehab 	if (status < 0)
56009a0bf528SMauro Carvalho Chehab 		goto error;
56019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
56029a0bf528SMauro Carvalho Chehab 	if (status < 0)
56039a0bf528SMauro Carvalho Chehab 		goto error;
56049a0bf528SMauro Carvalho Chehab 
56059a0bf528SMauro Carvalho Chehab 	/* Mirroring, QAM-block starting point not inverted */
5606ab5060cdSMauro Carvalho Chehab 	status = write16(state, QAM_SY_SP_INV__A,
5607ab5060cdSMauro Carvalho Chehab 			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
56089a0bf528SMauro Carvalho Chehab 	if (status < 0)
56099a0bf528SMauro Carvalho Chehab 		goto error;
56109a0bf528SMauro Carvalho Chehab 
56119a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
56129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
56139a0bf528SMauro Carvalho Chehab 	if (status < 0)
56149a0bf528SMauro Carvalho Chehab 		goto error;
56159a0bf528SMauro Carvalho Chehab 
56169a0bf528SMauro Carvalho Chehab 	/* STEP 4: modulation specific setup */
56179a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
56189a0bf528SMauro Carvalho Chehab 	case QAM_16:
5619cd7a67a4SMauro Carvalho Chehab 		status = set_qam16(state);
56209a0bf528SMauro Carvalho Chehab 		break;
56219a0bf528SMauro Carvalho Chehab 	case QAM_32:
5622cd7a67a4SMauro Carvalho Chehab 		status = set_qam32(state);
56239a0bf528SMauro Carvalho Chehab 		break;
56249a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
56259a0bf528SMauro Carvalho Chehab 	case QAM_64:
5626cd7a67a4SMauro Carvalho Chehab 		status = set_qam64(state);
56279a0bf528SMauro Carvalho Chehab 		break;
56289a0bf528SMauro Carvalho Chehab 	case QAM_128:
5629cd7a67a4SMauro Carvalho Chehab 		status = set_qam128(state);
56309a0bf528SMauro Carvalho Chehab 		break;
56319a0bf528SMauro Carvalho Chehab 	case QAM_256:
5632cd7a67a4SMauro Carvalho Chehab 		status = set_qam256(state);
56339a0bf528SMauro Carvalho Chehab 		break;
56349a0bf528SMauro Carvalho Chehab 	default:
56359a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
56369a0bf528SMauro Carvalho Chehab 		break;
56379a0bf528SMauro Carvalho Chehab 	}
56389a0bf528SMauro Carvalho Chehab 	if (status < 0)
56399a0bf528SMauro Carvalho Chehab 		goto error;
56409a0bf528SMauro Carvalho Chehab 
56419a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
56429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56439a0bf528SMauro Carvalho Chehab 	if (status < 0)
56449a0bf528SMauro Carvalho Chehab 		goto error;
56459a0bf528SMauro Carvalho Chehab 
56469a0bf528SMauro Carvalho Chehab 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
56479a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.modulation = channel->modulation; */
56489a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
5649cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, state->m_operation_mode);
56509a0bf528SMauro Carvalho Chehab 	if (status < 0)
56519a0bf528SMauro Carvalho Chehab 		goto error;
56529a0bf528SMauro Carvalho Chehab 
5653cd7a67a4SMauro Carvalho Chehab 	/* start processes */
5654cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
56559a0bf528SMauro Carvalho Chehab 	if (status < 0)
56569a0bf528SMauro Carvalho Chehab 		goto error;
56579a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
56589a0bf528SMauro Carvalho Chehab 	if (status < 0)
56599a0bf528SMauro Carvalho Chehab 		goto error;
56609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
56619a0bf528SMauro Carvalho Chehab 	if (status < 0)
56629a0bf528SMauro Carvalho Chehab 		goto error;
56639a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
56649a0bf528SMauro Carvalho Chehab 	if (status < 0)
56659a0bf528SMauro Carvalho Chehab 		goto error;
56669a0bf528SMauro Carvalho Chehab 
56679a0bf528SMauro Carvalho Chehab 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5668ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5669ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
5670ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
56719a0bf528SMauro Carvalho Chehab 	if (status < 0)
56729a0bf528SMauro Carvalho Chehab 		goto error;
56739a0bf528SMauro Carvalho Chehab 
56749a0bf528SMauro Carvalho Chehab 	/* update global DRXK data container */
56759a0bf528SMauro Carvalho Chehab /*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
56769a0bf528SMauro Carvalho Chehab 
56779a0bf528SMauro Carvalho Chehab error:
56789a0bf528SMauro Carvalho Chehab 	if (status < 0)
56793a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
56809a0bf528SMauro Carvalho Chehab 	return status;
56819a0bf528SMauro Carvalho Chehab }
56829a0bf528SMauro Carvalho Chehab 
5683cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
5684cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
56859a0bf528SMauro Carvalho Chehab {
56869a0bf528SMauro Carvalho Chehab 	int status;
56879a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
56889a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
56899a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
56909a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
56919a0bf528SMauro Carvalho Chehab #endif
56929a0bf528SMauro Carvalho Chehab 
56939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
56949a0bf528SMauro Carvalho Chehab 
56959a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
5696cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_qam(state);
56979a0bf528SMauro Carvalho Chehab 
56989a0bf528SMauro Carvalho Chehab 	/* Ensure correct power-up mode */
5699cd7a67a4SMauro Carvalho Chehab 	status = power_up_qam(state);
57009a0bf528SMauro Carvalho Chehab 	if (status < 0)
57019a0bf528SMauro Carvalho Chehab 		goto error;
57029a0bf528SMauro Carvalho Chehab 	/* Reset QAM block */
5703cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
57049a0bf528SMauro Carvalho Chehab 	if (status < 0)
57059a0bf528SMauro Carvalho Chehab 		goto error;
57069a0bf528SMauro Carvalho Chehab 
57079a0bf528SMauro Carvalho Chehab 	/* Setup IQM */
57089a0bf528SMauro Carvalho Chehab 
57099a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
57109a0bf528SMauro Carvalho Chehab 	if (status < 0)
57119a0bf528SMauro Carvalho Chehab 		goto error;
57129a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
57139a0bf528SMauro Carvalho Chehab 	if (status < 0)
57149a0bf528SMauro Carvalho Chehab 		goto error;
57159a0bf528SMauro Carvalho Chehab 
57169a0bf528SMauro Carvalho Chehab 	/* Upload IQM Channel Filter settings by
57179a0bf528SMauro Carvalho Chehab 		boot loader from ROM table */
5718cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
57199a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
5720ab5060cdSMauro Carvalho Chehab 		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5721ab5060cdSMauro Carvalho Chehab 				      DRXK_BLCC_NR_ELEMENTS_TAPS,
5722ab5060cdSMauro Carvalho Chehab 			DRXK_BLC_TIMEOUT);
57239a0bf528SMauro Carvalho Chehab 		break;
57249a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
5725ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5726ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5727ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5728ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57299a0bf528SMauro Carvalho Chehab 		if (status < 0)
57309a0bf528SMauro Carvalho Chehab 			goto error;
5731ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state,
5732ab5060cdSMauro Carvalho Chehab 				       IQM_CF_TAP_IM0__A,
5733ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5734ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5735ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57369a0bf528SMauro Carvalho Chehab 		break;
57379a0bf528SMauro Carvalho Chehab 	default:
57389a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
57399a0bf528SMauro Carvalho Chehab 	}
57409a0bf528SMauro Carvalho Chehab 	if (status < 0)
57419a0bf528SMauro Carvalho Chehab 		goto error;
57429a0bf528SMauro Carvalho Chehab 
5743ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
57449a0bf528SMauro Carvalho Chehab 	if (status < 0)
57459a0bf528SMauro Carvalho Chehab 		goto error;
57469a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57479a0bf528SMauro Carvalho Chehab 	if (status < 0)
57489a0bf528SMauro Carvalho Chehab 		goto error;
5749ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_MIDTAP__A,
5750ab5060cdSMauro Carvalho Chehab 		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57519a0bf528SMauro Carvalho Chehab 	if (status < 0)
57529a0bf528SMauro Carvalho Chehab 		goto error;
57539a0bf528SMauro Carvalho Chehab 
57549a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 21);
57559a0bf528SMauro Carvalho Chehab 	if (status < 0)
57569a0bf528SMauro Carvalho Chehab 		goto error;
57579a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
57589a0bf528SMauro Carvalho Chehab 	if (status < 0)
57599a0bf528SMauro Carvalho Chehab 		goto error;
57609a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
57619a0bf528SMauro Carvalho Chehab 	if (status < 0)
57629a0bf528SMauro Carvalho Chehab 		goto error;
57639a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
57649a0bf528SMauro Carvalho Chehab 	if (status < 0)
57659a0bf528SMauro Carvalho Chehab 		goto error;
57669a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
57679a0bf528SMauro Carvalho Chehab 	if (status < 0)
57689a0bf528SMauro Carvalho Chehab 		goto error;
57699a0bf528SMauro Carvalho Chehab 
57709a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FS_ADJ_SEL__A, 1);
57719a0bf528SMauro Carvalho Chehab 	if (status < 0)
57729a0bf528SMauro Carvalho Chehab 		goto error;
57739a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_ADJ_SEL__A, 1);
57749a0bf528SMauro Carvalho Chehab 	if (status < 0)
57759a0bf528SMauro Carvalho Chehab 		goto error;
57769a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_ADJ_SEL__A, 1);
57779a0bf528SMauro Carvalho Chehab 	if (status < 0)
57789a0bf528SMauro Carvalho Chehab 		goto error;
57799a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 0);
57809a0bf528SMauro Carvalho Chehab 	if (status < 0)
57819a0bf528SMauro Carvalho Chehab 		goto error;
57829a0bf528SMauro Carvalho Chehab 
57839a0bf528SMauro Carvalho Chehab 	/* IQM Impulse Noise Processing Unit */
57849a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_CLP_VAL__A, 500);
57859a0bf528SMauro Carvalho Chehab 	if (status < 0)
57869a0bf528SMauro Carvalho Chehab 		goto error;
57879a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 1000);
57889a0bf528SMauro Carvalho Chehab 	if (status < 0)
57899a0bf528SMauro Carvalho Chehab 		goto error;
57909a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_BYPASSDET__A, 1);
57919a0bf528SMauro Carvalho Chehab 	if (status < 0)
57929a0bf528SMauro Carvalho Chehab 		goto error;
57939a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);
57949a0bf528SMauro Carvalho Chehab 	if (status < 0)
57959a0bf528SMauro Carvalho Chehab 		goto error;
57969a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 1);
57979a0bf528SMauro Carvalho Chehab 	if (status < 0)
57989a0bf528SMauro Carvalho Chehab 		goto error;
57999a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 1);
58009a0bf528SMauro Carvalho Chehab 	if (status < 0)
58019a0bf528SMauro Carvalho Chehab 		goto error;
58029a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_BYPASS__A, 1);
58039a0bf528SMauro Carvalho Chehab 	if (status < 0)
58049a0bf528SMauro Carvalho Chehab 		goto error;
58059a0bf528SMauro Carvalho Chehab 
58069a0bf528SMauro Carvalho Chehab 	/* turn on IQMAF. Must be done before setAgc**() */
5807cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
58089a0bf528SMauro Carvalho Chehab 	if (status < 0)
58099a0bf528SMauro Carvalho Chehab 		goto error;
58109a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
58119a0bf528SMauro Carvalho Chehab 	if (status < 0)
58129a0bf528SMauro Carvalho Chehab 		goto error;
58139a0bf528SMauro Carvalho Chehab 
58149a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
5815cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
58169a0bf528SMauro Carvalho Chehab 	if (status < 0)
58179a0bf528SMauro Carvalho Chehab 		goto error;
58189a0bf528SMauro Carvalho Chehab 
58199a0bf528SMauro Carvalho Chehab 	/* Set the FSM step period */
58209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
58219a0bf528SMauro Carvalho Chehab 	if (status < 0)
58229a0bf528SMauro Carvalho Chehab 		goto error;
58239a0bf528SMauro Carvalho Chehab 
58249a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
58259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
58269a0bf528SMauro Carvalho Chehab 	if (status < 0)
58279a0bf528SMauro Carvalho Chehab 		goto error;
58289a0bf528SMauro Carvalho Chehab 
58299a0bf528SMauro Carvalho Chehab 	/* No more resets of the IQM, current standard correctly set =>
58309a0bf528SMauro Carvalho Chehab 		now AGCs can be configured. */
58319a0bf528SMauro Carvalho Chehab 
5832cd7a67a4SMauro Carvalho Chehab 	status = init_agc(state, true);
58339a0bf528SMauro Carvalho Chehab 	if (status < 0)
58349a0bf528SMauro Carvalho Chehab 		goto error;
5835cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
58369a0bf528SMauro Carvalho Chehab 	if (status < 0)
58379a0bf528SMauro Carvalho Chehab 		goto error;
58389a0bf528SMauro Carvalho Chehab 
58399a0bf528SMauro Carvalho Chehab 	/* Configure AGC's */
5840cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
58419a0bf528SMauro Carvalho Chehab 	if (status < 0)
58429a0bf528SMauro Carvalho Chehab 		goto error;
5843cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
58449a0bf528SMauro Carvalho Chehab 	if (status < 0)
58459a0bf528SMauro Carvalho Chehab 		goto error;
58469a0bf528SMauro Carvalho Chehab 
58479a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
58489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58499a0bf528SMauro Carvalho Chehab error:
58509a0bf528SMauro Carvalho Chehab 	if (status < 0)
58513a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
58529a0bf528SMauro Carvalho Chehab 	return status;
58539a0bf528SMauro Carvalho Chehab }
58549a0bf528SMauro Carvalho Chehab 
5855cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state)
58569a0bf528SMauro Carvalho Chehab {
58579a0bf528SMauro Carvalho Chehab 	int status;
58589a0bf528SMauro Carvalho Chehab 	u16 value = 0;
58599a0bf528SMauro Carvalho Chehab 
58609a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
58619a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
5862ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
5863ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58649a0bf528SMauro Carvalho Chehab 	if (status < 0)
58659a0bf528SMauro Carvalho Chehab 		goto error;
58669a0bf528SMauro Carvalho Chehab 
58679a0bf528SMauro Carvalho Chehab 	/*  Write magic word to enable pdr reg write               */
58689a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
58699a0bf528SMauro Carvalho Chehab 	if (status < 0)
58709a0bf528SMauro Carvalho Chehab 		goto error;
58719a0bf528SMauro Carvalho Chehab 
5872cd7a67a4SMauro Carvalho Chehab 	if (state->m_has_sawsw) {
5873cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0001) { /* UIO-1 */
58749a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5875ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5876ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58779a0bf528SMauro Carvalho Chehab 			if (status < 0)
58789a0bf528SMauro Carvalho Chehab 				goto error;
58799a0bf528SMauro Carvalho Chehab 
58809a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
58819a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58829a0bf528SMauro Carvalho Chehab 			if (status < 0)
58839a0bf528SMauro Carvalho Chehab 				goto error;
5884cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0001) == 0)
58859a0bf528SMauro Carvalho Chehab 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
58869a0bf528SMauro Carvalho Chehab 			else
58879a0bf528SMauro Carvalho Chehab 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
58889a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
58899a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58909a0bf528SMauro Carvalho Chehab 			if (status < 0)
58919a0bf528SMauro Carvalho Chehab 				goto error;
58929a0bf528SMauro Carvalho Chehab 		}
5893cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0002) { /* UIO-2 */
58949a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5895ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5896ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
58979a0bf528SMauro Carvalho Chehab 			if (status < 0)
58989a0bf528SMauro Carvalho Chehab 				goto error;
58999a0bf528SMauro Carvalho Chehab 
59009a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59019a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59029a0bf528SMauro Carvalho Chehab 			if (status < 0)
59039a0bf528SMauro Carvalho Chehab 				goto error;
5904cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0002) == 0)
59059a0bf528SMauro Carvalho Chehab 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
59069a0bf528SMauro Carvalho Chehab 			else
59079a0bf528SMauro Carvalho Chehab 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
59089a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59099a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59109a0bf528SMauro Carvalho Chehab 			if (status < 0)
59119a0bf528SMauro Carvalho Chehab 				goto error;
59129a0bf528SMauro Carvalho Chehab 		}
5913cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0004) { /* UIO-3 */
59149a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5915ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_GPIO_CFG__A,
5916ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59179a0bf528SMauro Carvalho Chehab 			if (status < 0)
59189a0bf528SMauro Carvalho Chehab 				goto error;
59199a0bf528SMauro Carvalho Chehab 
59209a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59219a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59229a0bf528SMauro Carvalho Chehab 			if (status < 0)
59239a0bf528SMauro Carvalho Chehab 				goto error;
5924cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0004) == 0)
59259a0bf528SMauro Carvalho Chehab 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
59269a0bf528SMauro Carvalho Chehab 			else
59279a0bf528SMauro Carvalho Chehab 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
59289a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59299a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59309a0bf528SMauro Carvalho Chehab 			if (status < 0)
59319a0bf528SMauro Carvalho Chehab 				goto error;
59329a0bf528SMauro Carvalho Chehab 		}
59339a0bf528SMauro Carvalho Chehab 	}
59349a0bf528SMauro Carvalho Chehab 	/*  Write magic word to disable pdr reg write               */
59359a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59369a0bf528SMauro Carvalho Chehab error:
59379a0bf528SMauro Carvalho Chehab 	if (status < 0)
59383a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59399a0bf528SMauro Carvalho Chehab 	return status;
59409a0bf528SMauro Carvalho Chehab }
59419a0bf528SMauro Carvalho Chehab 
5942cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state)
59439a0bf528SMauro Carvalho Chehab {
59449a0bf528SMauro Carvalho Chehab 	int status = 0;
59459a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59469a0bf528SMauro Carvalho Chehab 
59479a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59489a0bf528SMauro Carvalho Chehab 
59499a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59509a0bf528SMauro Carvalho Chehab 		return 0;
59519a0bf528SMauro Carvalho Chehab 
5952cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59539a0bf528SMauro Carvalho Chehab 
59549a0bf528SMauro Carvalho Chehab 	if (state->antenna_dvbt ^ gpio_state) {
59559a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-T mode. Switch */
59569a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5957cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
59589a0bf528SMauro Carvalho Chehab 		else
5959cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
5960cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59619a0bf528SMauro Carvalho Chehab 	}
59629a0bf528SMauro Carvalho Chehab 	if (status < 0)
59633a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59649a0bf528SMauro Carvalho Chehab 	return status;
59659a0bf528SMauro Carvalho Chehab }
59669a0bf528SMauro Carvalho Chehab 
5967cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state)
59689a0bf528SMauro Carvalho Chehab {
59699a0bf528SMauro Carvalho Chehab 	int status = 0;
59709a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59719a0bf528SMauro Carvalho Chehab 
59729a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59739a0bf528SMauro Carvalho Chehab 
59749a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59759a0bf528SMauro Carvalho Chehab 		return 0;
59769a0bf528SMauro Carvalho Chehab 
5977cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59789a0bf528SMauro Carvalho Chehab 
59799a0bf528SMauro Carvalho Chehab 	if (!(state->antenna_dvbt ^ gpio_state)) {
59809a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-C mode. Switch */
59819a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5982cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
59839a0bf528SMauro Carvalho Chehab 		else
5984cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
5985cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59869a0bf528SMauro Carvalho Chehab 	}
59879a0bf528SMauro Carvalho Chehab 	if (status < 0)
59883a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59899a0bf528SMauro Carvalho Chehab 	return status;
59909a0bf528SMauro Carvalho Chehab }
59919a0bf528SMauro Carvalho Chehab 
59929a0bf528SMauro Carvalho Chehab 
5993cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state)
59949a0bf528SMauro Carvalho Chehab {
59959a0bf528SMauro Carvalho Chehab 	/* Power down to requested mode */
59969a0bf528SMauro Carvalho Chehab 	/* Backup some register settings */
59979a0bf528SMauro Carvalho Chehab 	/* Set pins with possible pull-ups connected to them in input mode */
59989a0bf528SMauro Carvalho Chehab 	/* Analog power down */
59999a0bf528SMauro Carvalho Chehab 	/* ADC power down */
60009a0bf528SMauro Carvalho Chehab 	/* Power down device */
60019a0bf528SMauro Carvalho Chehab 	int status;
60029a0bf528SMauro Carvalho Chehab 
60039a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6004cd7a67a4SMauro Carvalho Chehab 	if (state->m_b_p_down_open_bridge) {
60059a0bf528SMauro Carvalho Chehab 		/* Open I2C bridge before power down of DRXK */
60069a0bf528SMauro Carvalho Chehab 		status = ConfigureI2CBridge(state, true);
60079a0bf528SMauro Carvalho Chehab 		if (status < 0)
60089a0bf528SMauro Carvalho Chehab 			goto error;
60099a0bf528SMauro Carvalho Chehab 	}
60109a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
6011cd7a67a4SMauro Carvalho Chehab 	status = dvbt_enable_ofdm_token_ring(state, false);
60129a0bf528SMauro Carvalho Chehab 	if (status < 0)
60139a0bf528SMauro Carvalho Chehab 		goto error;
60149a0bf528SMauro Carvalho Chehab 
6015ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A,
6016ab5060cdSMauro Carvalho Chehab 			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
60179a0bf528SMauro Carvalho Chehab 	if (status < 0)
60189a0bf528SMauro Carvalho Chehab 		goto error;
60199a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60209a0bf528SMauro Carvalho Chehab 	if (status < 0)
60219a0bf528SMauro Carvalho Chehab 		goto error;
6022cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6023cd7a67a4SMauro Carvalho Chehab 	status = hi_cfg_command(state);
60249a0bf528SMauro Carvalho Chehab error:
60259a0bf528SMauro Carvalho Chehab 	if (status < 0)
60263a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
60279a0bf528SMauro Carvalho Chehab 
60289a0bf528SMauro Carvalho Chehab 	return status;
60299a0bf528SMauro Carvalho Chehab }
60309a0bf528SMauro Carvalho Chehab 
60319a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60329a0bf528SMauro Carvalho Chehab {
60339a0bf528SMauro Carvalho Chehab 	int status = 0, n = 0;
6034cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6035cd7a67a4SMauro Carvalho Chehab 	u16 driver_version;
60369a0bf528SMauro Carvalho Chehab 
60379a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60387369bbf2SNick Desaulniers 	if (state->m_drxk_state == DRXK_UNINITIALIZED) {
60399a0bf528SMauro Carvalho Chehab 		drxk_i2c_lock(state);
6040cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
60419a0bf528SMauro Carvalho Chehab 		if (status < 0)
60429a0bf528SMauro Carvalho Chehab 			goto error;
6043cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
60449a0bf528SMauro Carvalho Chehab 		if (status < 0)
60459a0bf528SMauro Carvalho Chehab 			goto error;
60469a0bf528SMauro Carvalho Chehab 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
6047ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_CC_SOFT_RST__A,
6048ab5060cdSMauro Carvalho Chehab 				 SIO_CC_SOFT_RST_OFDM__M
6049ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_SYS__M
6050ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_OSC__M);
60519a0bf528SMauro Carvalho Chehab 		if (status < 0)
60529a0bf528SMauro Carvalho Chehab 			goto error;
60539a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60549a0bf528SMauro Carvalho Chehab 		if (status < 0)
60559a0bf528SMauro Carvalho Chehab 			goto error;
6056ab5060cdSMauro Carvalho Chehab 		/*
6057ab5060cdSMauro Carvalho Chehab 		 * TODO is this needed? If yes, how much delay in
6058ab5060cdSMauro Carvalho Chehab 		 * worst case scenario
6059ab5060cdSMauro Carvalho Chehab 		 */
6060b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
6061cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_a3_patch_code = true;
6062cd7a67a4SMauro Carvalho Chehab 		status = get_device_capabilities(state);
60639a0bf528SMauro Carvalho Chehab 		if (status < 0)
60649a0bf528SMauro Carvalho Chehab 			goto error;
60659a0bf528SMauro Carvalho Chehab 
60669a0bf528SMauro Carvalho Chehab 		/* Bridge delay, uses oscilator clock */
60679a0bf528SMauro Carvalho Chehab 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60689a0bf528SMauro Carvalho Chehab 		/* SDA brdige delay */
6069cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay =
6070cd7a67a4SMauro Carvalho Chehab 			(u16) ((state->m_osc_clock_freq / 1000) *
60719a0bf528SMauro Carvalho Chehab 				HI_I2C_BRIDGE_DELAY) / 1000;
60729a0bf528SMauro Carvalho Chehab 		/* Clipping */
6073cd7a67a4SMauro Carvalho Chehab 		if (state->m_hi_cfg_bridge_delay >
60749a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6075cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay =
60769a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
60779a0bf528SMauro Carvalho Chehab 		}
60789a0bf528SMauro Carvalho Chehab 		/* SCL bridge delay, same as SDA for now */
6079cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay +=
6080cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay <<
60819a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
60829a0bf528SMauro Carvalho Chehab 
6083cd7a67a4SMauro Carvalho Chehab 		status = init_hi(state);
60849a0bf528SMauro Carvalho Chehab 		if (status < 0)
60859a0bf528SMauro Carvalho Chehab 			goto error;
60869a0bf528SMauro Carvalho Chehab 		/* disable various processes */
60879a0bf528SMauro Carvalho Chehab #if NOA1ROM
60889a0bf528SMauro Carvalho Chehab 		if (!(state->m_DRXK_A1_ROM_CODE)
60899a0bf528SMauro Carvalho Chehab 			&& !(state->m_DRXK_A2_ROM_CODE))
60909a0bf528SMauro Carvalho Chehab #endif
60919a0bf528SMauro Carvalho Chehab 		{
6092ab5060cdSMauro Carvalho Chehab 			status = write16(state, SCU_RAM_GPIO__A,
6093ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
60949a0bf528SMauro Carvalho Chehab 			if (status < 0)
60959a0bf528SMauro Carvalho Chehab 				goto error;
60969a0bf528SMauro Carvalho Chehab 		}
60979a0bf528SMauro Carvalho Chehab 
60989a0bf528SMauro Carvalho Chehab 		/* disable MPEG port */
6099cd7a67a4SMauro Carvalho Chehab 		status = mpegts_disable(state);
61009a0bf528SMauro Carvalho Chehab 		if (status < 0)
61019a0bf528SMauro Carvalho Chehab 			goto error;
61029a0bf528SMauro Carvalho Chehab 
61039a0bf528SMauro Carvalho Chehab 		/* Stop AUD and SCU */
61049a0bf528SMauro Carvalho Chehab 		status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
61059a0bf528SMauro Carvalho Chehab 		if (status < 0)
61069a0bf528SMauro Carvalho Chehab 			goto error;
61079a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
61089a0bf528SMauro Carvalho Chehab 		if (status < 0)
61099a0bf528SMauro Carvalho Chehab 			goto error;
61109a0bf528SMauro Carvalho Chehab 
61119a0bf528SMauro Carvalho Chehab 		/* enable token-ring bus through OFDM block for possible ucode upload */
6112ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6113ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
61149a0bf528SMauro Carvalho Chehab 		if (status < 0)
61159a0bf528SMauro Carvalho Chehab 			goto error;
61169a0bf528SMauro Carvalho Chehab 
61179a0bf528SMauro Carvalho Chehab 		/* include boot loader section */
6118ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_BL_COMM_EXEC__A,
6119ab5060cdSMauro Carvalho Chehab 				 SIO_BL_COMM_EXEC_ACTIVE);
61209a0bf528SMauro Carvalho Chehab 		if (status < 0)
61219a0bf528SMauro Carvalho Chehab 			goto error;
6122cd7a67a4SMauro Carvalho Chehab 		status = bl_chain_cmd(state, 0, 6, 100);
61239a0bf528SMauro Carvalho Chehab 		if (status < 0)
61249a0bf528SMauro Carvalho Chehab 			goto error;
61259a0bf528SMauro Carvalho Chehab 
61269a0bf528SMauro Carvalho Chehab 		if (state->fw) {
6127cd7a67a4SMauro Carvalho Chehab 			status = download_microcode(state, state->fw->data,
61289a0bf528SMauro Carvalho Chehab 						   state->fw->size);
61299a0bf528SMauro Carvalho Chehab 			if (status < 0)
61309a0bf528SMauro Carvalho Chehab 				goto error;
61319a0bf528SMauro Carvalho Chehab 		}
61329a0bf528SMauro Carvalho Chehab 
61339a0bf528SMauro Carvalho Chehab 		/* disable 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_OFF);
61369a0bf528SMauro Carvalho Chehab 		if (status < 0)
61379a0bf528SMauro Carvalho Chehab 			goto error;
61389a0bf528SMauro Carvalho Chehab 
61399a0bf528SMauro Carvalho Chehab 		/* Run SCU for a little while to initialize microcode version numbers */
61409a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61419a0bf528SMauro Carvalho Chehab 		if (status < 0)
61429a0bf528SMauro Carvalho Chehab 			goto error;
6143cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
61449a0bf528SMauro Carvalho Chehab 		if (status < 0)
61459a0bf528SMauro Carvalho Chehab 			goto error;
61469a0bf528SMauro Carvalho Chehab 		/* added for test */
61479a0bf528SMauro Carvalho Chehab 		msleep(30);
61489a0bf528SMauro Carvalho Chehab 
6149cd7a67a4SMauro Carvalho Chehab 		power_mode = DRXK_POWER_DOWN_OFDM;
6150cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
61519a0bf528SMauro Carvalho Chehab 		if (status < 0)
61529a0bf528SMauro Carvalho Chehab 			goto error;
61539a0bf528SMauro Carvalho Chehab 
61549a0bf528SMauro Carvalho Chehab 		/* Stamp driver version number in SCU data RAM in BCD code
615539c1cb2bSJonathan McCrohan 			Done to enable field application engineers to retrieve drxdriver version
61569a0bf528SMauro Carvalho Chehab 			via I2C from SCU RAM.
61579a0bf528SMauro Carvalho Chehab 			Not using SCU command interface for SCU register access since no
61589a0bf528SMauro Carvalho Chehab 			microcode may be present.
61599a0bf528SMauro Carvalho Chehab 			*/
6160cd7a67a4SMauro Carvalho Chehab 		driver_version =
61619a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61629a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61639a0bf528SMauro Carvalho Chehab 			((DRXK_VERSION_MAJOR % 10) << 4) +
61649a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_MINOR % 10);
6165ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6166ab5060cdSMauro Carvalho Chehab 				 driver_version);
61679a0bf528SMauro Carvalho Chehab 		if (status < 0)
61689a0bf528SMauro Carvalho Chehab 			goto error;
6169cd7a67a4SMauro Carvalho Chehab 		driver_version =
61709a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61719a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61729a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
61739a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_PATCH % 10);
6174ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6175ab5060cdSMauro Carvalho Chehab 				 driver_version);
61769a0bf528SMauro Carvalho Chehab 		if (status < 0)
61779a0bf528SMauro Carvalho Chehab 			goto error;
61789a0bf528SMauro Carvalho Chehab 
61793a4398f5SMauro Carvalho Chehab 		pr_info("DRXK driver version %d.%d.%d\n",
61809a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
61819a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_PATCH);
61829a0bf528SMauro Carvalho Chehab 
6183ab5060cdSMauro Carvalho Chehab 		/*
6184ab5060cdSMauro Carvalho Chehab 		 * Dirty fix of default values for ROM/PATCH microcode
6185ab5060cdSMauro Carvalho Chehab 		 * Dirty because this fix makes it impossible to setup
6186ab5060cdSMauro Carvalho Chehab 		 * suitable values before calling DRX_Open. This solution
6187ab5060cdSMauro Carvalho Chehab 		 * requires changes to RF AGC speed to be done via the CTRL
6188ab5060cdSMauro Carvalho Chehab 		 * function after calling DRX_Open
6189ab5060cdSMauro Carvalho Chehab 		 */
61909a0bf528SMauro Carvalho Chehab 
6191cd7a67a4SMauro Carvalho Chehab 		/* m_dvbt_rf_agc_cfg.speed = 3; */
61929a0bf528SMauro Carvalho Chehab 
61939a0bf528SMauro Carvalho Chehab 		/* Reset driver debug flags to 0 */
61949a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
61959a0bf528SMauro Carvalho Chehab 		if (status < 0)
61969a0bf528SMauro Carvalho Chehab 			goto error;
61979a0bf528SMauro Carvalho Chehab 		/* driver 0.9.0 */
61989a0bf528SMauro Carvalho Chehab 		/* Setup FEC OC:
61999a0bf528SMauro Carvalho Chehab 			NOTE: No more full FEC resets allowed afterwards!! */
62009a0bf528SMauro Carvalho Chehab 		status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
62019a0bf528SMauro Carvalho Chehab 		if (status < 0)
62029a0bf528SMauro Carvalho Chehab 			goto error;
62039a0bf528SMauro Carvalho Chehab 		/* MPEGTS functions are still the same */
6204cd7a67a4SMauro Carvalho Chehab 		status = mpegts_dto_init(state);
62059a0bf528SMauro Carvalho Chehab 		if (status < 0)
62069a0bf528SMauro Carvalho Chehab 			goto error;
6207cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
62089a0bf528SMauro Carvalho Chehab 		if (status < 0)
62099a0bf528SMauro Carvalho Chehab 			goto error;
6210cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_polarity(state);
62119a0bf528SMauro Carvalho Chehab 		if (status < 0)
62129a0bf528SMauro Carvalho Chehab 			goto error;
6213cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
62149a0bf528SMauro Carvalho Chehab 		if (status < 0)
62159a0bf528SMauro Carvalho Chehab 			goto error;
62169a0bf528SMauro Carvalho Chehab 		/* added: configure GPIO */
6217cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
62189a0bf528SMauro Carvalho Chehab 		if (status < 0)
62199a0bf528SMauro Carvalho Chehab 			goto error;
62209a0bf528SMauro Carvalho Chehab 
6221cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_STOPPED;
62229a0bf528SMauro Carvalho Chehab 
6223cd7a67a4SMauro Carvalho Chehab 		if (state->m_b_power_down) {
6224cd7a67a4SMauro Carvalho Chehab 			status = power_down_device(state);
62259a0bf528SMauro Carvalho Chehab 			if (status < 0)
62269a0bf528SMauro Carvalho Chehab 				goto error;
6227cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_POWERED_DOWN;
62289a0bf528SMauro Carvalho Chehab 		} else
6229cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_STOPPED;
62309a0bf528SMauro Carvalho Chehab 
62319a0bf528SMauro Carvalho Chehab 		/* Initialize the supported delivery systems */
62329a0bf528SMauro Carvalho Chehab 		n = 0;
6233cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbc) {
62349a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62359a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62369a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-C",
62379a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62389a0bf528SMauro Carvalho Chehab 		}
6239cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbt) {
62409a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBT;
62419a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-T",
62429a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62439a0bf528SMauro Carvalho Chehab 		}
62449a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62459a0bf528SMauro Carvalho Chehab 	}
62469a0bf528SMauro Carvalho Chehab error:
62479a0bf528SMauro Carvalho Chehab 	if (status < 0) {
6248cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_NO_DEV;
62499a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62503a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
62519a0bf528SMauro Carvalho Chehab 	}
62529a0bf528SMauro Carvalho Chehab 
62539a0bf528SMauro Carvalho Chehab 	return status;
62549a0bf528SMauro Carvalho Chehab }
62559a0bf528SMauro Carvalho Chehab 
62569a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62579a0bf528SMauro Carvalho Chehab 			     void *context)
62589a0bf528SMauro Carvalho Chehab {
62599a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = context;
62609a0bf528SMauro Carvalho Chehab 
62619a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62629a0bf528SMauro Carvalho Chehab 	if (!fw) {
62633a4398f5SMauro Carvalho Chehab 		pr_err("Could not load firmware file %s.\n",
62649a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62653a4398f5SMauro Carvalho Chehab 		pr_info("Copy %s to your hotplug directory!\n",
62669a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62679a0bf528SMauro Carvalho Chehab 		state->microcode_name = NULL;
62689a0bf528SMauro Carvalho Chehab 
62699a0bf528SMauro Carvalho Chehab 		/*
62709a0bf528SMauro Carvalho Chehab 		 * As firmware is now load asynchronous, it is not possible
62719a0bf528SMauro Carvalho Chehab 		 * anymore to fail at frontend attach. We might silently
62729a0bf528SMauro Carvalho Chehab 		 * return here, and hope that the driver won't crash.
62739a0bf528SMauro Carvalho Chehab 		 * We might also change all DVB callbacks to return -ENODEV
62749a0bf528SMauro Carvalho Chehab 		 * if the device is not initialized.
62759a0bf528SMauro Carvalho Chehab 		 * As the DRX-K devices have their own internal firmware,
62769a0bf528SMauro Carvalho Chehab 		 * let's just hope that it will match a firmware revision
62779a0bf528SMauro Carvalho Chehab 		 * compatible with this driver and proceed.
62789a0bf528SMauro Carvalho Chehab 		 */
62799a0bf528SMauro Carvalho Chehab 	}
62809a0bf528SMauro Carvalho Chehab 	state->fw = fw;
62819a0bf528SMauro Carvalho Chehab 
62829a0bf528SMauro Carvalho Chehab 	init_drxk(state);
62839a0bf528SMauro Carvalho Chehab }
62849a0bf528SMauro Carvalho Chehab 
62859a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
62869a0bf528SMauro Carvalho Chehab {
62879a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62889a0bf528SMauro Carvalho Chehab 
62899a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
62909a0bf528SMauro Carvalho Chehab 	release_firmware(state->fw);
62919a0bf528SMauro Carvalho Chehab 
62929a0bf528SMauro Carvalho Chehab 	kfree(state);
62939a0bf528SMauro Carvalho Chehab }
62949a0bf528SMauro Carvalho Chehab 
62959a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
62969a0bf528SMauro Carvalho Chehab {
62979a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
62989a0bf528SMauro Carvalho Chehab 
62999a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63009a0bf528SMauro Carvalho Chehab 
6301cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63029a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6303cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63049a0bf528SMauro Carvalho Chehab 		return 0;
63059a0bf528SMauro Carvalho Chehab 
6306cd7a67a4SMauro Carvalho Chehab 	shut_down(state);
63079a0bf528SMauro Carvalho Chehab 	return 0;
63089a0bf528SMauro Carvalho Chehab }
63099a0bf528SMauro Carvalho Chehab 
63109a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
63119a0bf528SMauro Carvalho Chehab {
63129a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63139a0bf528SMauro Carvalho Chehab 
63149a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
63159a0bf528SMauro Carvalho Chehab 
6316cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63179a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63189a0bf528SMauro Carvalho Chehab 
63199a0bf528SMauro Carvalho Chehab 	return ConfigureI2CBridge(state, enable ? true : false);
63209a0bf528SMauro Carvalho Chehab }
63219a0bf528SMauro Carvalho Chehab 
63229a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
63239a0bf528SMauro Carvalho Chehab {
63249a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
63259a0bf528SMauro Carvalho Chehab 	u32 delsys  = p->delivery_system, old_delsys;
63269a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63279a0bf528SMauro Carvalho Chehab 	u32 IF;
63289a0bf528SMauro Carvalho Chehab 
63299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63309a0bf528SMauro Carvalho Chehab 
6331cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63329a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63339a0bf528SMauro Carvalho Chehab 
6334cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63359a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
63369a0bf528SMauro Carvalho Chehab 
63379a0bf528SMauro Carvalho Chehab 	if (!fe->ops.tuner_ops.get_if_frequency) {
63383a4398f5SMauro Carvalho Chehab 		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63399a0bf528SMauro Carvalho Chehab 		return -EINVAL;
63409a0bf528SMauro Carvalho Chehab 	}
63419a0bf528SMauro Carvalho Chehab 
63429a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63439a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 1);
63449a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
63459a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
63469a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63479a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 0);
63489a0bf528SMauro Carvalho Chehab 
63499a0bf528SMauro Carvalho Chehab 	old_delsys = state->props.delivery_system;
63509a0bf528SMauro Carvalho Chehab 	state->props = *p;
63519a0bf528SMauro Carvalho Chehab 
63529a0bf528SMauro Carvalho Chehab 	if (old_delsys != delsys) {
6353cd7a67a4SMauro Carvalho Chehab 		shut_down(state);
63549a0bf528SMauro Carvalho Chehab 		switch (delsys) {
63559a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_A:
63569a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_C:
6357cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbc)
63589a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6359ab5060cdSMauro Carvalho Chehab 			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6360ab5060cdSMauro Carvalho Chehab 						true : false;
63619a0bf528SMauro Carvalho Chehab 			if (state->m_itut_annex_c)
6362cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_C);
63639a0bf528SMauro Carvalho Chehab 			else
6364cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_A);
63659a0bf528SMauro Carvalho Chehab 			break;
63669a0bf528SMauro Carvalho Chehab 		case SYS_DVBT:
6367cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbt)
63689a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6369cd7a67a4SMauro Carvalho Chehab 			setoperation_mode(state, OM_DVBT);
63709a0bf528SMauro Carvalho Chehab 			break;
63719a0bf528SMauro Carvalho Chehab 		default:
63729a0bf528SMauro Carvalho Chehab 			return -EINVAL;
63739a0bf528SMauro Carvalho Chehab 		}
63749a0bf528SMauro Carvalho Chehab 	}
63759a0bf528SMauro Carvalho Chehab 
63769a0bf528SMauro Carvalho Chehab 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
6377cd7a67a4SMauro Carvalho Chehab 	start(state, 0, IF);
63789a0bf528SMauro Carvalho Chehab 
637939c1cb2bSJonathan McCrohan 	/* After set_frontend, stats aren't available */
63808f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
63818f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63828f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63838f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63848f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63858f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63868f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63878f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63888f3741e0SMauro Carvalho Chehab 
63899a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
63909a0bf528SMauro Carvalho Chehab 
63919a0bf528SMauro Carvalho Chehab 	return 0;
63929a0bf528SMauro Carvalho Chehab }
63939a0bf528SMauro Carvalho Chehab 
639459a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength)
639559a7a23cSMauro Carvalho Chehab {
639659a7a23cSMauro Carvalho Chehab 	int status;
6397cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc   rf_agc, if_agc;
6398cd7a67a4SMauro Carvalho Chehab 	u32          total_gain  = 0;
639959a7a23cSMauro Carvalho Chehab 	u32          atten      = 0;
6400cd7a67a4SMauro Carvalho Chehab 	u32          agc_range   = 0;
640159a7a23cSMauro Carvalho Chehab 	u16            scu_lvl  = 0;
640259a7a23cSMauro Carvalho Chehab 	u16            scu_coc  = 0;
640359a7a23cSMauro Carvalho Chehab 	/* FIXME: those are part of the tuner presets */
6404cd7a67a4SMauro Carvalho Chehab 	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
6405cd7a67a4SMauro Carvalho Chehab 	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
640659a7a23cSMauro Carvalho Chehab 
640759a7a23cSMauro Carvalho Chehab 	*strength = 0;
640859a7a23cSMauro Carvalho Chehab 
6409cd7a67a4SMauro Carvalho Chehab 	if (is_dvbt(state)) {
6410cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_dvbt_rf_agc_cfg;
6411cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_dvbt_if_agc_cfg;
6412cd7a67a4SMauro Carvalho Chehab 	} else if (is_qam(state)) {
6413cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_qam_rf_agc_cfg;
6414cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_qam_if_agc_cfg;
641559a7a23cSMauro Carvalho Chehab 	} else {
6416cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_atv_rf_agc_cfg;
6417cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_atv_if_agc_cfg;
641859a7a23cSMauro Carvalho Chehab 	}
641959a7a23cSMauro Carvalho Chehab 
6420cd7a67a4SMauro Carvalho Chehab 	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6421cd7a67a4SMauro Carvalho Chehab 		/* SCU output_level */
642259a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
642359a7a23cSMauro Carvalho Chehab 		if (status < 0)
642459a7a23cSMauro Carvalho Chehab 			return status;
642559a7a23cSMauro Carvalho Chehab 
642659a7a23cSMauro Carvalho Chehab 		/* SCU c.o.c. */
6427d259a5eeSChristophe JAILLET 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
642859a7a23cSMauro Carvalho Chehab 		if (status < 0)
642959a7a23cSMauro Carvalho Chehab 			return status;
643059a7a23cSMauro Carvalho Chehab 
643159a7a23cSMauro Carvalho Chehab 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6432cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = scu_lvl + scu_coc;
643359a7a23cSMauro Carvalho Chehab 		else
6434cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = 0xffff;
643559a7a23cSMauro Carvalho Chehab 
643659a7a23cSMauro Carvalho Chehab 		/* Take RF gain into account */
6437cd7a67a4SMauro Carvalho Chehab 		total_gain += tuner_rf_gain;
643859a7a23cSMauro Carvalho Chehab 
643959a7a23cSMauro Carvalho Chehab 		/* clip output value */
6440cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level < rf_agc.min_output_level)
6441cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.min_output_level;
6442cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level > rf_agc.max_output_level)
6443cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.max_output_level;
644459a7a23cSMauro Carvalho Chehab 
6445cd7a67a4SMauro Carvalho Chehab 		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6446cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
644759a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6448cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_rf_gain)) *
6449cd7a67a4SMauro Carvalho Chehab 				((u32)(rf_agc.output_level - rf_agc.min_output_level))
6450cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
645159a7a23cSMauro Carvalho Chehab 		}
645259a7a23cSMauro Carvalho Chehab 	}
645359a7a23cSMauro Carvalho Chehab 
6454cd7a67a4SMauro Carvalho Chehab 	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
645559a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6456cd7a67a4SMauro Carvalho Chehab 				&if_agc.output_level);
645759a7a23cSMauro Carvalho Chehab 		if (status < 0)
645859a7a23cSMauro Carvalho Chehab 			return status;
645959a7a23cSMauro Carvalho Chehab 
646059a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6461cd7a67a4SMauro Carvalho Chehab 				&if_agc.top);
646259a7a23cSMauro Carvalho Chehab 		if (status < 0)
646359a7a23cSMauro Carvalho Chehab 			return status;
646459a7a23cSMauro Carvalho Chehab 
646559a7a23cSMauro Carvalho Chehab 		/* Take IF gain into account */
6466cd7a67a4SMauro Carvalho Chehab 		total_gain += (u32) tuner_if_gain;
646759a7a23cSMauro Carvalho Chehab 
646859a7a23cSMauro Carvalho Chehab 		/* clip output value */
6469cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level < if_agc.min_output_level)
6470cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.min_output_level;
6471cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level > if_agc.max_output_level)
6472cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.max_output_level;
647359a7a23cSMauro Carvalho Chehab 
6474cd7a67a4SMauro Carvalho Chehab 		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
6475cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
647659a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6477cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_if_gain)) *
6478cd7a67a4SMauro Carvalho Chehab 				((u32)(if_agc.output_level - if_agc.min_output_level))
6479cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
648059a7a23cSMauro Carvalho Chehab 		}
648159a7a23cSMauro Carvalho Chehab 	}
648259a7a23cSMauro Carvalho Chehab 
648359a7a23cSMauro Carvalho Chehab 	/*
648459a7a23cSMauro Carvalho Chehab 	 * Convert to 0..65535 scale.
648559a7a23cSMauro Carvalho Chehab 	 * If it can't be measured (AGC is disabled), just show 100%.
648659a7a23cSMauro Carvalho Chehab 	 */
6487cd7a67a4SMauro Carvalho Chehab 	if (total_gain > 0)
6488cd7a67a4SMauro Carvalho Chehab 		*strength = (65535UL * atten / total_gain / 100);
648959a7a23cSMauro Carvalho Chehab 	else
649059a7a23cSMauro Carvalho Chehab 		*strength = 65535;
649159a7a23cSMauro Carvalho Chehab 
649259a7a23cSMauro Carvalho Chehab 	return 0;
649359a7a23cSMauro Carvalho Chehab }
649459a7a23cSMauro Carvalho Chehab 
64958f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe)
64969a0bf528SMauro Carvalho Chehab {
64978f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
64989a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64998f3741e0SMauro Carvalho Chehab 	int status;
65009a0bf528SMauro Carvalho Chehab 	u32 stat;
65018f3741e0SMauro Carvalho Chehab 	u16 reg16;
65028f3741e0SMauro Carvalho Chehab 	u32 post_bit_count;
65038f3741e0SMauro Carvalho Chehab 	u32 post_bit_err_count;
65048f3741e0SMauro Carvalho Chehab 	u32 post_bit_error_scale;
65058f3741e0SMauro Carvalho Chehab 	u32 pre_bit_err_count;
65068f3741e0SMauro Carvalho Chehab 	u32 pre_bit_count;
65078f3741e0SMauro Carvalho Chehab 	u32 pkt_count;
65088f3741e0SMauro Carvalho Chehab 	u32 pkt_error_count;
650959a7a23cSMauro Carvalho Chehab 	s32 cnr;
65109a0bf528SMauro Carvalho Chehab 
6511cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
65129a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6513cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
65149a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
65159a0bf528SMauro Carvalho Chehab 
65168f3741e0SMauro Carvalho Chehab 	/* get status */
65178f3741e0SMauro Carvalho Chehab 	state->fe_status = 0;
6518cd7a67a4SMauro Carvalho Chehab 	get_lock_status(state, &stat);
65199a0bf528SMauro Carvalho Chehab 	if (stat == MPEG_LOCK)
65208f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x1f;
65219a0bf528SMauro Carvalho Chehab 	if (stat == FEC_LOCK)
65228f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x0f;
65239a0bf528SMauro Carvalho Chehab 	if (stat == DEMOD_LOCK)
65248f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x07;
65258f3741e0SMauro Carvalho Chehab 
652659a7a23cSMauro Carvalho Chehab 	/*
652759a7a23cSMauro Carvalho Chehab 	 * Estimate signal strength from AGC
652859a7a23cSMauro Carvalho Chehab 	 */
652959a7a23cSMauro Carvalho Chehab 	get_strength(state, &c->strength.stat[0].uvalue);
653059a7a23cSMauro Carvalho Chehab 	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
653159a7a23cSMauro Carvalho Chehab 
653259a7a23cSMauro Carvalho Chehab 
65338f3741e0SMauro Carvalho Chehab 	if (stat >= DEMOD_LOCK) {
6534cd7a67a4SMauro Carvalho Chehab 		get_signal_to_noise(state, &cnr);
65358f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].svalue = cnr * 100;
65368f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
65378f3741e0SMauro Carvalho Chehab 	} else {
65388f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65398f3741e0SMauro Carvalho Chehab 	}
65408f3741e0SMauro Carvalho Chehab 
65418f3741e0SMauro Carvalho Chehab 	if (stat < FEC_LOCK) {
65428f3741e0SMauro Carvalho Chehab 		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65438f3741e0SMauro Carvalho Chehab 		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65448f3741e0SMauro Carvalho Chehab 		c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65458f3741e0SMauro Carvalho Chehab 		c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65468f3741e0SMauro Carvalho Chehab 		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65478f3741e0SMauro Carvalho Chehab 		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65488f3741e0SMauro Carvalho Chehab 		return 0;
65498f3741e0SMauro Carvalho Chehab 	}
65508f3741e0SMauro Carvalho Chehab 
65518f3741e0SMauro Carvalho Chehab 	/* Get post BER */
65528f3741e0SMauro Carvalho Chehab 
65538f3741e0SMauro Carvalho Chehab 	/* BER measurement is valid if at least FEC lock is achieved */
65548f3741e0SMauro Carvalho Chehab 
6555ab5060cdSMauro Carvalho Chehab 	/*
6556ab5060cdSMauro Carvalho Chehab 	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6557ab5060cdSMauro Carvalho Chehab 	 * written to set nr of symbols or bits over which to measure
6558ab5060cdSMauro Carvalho Chehab 	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6559ab5060cdSMauro Carvalho Chehab 	 */
65608f3741e0SMauro Carvalho Chehab 
65618f3741e0SMauro Carvalho Chehab 	/* Read registers for post/preViterbi BER calculation */
65628f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
65638f3741e0SMauro Carvalho Chehab 	if (status < 0)
65648f3741e0SMauro Carvalho Chehab 		goto error;
65658f3741e0SMauro Carvalho Chehab 	pre_bit_err_count = reg16;
65668f3741e0SMauro Carvalho Chehab 
65678f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
65688f3741e0SMauro Carvalho Chehab 	if (status < 0)
65698f3741e0SMauro Carvalho Chehab 		goto error;
65708f3741e0SMauro Carvalho Chehab 	pre_bit_count = reg16;
65718f3741e0SMauro Carvalho Chehab 
65728f3741e0SMauro Carvalho Chehab 	/* Number of bit-errors */
65738f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
65748f3741e0SMauro Carvalho Chehab 	if (status < 0)
65758f3741e0SMauro Carvalho Chehab 		goto error;
65768f3741e0SMauro Carvalho Chehab 	post_bit_err_count = reg16;
65778f3741e0SMauro Carvalho Chehab 
65788f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
65798f3741e0SMauro Carvalho Chehab 	if (status < 0)
65808f3741e0SMauro Carvalho Chehab 		goto error;
65818f3741e0SMauro Carvalho Chehab 	post_bit_error_scale = reg16;
65828f3741e0SMauro Carvalho Chehab 
65838f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
65848f3741e0SMauro Carvalho Chehab 	if (status < 0)
65858f3741e0SMauro Carvalho Chehab 		goto error;
65868f3741e0SMauro Carvalho Chehab 	pkt_count = reg16;
65878f3741e0SMauro Carvalho Chehab 
65888f3741e0SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
65898f3741e0SMauro Carvalho Chehab 	if (status < 0)
65908f3741e0SMauro Carvalho Chehab 		goto error;
65918f3741e0SMauro Carvalho Chehab 	pkt_error_count = reg16;
65928f3741e0SMauro Carvalho Chehab 	write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
65938f3741e0SMauro Carvalho Chehab 
65948f3741e0SMauro Carvalho Chehab 	post_bit_err_count *= post_bit_error_scale;
65958f3741e0SMauro Carvalho Chehab 
65968f3741e0SMauro Carvalho Chehab 	post_bit_count = pkt_count * 204 * 8;
65978f3741e0SMauro Carvalho Chehab 
65988f3741e0SMauro Carvalho Chehab 	/* Store the results */
65998f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
66008f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].uvalue += pkt_error_count;
66018f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].scale = FE_SCALE_COUNTER;
66028f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].uvalue += pkt_count;
66038f3741e0SMauro Carvalho Chehab 
66048f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66058f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
66068f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66078f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].uvalue += pre_bit_count;
66088f3741e0SMauro Carvalho Chehab 
66098f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66108f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].uvalue += post_bit_err_count;
66118f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66128f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].uvalue += post_bit_count;
66138f3741e0SMauro Carvalho Chehab 
66148f3741e0SMauro Carvalho Chehab error:
66158f3741e0SMauro Carvalho Chehab 	return status;
66168f3741e0SMauro Carvalho Chehab }
66178f3741e0SMauro Carvalho Chehab 
66188f3741e0SMauro Carvalho Chehab 
66190df289a2SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status)
66208f3741e0SMauro Carvalho Chehab {
66218f3741e0SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66228f3741e0SMauro Carvalho Chehab 	int rc;
66238f3741e0SMauro Carvalho Chehab 
66248f3741e0SMauro Carvalho Chehab 	dprintk(1, "\n");
66258f3741e0SMauro Carvalho Chehab 
66268f3741e0SMauro Carvalho Chehab 	rc = drxk_get_stats(fe);
66278f3741e0SMauro Carvalho Chehab 	if (rc < 0)
66288f3741e0SMauro Carvalho Chehab 		return rc;
66298f3741e0SMauro Carvalho Chehab 
66308f3741e0SMauro Carvalho Chehab 	*status = state->fe_status;
66318f3741e0SMauro Carvalho Chehab 
66329a0bf528SMauro Carvalho Chehab 	return 0;
66339a0bf528SMauro Carvalho Chehab }
66349a0bf528SMauro Carvalho Chehab 
66359a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
66369a0bf528SMauro Carvalho Chehab 				     u16 *strength)
66379a0bf528SMauro Carvalho Chehab {
66389a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
6639340e7696SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
66409a0bf528SMauro Carvalho Chehab 
66419a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66429a0bf528SMauro Carvalho Chehab 
6643cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66449a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6645cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66469a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66479a0bf528SMauro Carvalho Chehab 
6648340e7696SMauro Carvalho Chehab 	*strength = c->strength.stat[0].uvalue;
66499a0bf528SMauro Carvalho Chehab 	return 0;
66509a0bf528SMauro Carvalho Chehab }
66519a0bf528SMauro Carvalho Chehab 
66529a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
66539a0bf528SMauro Carvalho Chehab {
66549a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66559a0bf528SMauro Carvalho Chehab 	s32 snr2;
66569a0bf528SMauro Carvalho Chehab 
66579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66589a0bf528SMauro Carvalho Chehab 
6659cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66609a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6661cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66629a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66639a0bf528SMauro Carvalho Chehab 
6664cd7a67a4SMauro Carvalho Chehab 	get_signal_to_noise(state, &snr2);
66658f3741e0SMauro Carvalho Chehab 
66668f3741e0SMauro Carvalho Chehab 	/* No negative SNR, clip to zero */
66678f3741e0SMauro Carvalho Chehab 	if (snr2 < 0)
66688f3741e0SMauro Carvalho Chehab 		snr2 = 0;
66699a0bf528SMauro Carvalho Chehab 	*snr = snr2 & 0xffff;
66709a0bf528SMauro Carvalho Chehab 	return 0;
66719a0bf528SMauro Carvalho Chehab }
66729a0bf528SMauro Carvalho Chehab 
66739a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
66749a0bf528SMauro Carvalho Chehab {
66759a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66769a0bf528SMauro Carvalho Chehab 	u16 err;
66779a0bf528SMauro Carvalho Chehab 
66789a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66799a0bf528SMauro Carvalho Chehab 
6680cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66819a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6682cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66839a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66849a0bf528SMauro Carvalho Chehab 
6685cd7a67a4SMauro Carvalho Chehab 	dvbtqam_get_acc_pkt_err(state, &err);
66869a0bf528SMauro Carvalho Chehab 	*ucblocks = (u32) err;
66879a0bf528SMauro Carvalho Chehab 	return 0;
66889a0bf528SMauro Carvalho Chehab }
66899a0bf528SMauro Carvalho Chehab 
6690ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe,
6691ab5060cdSMauro Carvalho Chehab 				  struct dvb_frontend_tune_settings *sets)
66929a0bf528SMauro Carvalho Chehab {
66939a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66949a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
66959a0bf528SMauro Carvalho Chehab 
66969a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66979a0bf528SMauro Carvalho Chehab 
6698cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66999a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6700cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
67019a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
67029a0bf528SMauro Carvalho Chehab 
67039a0bf528SMauro Carvalho Chehab 	switch (p->delivery_system) {
67049a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_A:
67059a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_C:
67069a0bf528SMauro Carvalho Chehab 	case SYS_DVBT:
67079a0bf528SMauro Carvalho Chehab 		sets->min_delay_ms = 3000;
67089a0bf528SMauro Carvalho Chehab 		sets->max_drift = 0;
67099a0bf528SMauro Carvalho Chehab 		sets->step_size = 0;
67109a0bf528SMauro Carvalho Chehab 		return 0;
67119a0bf528SMauro Carvalho Chehab 	default:
67129a0bf528SMauro Carvalho Chehab 		return -EINVAL;
67139a0bf528SMauro Carvalho Chehab 	}
67149a0bf528SMauro Carvalho Chehab }
67159a0bf528SMauro Carvalho Chehab 
6716bd336e63SMax Kellermann static const struct dvb_frontend_ops drxk_ops = {
67179a0bf528SMauro Carvalho Chehab 	/* .delsys will be filled dynamically */
67189a0bf528SMauro Carvalho Chehab 	.info = {
67199a0bf528SMauro Carvalho Chehab 		.name = "DRXK",
6720f1b1eabfSMauro Carvalho Chehab 		.frequency_min_hz =  47 * MHz,
6721f1b1eabfSMauro Carvalho Chehab 		.frequency_max_hz = 865 * MHz,
67229a0bf528SMauro Carvalho Chehab 		 /* For DVB-C */
67239a0bf528SMauro Carvalho Chehab 		.symbol_rate_min =   870000,
67249a0bf528SMauro Carvalho Chehab 		.symbol_rate_max = 11700000,
67259a0bf528SMauro Carvalho Chehab 		/* For DVB-T */
6726f1b1eabfSMauro Carvalho Chehab 		.frequency_stepsize_hz = 166667,
67279a0bf528SMauro Carvalho Chehab 
67289a0bf528SMauro Carvalho Chehab 		.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
67299a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
67309a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
67319a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
67329a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
67339a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
67349a0bf528SMauro Carvalho Chehab 	},
67359a0bf528SMauro Carvalho Chehab 
67369a0bf528SMauro Carvalho Chehab 	.release = drxk_release,
67379a0bf528SMauro Carvalho Chehab 	.sleep = drxk_sleep,
67389a0bf528SMauro Carvalho Chehab 	.i2c_gate_ctrl = drxk_gate_ctrl,
67399a0bf528SMauro Carvalho Chehab 
67409a0bf528SMauro Carvalho Chehab 	.set_frontend = drxk_set_parameters,
67419a0bf528SMauro Carvalho Chehab 	.get_tune_settings = drxk_get_tune_settings,
67429a0bf528SMauro Carvalho Chehab 
67439a0bf528SMauro Carvalho Chehab 	.read_status = drxk_read_status,
67449a0bf528SMauro Carvalho Chehab 	.read_signal_strength = drxk_read_signal_strength,
67459a0bf528SMauro Carvalho Chehab 	.read_snr = drxk_read_snr,
67469a0bf528SMauro Carvalho Chehab 	.read_ucblocks = drxk_read_ucblocks,
67479a0bf528SMauro Carvalho Chehab };
67489a0bf528SMauro Carvalho Chehab 
67499a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
67509a0bf528SMauro Carvalho Chehab 				 struct i2c_adapter *i2c)
67519a0bf528SMauro Carvalho Chehab {
67528f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *p;
67539a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = NULL;
67549a0bf528SMauro Carvalho Chehab 	u8 adr = config->adr;
67559a0bf528SMauro Carvalho Chehab 	int status;
67569a0bf528SMauro Carvalho Chehab 
67579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67589a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
67599a0bf528SMauro Carvalho Chehab 	if (!state)
67609a0bf528SMauro Carvalho Chehab 		return NULL;
67619a0bf528SMauro Carvalho Chehab 
67629a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
67639a0bf528SMauro Carvalho Chehab 	state->demod_address = adr;
67649a0bf528SMauro Carvalho Chehab 	state->single_master = config->single_master;
67659a0bf528SMauro Carvalho Chehab 	state->microcode_name = config->microcode_name;
67669a0bf528SMauro Carvalho Chehab 	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
67679a0bf528SMauro Carvalho Chehab 	state->no_i2c_bridge = config->no_i2c_bridge;
67689a0bf528SMauro Carvalho Chehab 	state->antenna_gpio = config->antenna_gpio;
67699a0bf528SMauro Carvalho Chehab 	state->antenna_dvbt = config->antenna_dvbt;
6770cd7a67a4SMauro Carvalho Chehab 	state->m_chunk_size = config->chunk_size;
67719a0bf528SMauro Carvalho Chehab 	state->enable_merr_cfg = config->enable_merr_cfg;
67729a0bf528SMauro Carvalho Chehab 
67739a0bf528SMauro Carvalho Chehab 	if (config->dynamic_clk) {
67745a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = false;
67755a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = false;
67769a0bf528SMauro Carvalho Chehab 	} else {
67775a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = true;
67785a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = true;
67799a0bf528SMauro Carvalho Chehab 	}
67809a0bf528SMauro Carvalho Chehab 
67819a0bf528SMauro Carvalho Chehab 
67829a0bf528SMauro Carvalho Chehab 	if (config->mpeg_out_clk_strength)
6783cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
67849a0bf528SMauro Carvalho Chehab 	else
6785cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = 0x06;
67869a0bf528SMauro Carvalho Chehab 
67879a0bf528SMauro Carvalho Chehab 	if (config->parallel_ts)
6788cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = true;
67899a0bf528SMauro Carvalho Chehab 	else
6790cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = false;
67919a0bf528SMauro Carvalho Chehab 
67929a0bf528SMauro Carvalho Chehab 	/* NOTE: as more UIO bits will be used, add them to the mask */
6793cd7a67a4SMauro Carvalho Chehab 	state->uio_mask = config->antenna_gpio;
67949a0bf528SMauro Carvalho Chehab 
67959a0bf528SMauro Carvalho Chehab 	/* Default gpio to DVB-C */
67969a0bf528SMauro Carvalho Chehab 	if (!state->antenna_dvbt && state->antenna_gpio)
6797cd7a67a4SMauro Carvalho Chehab 		state->m_gpio |= state->antenna_gpio;
67989a0bf528SMauro Carvalho Chehab 	else
6799cd7a67a4SMauro Carvalho Chehab 		state->m_gpio &= ~state->antenna_gpio;
68009a0bf528SMauro Carvalho Chehab 
68019a0bf528SMauro Carvalho Chehab 	mutex_init(&state->mutex);
68029a0bf528SMauro Carvalho Chehab 
68039a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
68049a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
68059a0bf528SMauro Carvalho Chehab 
68069a0bf528SMauro Carvalho Chehab 	init_state(state);
68079a0bf528SMauro Carvalho Chehab 
68089a0bf528SMauro Carvalho Chehab 	/* Load firmware and initialize DRX-K */
68099a0bf528SMauro Carvalho Chehab 	if (state->microcode_name) {
68108e30783bSMauro Carvalho Chehab 		const struct firmware *fw = NULL;
68118e30783bSMauro Carvalho Chehab 
68128e30783bSMauro Carvalho Chehab 		status = request_firmware(&fw, state->microcode_name,
68138e30783bSMauro Carvalho Chehab 					  state->i2c->dev.parent);
68148e30783bSMauro Carvalho Chehab 		if (status < 0)
68158e30783bSMauro Carvalho Chehab 			fw = NULL;
68168e30783bSMauro Carvalho Chehab 		load_firmware_cb(fw, state);
68179a0bf528SMauro Carvalho Chehab 	} else if (init_drxk(state) < 0)
68189a0bf528SMauro Carvalho Chehab 		goto error;
68199a0bf528SMauro Carvalho Chehab 
68208f3741e0SMauro Carvalho Chehab 
68218f3741e0SMauro Carvalho Chehab 	/* Initialize stats */
68228f3741e0SMauro Carvalho Chehab 	p = &state->frontend.dtv_property_cache;
68238f3741e0SMauro Carvalho Chehab 	p->strength.len = 1;
68248f3741e0SMauro Carvalho Chehab 	p->cnr.len = 1;
68258f3741e0SMauro Carvalho Chehab 	p->block_error.len = 1;
68268f3741e0SMauro Carvalho Chehab 	p->block_count.len = 1;
68278f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.len = 1;
68288f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.len = 1;
68298f3741e0SMauro Carvalho Chehab 	p->post_bit_error.len = 1;
68308f3741e0SMauro Carvalho Chehab 	p->post_bit_count.len = 1;
68318f3741e0SMauro Carvalho Chehab 
68328f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
68338f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68348f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68358f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68368f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68378f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68388f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68398f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68408f3741e0SMauro Carvalho Chehab 
68413a4398f5SMauro Carvalho Chehab 	pr_info("frontend initialized.\n");
68429a0bf528SMauro Carvalho Chehab 	return &state->frontend;
68439a0bf528SMauro Carvalho Chehab 
68449a0bf528SMauro Carvalho Chehab error:
68453a4398f5SMauro Carvalho Chehab 	pr_err("not found\n");
68469a0bf528SMauro Carvalho Chehab 	kfree(state);
68479a0bf528SMauro Carvalho Chehab 	return NULL;
68489a0bf528SMauro Carvalho Chehab }
68499a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach);
68509a0bf528SMauro Carvalho Chehab 
68519a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
68529a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
68539a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6854