19a0bf528SMauro Carvalho Chehab /*
29a0bf528SMauro Carvalho Chehab  * drxk_hard: DRX-K DVB-C/T demodulator driver
39a0bf528SMauro Carvalho Chehab  *
49a0bf528SMauro Carvalho Chehab  * Copyright (C) 2010-2011 Digital Devices GmbH
59a0bf528SMauro Carvalho Chehab  *
69a0bf528SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or
79a0bf528SMauro Carvalho Chehab  * modify it under the terms of the GNU General Public License
89a0bf528SMauro Carvalho Chehab  * version 2 only, as published by the Free Software Foundation.
99a0bf528SMauro Carvalho Chehab  *
109a0bf528SMauro Carvalho Chehab  *
119a0bf528SMauro Carvalho Chehab  * This program is distributed in the hope that it will be useful,
129a0bf528SMauro Carvalho Chehab  * but WITHOUT ANY WARRANTY; without even the implied warranty of
139a0bf528SMauro Carvalho Chehab  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149a0bf528SMauro Carvalho Chehab  * GNU General Public License for more details.
159a0bf528SMauro Carvalho Chehab  *
16bcb63314SSakari Ailus  * To obtain the license, point your browser to
17bcb63314SSakari Ailus  * http://www.gnu.org/copyleft/gpl.html
189a0bf528SMauro Carvalho Chehab  */
199a0bf528SMauro Carvalho Chehab 
203a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
213a4398f5SMauro Carvalho Chehab 
229a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
239a0bf528SMauro Carvalho Chehab #include <linux/module.h>
249a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
259a0bf528SMauro Carvalho Chehab #include <linux/init.h>
269a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
279a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
289a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
299a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
309a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
319a0bf528SMauro Carvalho Chehab 
329a0bf528SMauro Carvalho Chehab #include "dvb_frontend.h"
339a0bf528SMauro Carvalho Chehab #include "drxk.h"
349a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
35b5e9eb6fSMauro Carvalho Chehab #include "dvb_math.h"
369a0bf528SMauro Carvalho Chehab 
37cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
38cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state);
39cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
40cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
41cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
42cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode);
43cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
44cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset);
45cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
46cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode);
47cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state);
48cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
49cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset);
50cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
51cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
52cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state);
53cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state);
549a0bf528SMauro Carvalho Chehab 
55cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state)
569a0bf528SMauro Carvalho Chehab {
57cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_DVBT;
589a0bf528SMauro Carvalho Chehab }
599a0bf528SMauro Carvalho Chehab 
60cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state)
619a0bf528SMauro Carvalho Chehab {
62cd7a67a4SMauro Carvalho Chehab 	return state->m_operation_mode == OM_QAM_ITU_A ||
63cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_B ||
64cd7a67a4SMauro Carvalho Chehab 	    state->m_operation_mode == OM_QAM_ITU_C;
659a0bf528SMauro Carvalho Chehab }
669a0bf528SMauro Carvalho Chehab 
679a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
689a0bf528SMauro Carvalho Chehab 
699a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
709a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
719a0bf528SMauro Carvalho Chehab 
729a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83  165
739a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93  250
749a0bf528SMauro Carvalho Chehab 
759a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
769a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
779a0bf528SMauro Carvalho Chehab #endif
789a0bf528SMauro Carvalho Chehab 
799a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
809a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
819a0bf528SMauro Carvalho Chehab #endif
829a0bf528SMauro Carvalho Chehab 
839a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
849a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
859a0bf528SMauro Carvalho Chehab 
869a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
879a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV   4
889a0bf528SMauro Carvalho Chehab #endif
899a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
909a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV   6
919a0bf528SMauro Carvalho Chehab #endif
929a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
939a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV   7
949a0bf528SMauro Carvalho Chehab #endif
959a0bf528SMauro Carvalho Chehab 
969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
979a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM   3
989a0bf528SMauro Carvalho Chehab #endif
999a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
1009a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM   4
1019a0bf528SMauro Carvalho Chehab #endif
1029a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
1039a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM   7
1049a0bf528SMauro Carvalho Chehab #endif
1059a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
1069a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
1079a0bf528SMauro Carvalho Chehab #endif
1089a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
1099a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
1109a0bf528SMauro Carvalho Chehab #endif
1119a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1129a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
1139a0bf528SMauro Carvalho Chehab #endif
1149a0bf528SMauro Carvalho Chehab 
1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1169a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1179a0bf528SMauro Carvalho Chehab #endif
1189a0bf528SMauro Carvalho Chehab 
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1209a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab 
1239a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1249a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
1259a0bf528SMauro Carvalho Chehab #endif
1269a0bf528SMauro Carvalho Chehab 
1279a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1289a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
1299a0bf528SMauro Carvalho Chehab #endif
1309a0bf528SMauro Carvalho Chehab 
1319a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1329a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
1339a0bf528SMauro Carvalho Chehab #endif
1349a0bf528SMauro Carvalho Chehab 
1359a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
1369a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
1379a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
1389a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG      24
1399a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
1409a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
1419a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM      48
1429a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE        0
1439a0bf528SMauro Carvalho Chehab 
1449a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT                100
1459a0bf528SMauro Carvalho Chehab 
1469a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS      2
1479a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE     6
1489a0bf528SMauro Carvalho Chehab 
1499a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS      28
1509a0bf528SMauro Carvalho Chehab 
1519a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1529a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
1539a0bf528SMauro Carvalho Chehab #endif
1549a0bf528SMauro Carvalho Chehab 
1559a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
1569a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
1579a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
1589a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
1599a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
1609a0bf528SMauro Carvalho Chehab 
1619a0bf528SMauro Carvalho Chehab static unsigned int debug;
1629a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1639a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1649a0bf528SMauro Carvalho Chehab 
1659a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do {				\
1669a0bf528SMauro Carvalho Chehab if (debug >= level)							\
16752ee29feSMauro Carvalho Chehab 	printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg);	\
1689a0bf528SMauro Carvalho Chehab } while (0)
1699a0bf528SMauro Carvalho Chehab 
1709a0bf528SMauro Carvalho Chehab 
1719a0bf528SMauro Carvalho Chehab static inline u32 MulDiv32(u32 a, u32 b, u32 c)
1729a0bf528SMauro Carvalho Chehab {
1739a0bf528SMauro Carvalho Chehab 	u64 tmp64;
1749a0bf528SMauro Carvalho Chehab 
1759a0bf528SMauro Carvalho Chehab 	tmp64 = (u64) a * (u64) b;
1769a0bf528SMauro Carvalho Chehab 	do_div(tmp64, c);
1779a0bf528SMauro Carvalho Chehab 
1789a0bf528SMauro Carvalho Chehab 	return (u32) tmp64;
1799a0bf528SMauro Carvalho Chehab }
1809a0bf528SMauro Carvalho Chehab 
181ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c)
1829a0bf528SMauro Carvalho Chehab {
1839a0bf528SMauro Carvalho Chehab 	int i = 0;
1849a0bf528SMauro Carvalho Chehab 	u32 Q1 = 0;
1859a0bf528SMauro Carvalho Chehab 	u32 R0 = 0;
1869a0bf528SMauro Carvalho Chehab 
1879a0bf528SMauro Carvalho Chehab 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
188ab5060cdSMauro Carvalho Chehab 	Q1 = a / c;		/*
189ab5060cdSMauro Carvalho Chehab 				 * integer part, only the 4 least significant
190ab5060cdSMauro Carvalho Chehab 				 * bits will be visible in the result
191ab5060cdSMauro Carvalho Chehab 				 */
1929a0bf528SMauro Carvalho Chehab 
1939a0bf528SMauro Carvalho Chehab 	/* division using radix 16, 7 nibbles in the result */
1949a0bf528SMauro Carvalho Chehab 	for (i = 0; i < 7; i++) {
1959a0bf528SMauro Carvalho Chehab 		Q1 = (Q1 << 4) | (R0 / c);
1969a0bf528SMauro Carvalho Chehab 		R0 = (R0 % c) << 4;
1979a0bf528SMauro Carvalho Chehab 	}
1989a0bf528SMauro Carvalho Chehab 	/* rounding */
1999a0bf528SMauro Carvalho Chehab 	if ((R0 >> 3) >= c)
2009a0bf528SMauro Carvalho Chehab 		Q1++;
2019a0bf528SMauro Carvalho Chehab 
2029a0bf528SMauro Carvalho Chehab 	return Q1;
2039a0bf528SMauro Carvalho Chehab }
2049a0bf528SMauro Carvalho Chehab 
205b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value)
2069a0bf528SMauro Carvalho Chehab {
207b5e9eb6fSMauro Carvalho Chehab 	return (100L * intlog10(value)) >> 24;
2089a0bf528SMauro Carvalho Chehab }
2099a0bf528SMauro Carvalho Chehab 
21034eb9751SMauro Carvalho Chehab /***************************************************************************/
2119a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
21234eb9751SMauro Carvalho Chehab /***************************************************************************/
2139a0bf528SMauro Carvalho Chehab 
2149a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
2159a0bf528SMauro Carvalho Chehab {
2169a0bf528SMauro Carvalho Chehab 	i2c_lock_adapter(state->i2c);
2179a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = true;
2189a0bf528SMauro Carvalho Chehab 
2199a0bf528SMauro Carvalho Chehab 	return 0;
2209a0bf528SMauro Carvalho Chehab }
2219a0bf528SMauro Carvalho Chehab 
2229a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
2239a0bf528SMauro Carvalho Chehab {
2249a0bf528SMauro Carvalho Chehab 	if (!state->drxk_i2c_exclusive_lock)
2259a0bf528SMauro Carvalho Chehab 		return;
2269a0bf528SMauro Carvalho Chehab 
2279a0bf528SMauro Carvalho Chehab 	i2c_unlock_adapter(state->i2c);
2289a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = false;
2299a0bf528SMauro Carvalho Chehab }
2309a0bf528SMauro Carvalho Chehab 
2319a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
2329a0bf528SMauro Carvalho Chehab 			     unsigned len)
2339a0bf528SMauro Carvalho Chehab {
2349a0bf528SMauro Carvalho Chehab 	if (state->drxk_i2c_exclusive_lock)
2359a0bf528SMauro Carvalho Chehab 		return __i2c_transfer(state->i2c, msgs, len);
2369a0bf528SMauro Carvalho Chehab 	else
2379a0bf528SMauro Carvalho Chehab 		return i2c_transfer(state->i2c, msgs, len);
2389a0bf528SMauro Carvalho Chehab }
2399a0bf528SMauro Carvalho Chehab 
2409a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
2419a0bf528SMauro Carvalho Chehab {
2429a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
2439a0bf528SMauro Carvalho Chehab 				    .buf = val, .len = 1}
2449a0bf528SMauro Carvalho Chehab 	};
2459a0bf528SMauro Carvalho Chehab 
2469a0bf528SMauro Carvalho Chehab 	return drxk_i2c_transfer(state, msgs, 1);
2479a0bf528SMauro Carvalho Chehab }
2489a0bf528SMauro Carvalho Chehab 
2499a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
2509a0bf528SMauro Carvalho Chehab {
2519a0bf528SMauro Carvalho Chehab 	int status;
2529a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg = {
2539a0bf528SMauro Carvalho Chehab 	    .addr = adr, .flags = 0, .buf = data, .len = len };
2549a0bf528SMauro Carvalho Chehab 
2559a0bf528SMauro Carvalho Chehab 	dprintk(3, ":");
2569a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2579a0bf528SMauro Carvalho Chehab 		int i;
2589a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
2590fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", data[i]);
2600fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
2619a0bf528SMauro Carvalho Chehab 	}
2629a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, &msg, 1);
2639a0bf528SMauro Carvalho Chehab 	if (status >= 0 && status != 1)
2649a0bf528SMauro Carvalho Chehab 		status = -EIO;
2659a0bf528SMauro Carvalho Chehab 
2669a0bf528SMauro Carvalho Chehab 	if (status < 0)
2673a4398f5SMauro Carvalho Chehab 		pr_err("i2c write error at addr 0x%02x\n", adr);
2689a0bf528SMauro Carvalho Chehab 
2699a0bf528SMauro Carvalho Chehab 	return status;
2709a0bf528SMauro Carvalho Chehab }
2719a0bf528SMauro Carvalho Chehab 
2729a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
2739a0bf528SMauro Carvalho Chehab 		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
2749a0bf528SMauro Carvalho Chehab {
2759a0bf528SMauro Carvalho Chehab 	int status;
2769a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[2] = {
2779a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = 0,
2789a0bf528SMauro Carvalho Chehab 				    .buf = msg, .len = len},
2799a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = I2C_M_RD,
2809a0bf528SMauro Carvalho Chehab 		 .buf = answ, .len = alen}
2819a0bf528SMauro Carvalho Chehab 	};
2829a0bf528SMauro Carvalho Chehab 
2839a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, msgs, 2);
2849a0bf528SMauro Carvalho Chehab 	if (status != 2) {
2859a0bf528SMauro Carvalho Chehab 		if (debug > 2)
2860fb220f2SMauro Carvalho Chehab 			pr_cont(": ERROR!\n");
2879a0bf528SMauro Carvalho Chehab 		if (status >= 0)
2889a0bf528SMauro Carvalho Chehab 			status = -EIO;
2899a0bf528SMauro Carvalho Chehab 
2903a4398f5SMauro Carvalho Chehab 		pr_err("i2c read error at addr 0x%02x\n", adr);
2919a0bf528SMauro Carvalho Chehab 		return status;
2929a0bf528SMauro Carvalho Chehab 	}
2939a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
2949a0bf528SMauro Carvalho Chehab 		int i;
2959a0bf528SMauro Carvalho Chehab 		dprintk(2, ": read from");
2969a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
2970fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", msg[i]);
2980fb220f2SMauro Carvalho Chehab 		pr_cont(", value = ");
2999a0bf528SMauro Carvalho Chehab 		for (i = 0; i < alen; i++)
3000fb220f2SMauro Carvalho Chehab 			pr_cont(" %02x", answ[i]);
3010fb220f2SMauro Carvalho Chehab 		pr_cont("\n");
3029a0bf528SMauro Carvalho Chehab 	}
3039a0bf528SMauro Carvalho Chehab 	return 0;
3049a0bf528SMauro Carvalho Chehab }
3059a0bf528SMauro Carvalho Chehab 
3069a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
3079a0bf528SMauro Carvalho Chehab {
3089a0bf528SMauro Carvalho Chehab 	int status;
3099a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[2], len;
3109a0bf528SMauro Carvalho Chehab 
3119a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3129a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3139a0bf528SMauro Carvalho Chehab 
3149a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3159a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3169a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3179a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3189a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3199a0bf528SMauro Carvalho Chehab 		len = 4;
3209a0bf528SMauro Carvalho Chehab 	} else {
3219a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3229a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3239a0bf528SMauro Carvalho Chehab 		len = 2;
3249a0bf528SMauro Carvalho Chehab 	}
3259a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3269a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 2);
3279a0bf528SMauro Carvalho Chehab 	if (status < 0)
3289a0bf528SMauro Carvalho Chehab 		return status;
3299a0bf528SMauro Carvalho Chehab 	if (data)
3309a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8);
3319a0bf528SMauro Carvalho Chehab 
3329a0bf528SMauro Carvalho Chehab 	return 0;
3339a0bf528SMauro Carvalho Chehab }
3349a0bf528SMauro Carvalho Chehab 
3359a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
3369a0bf528SMauro Carvalho Chehab {
3379a0bf528SMauro Carvalho Chehab 	return read16_flags(state, reg, data, 0);
3389a0bf528SMauro Carvalho Chehab }
3399a0bf528SMauro Carvalho Chehab 
3409a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
3419a0bf528SMauro Carvalho Chehab {
3429a0bf528SMauro Carvalho Chehab 	int status;
3439a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[4], len;
3449a0bf528SMauro Carvalho Chehab 
3459a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3469a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3479a0bf528SMauro Carvalho Chehab 
3489a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3499a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3509a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
3519a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
3529a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
3539a0bf528SMauro Carvalho Chehab 		len = 4;
3549a0bf528SMauro Carvalho Chehab 	} else {
3559a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
3569a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3579a0bf528SMauro Carvalho Chehab 		len = 2;
3589a0bf528SMauro Carvalho Chehab 	}
3599a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3609a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 4);
3619a0bf528SMauro Carvalho Chehab 	if (status < 0)
3629a0bf528SMauro Carvalho Chehab 		return status;
3639a0bf528SMauro Carvalho Chehab 	if (data)
3649a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8) |
3659a0bf528SMauro Carvalho Chehab 		    (mm2[2] << 16) | (mm2[3] << 24);
3669a0bf528SMauro Carvalho Chehab 
3679a0bf528SMauro Carvalho Chehab 	return 0;
3689a0bf528SMauro Carvalho Chehab }
3699a0bf528SMauro Carvalho Chehab 
3709a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
3719a0bf528SMauro Carvalho Chehab {
3729a0bf528SMauro Carvalho Chehab 	return read32_flags(state, reg, data, 0);
3739a0bf528SMauro Carvalho Chehab }
3749a0bf528SMauro Carvalho Chehab 
3759a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
3769a0bf528SMauro Carvalho Chehab {
3779a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[6], len;
3789a0bf528SMauro Carvalho Chehab 
3799a0bf528SMauro Carvalho Chehab 	if (state->single_master)
3809a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
3819a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3829a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
3839a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
3849a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
3859a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
3869a0bf528SMauro Carvalho Chehab 		len = 4;
3879a0bf528SMauro Carvalho Chehab 	} else {
3889a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
3899a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3909a0bf528SMauro Carvalho Chehab 		len = 2;
3919a0bf528SMauro Carvalho Chehab 	}
3929a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
3939a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
3949a0bf528SMauro Carvalho Chehab 
3959a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
3969a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 2);
3979a0bf528SMauro Carvalho Chehab }
3989a0bf528SMauro Carvalho Chehab 
3999a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
4009a0bf528SMauro Carvalho Chehab {
4019a0bf528SMauro Carvalho Chehab 	return write16_flags(state, reg, data, 0);
4029a0bf528SMauro Carvalho Chehab }
4039a0bf528SMauro Carvalho Chehab 
4049a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
4059a0bf528SMauro Carvalho Chehab {
4069a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[8], len;
4079a0bf528SMauro Carvalho Chehab 
4089a0bf528SMauro Carvalho Chehab 	if (state->single_master)
4099a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
4109a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
4119a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
4129a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
4139a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
4149a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
4159a0bf528SMauro Carvalho Chehab 		len = 4;
4169a0bf528SMauro Carvalho Chehab 	} else {
4179a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
4189a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
4199a0bf528SMauro Carvalho Chehab 		len = 2;
4209a0bf528SMauro Carvalho Chehab 	}
4219a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
4229a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
4239a0bf528SMauro Carvalho Chehab 	mm[len + 2] = (data >> 16) & 0xff;
4249a0bf528SMauro Carvalho Chehab 	mm[len + 3] = (data >> 24) & 0xff;
4259a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
4269a0bf528SMauro Carvalho Chehab 
4279a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 4);
4289a0bf528SMauro Carvalho Chehab }
4299a0bf528SMauro Carvalho Chehab 
4309a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
4319a0bf528SMauro Carvalho Chehab {
4329a0bf528SMauro Carvalho Chehab 	return write32_flags(state, reg, data, 0);
4339a0bf528SMauro Carvalho Chehab }
4349a0bf528SMauro Carvalho Chehab 
435cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address,
436cd7a67a4SMauro Carvalho Chehab 		      const int block_size, const u8 p_block[])
4379a0bf528SMauro Carvalho Chehab {
438cd7a67a4SMauro Carvalho Chehab 	int status = 0, blk_size = block_size;
439cd7a67a4SMauro Carvalho Chehab 	u8 flags = 0;
4409a0bf528SMauro Carvalho Chehab 
4419a0bf528SMauro Carvalho Chehab 	if (state->single_master)
442cd7a67a4SMauro Carvalho Chehab 		flags |= 0xC0;
4439a0bf528SMauro Carvalho Chehab 
444cd7a67a4SMauro Carvalho Chehab 	while (blk_size > 0) {
445cd7a67a4SMauro Carvalho Chehab 		int chunk = blk_size > state->m_chunk_size ?
446cd7a67a4SMauro Carvalho Chehab 		    state->m_chunk_size : blk_size;
447cd7a67a4SMauro Carvalho Chehab 		u8 *adr_buf = &state->chunk[0];
448cd7a67a4SMauro Carvalho Chehab 		u32 adr_length = 0;
4499a0bf528SMauro Carvalho Chehab 
450cd7a67a4SMauro Carvalho Chehab 		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
451cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
452cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = ((address >> 16) & 0xFF);
453cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] = ((address >> 24) & 0xFF);
454cd7a67a4SMauro Carvalho Chehab 			adr_buf[3] = ((address >> 7) & 0xFF);
455cd7a67a4SMauro Carvalho Chehab 			adr_buf[2] |= flags;
456cd7a67a4SMauro Carvalho Chehab 			adr_length = 4;
457cd7a67a4SMauro Carvalho Chehab 			if (chunk == state->m_chunk_size)
458cd7a67a4SMauro Carvalho Chehab 				chunk -= 2;
4599a0bf528SMauro Carvalho Chehab 		} else {
460cd7a67a4SMauro Carvalho Chehab 			adr_buf[0] = ((address << 1) & 0xFF);
461cd7a67a4SMauro Carvalho Chehab 			adr_buf[1] = (((address >> 16) & 0x0F) |
462cd7a67a4SMauro Carvalho Chehab 				     ((address >> 18) & 0xF0));
463cd7a67a4SMauro Carvalho Chehab 			adr_length = 2;
4649a0bf528SMauro Carvalho Chehab 		}
465cd7a67a4SMauro Carvalho Chehab 		memcpy(&state->chunk[adr_length], p_block, chunk);
466cd7a67a4SMauro Carvalho Chehab 		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
4679a0bf528SMauro Carvalho Chehab 		if (debug > 1) {
4689a0bf528SMauro Carvalho Chehab 			int i;
469cd7a67a4SMauro Carvalho Chehab 			if (p_block)
470cd7a67a4SMauro Carvalho Chehab 				for (i = 0; i < chunk; i++)
4710fb220f2SMauro Carvalho Chehab 					pr_cont(" %02x", p_block[i]);
4720fb220f2SMauro Carvalho Chehab 			pr_cont("\n");
4739a0bf528SMauro Carvalho Chehab 		}
4749a0bf528SMauro Carvalho Chehab 		status = i2c_write(state, state->demod_address,
475cd7a67a4SMauro Carvalho Chehab 				   &state->chunk[0], chunk + adr_length);
4769a0bf528SMauro Carvalho Chehab 		if (status < 0) {
4773a4398f5SMauro Carvalho Chehab 			pr_err("%s: i2c write error at addr 0x%02x\n",
478cd7a67a4SMauro Carvalho Chehab 			       __func__, address);
4799a0bf528SMauro Carvalho Chehab 			break;
4809a0bf528SMauro Carvalho Chehab 		}
481cd7a67a4SMauro Carvalho Chehab 		p_block += chunk;
482cd7a67a4SMauro Carvalho Chehab 		address += (chunk >> 1);
483cd7a67a4SMauro Carvalho Chehab 		blk_size -= chunk;
4849a0bf528SMauro Carvalho Chehab 	}
4859a0bf528SMauro Carvalho Chehab 	return status;
4869a0bf528SMauro Carvalho Chehab }
4879a0bf528SMauro Carvalho Chehab 
4889a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
4899a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
4909a0bf528SMauro Carvalho Chehab #endif
4919a0bf528SMauro Carvalho Chehab 
492cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state)
4939a0bf528SMauro Carvalho Chehab {
4949a0bf528SMauro Carvalho Chehab 	int status;
4959a0bf528SMauro Carvalho Chehab 	u8 data = 0;
496cd7a67a4SMauro Carvalho Chehab 	u16 retry_count = 0;
4979a0bf528SMauro Carvalho Chehab 
4989a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4999a0bf528SMauro Carvalho Chehab 
5009a0bf528SMauro Carvalho Chehab 	status = i2c_read1(state, state->demod_address, &data);
5019a0bf528SMauro Carvalho Chehab 	if (status < 0) {
5029a0bf528SMauro Carvalho Chehab 		do {
5039a0bf528SMauro Carvalho Chehab 			data = 0;
5049a0bf528SMauro Carvalho Chehab 			status = i2c_write(state, state->demod_address,
5059a0bf528SMauro Carvalho Chehab 					   &data, 1);
506b72852baSMauro Carvalho Chehab 			usleep_range(10000, 11000);
507cd7a67a4SMauro Carvalho Chehab 			retry_count++;
5089a0bf528SMauro Carvalho Chehab 			if (status < 0)
5099a0bf528SMauro Carvalho Chehab 				continue;
5109a0bf528SMauro Carvalho Chehab 			status = i2c_read1(state, state->demod_address,
5119a0bf528SMauro Carvalho Chehab 					   &data);
5129a0bf528SMauro Carvalho Chehab 		} while (status < 0 &&
513cd7a67a4SMauro Carvalho Chehab 			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
514cd7a67a4SMauro Carvalho Chehab 		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
5159a0bf528SMauro Carvalho Chehab 			goto error;
5169a0bf528SMauro Carvalho Chehab 	}
5179a0bf528SMauro Carvalho Chehab 
5189a0bf528SMauro Carvalho Chehab 	/* Make sure all clk domains are active */
5199a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
5209a0bf528SMauro Carvalho Chehab 	if (status < 0)
5219a0bf528SMauro Carvalho Chehab 		goto error;
5229a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5239a0bf528SMauro Carvalho Chehab 	if (status < 0)
5249a0bf528SMauro Carvalho Chehab 		goto error;
5259a0bf528SMauro Carvalho Chehab 	/* Enable pll lock tests */
5269a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PLL_LOCK__A, 1);
5279a0bf528SMauro Carvalho Chehab 	if (status < 0)
5289a0bf528SMauro Carvalho Chehab 		goto error;
5299a0bf528SMauro Carvalho Chehab 
530cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_UP;
5319a0bf528SMauro Carvalho Chehab 
5329a0bf528SMauro Carvalho Chehab error:
5339a0bf528SMauro Carvalho Chehab 	if (status < 0)
5343a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
5359a0bf528SMauro Carvalho Chehab 
5369a0bf528SMauro Carvalho Chehab 	return status;
5379a0bf528SMauro Carvalho Chehab }
5389a0bf528SMauro Carvalho Chehab 
5399a0bf528SMauro Carvalho Chehab 
5409a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
5419a0bf528SMauro Carvalho Chehab {
5429a0bf528SMauro Carvalho Chehab 	/*
5435a13e40bSMauro Carvalho Chehab 	 * FIXME: most (all?) of the values below should be moved into
5449a0bf528SMauro Carvalho Chehab 	 * struct drxk_config, as they are probably board-specific
5459a0bf528SMauro Carvalho Chehab 	 */
546cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
547cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_output_level = 0;
548cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_min_level = 0;
549cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_max_level = 0x7FFF;
550cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_if_agc_speed = 3;
5519a0bf528SMauro Carvalho Chehab 
552cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
553cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_output_level = 0;
554cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_min_level = 0;
555cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
556cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_speed = 3;
557cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_top = 9500;
558cd7a67a4SMauro Carvalho Chehab 	u32 ul_vsb_rf_agc_cut_off_current = 4000;
5599a0bf528SMauro Carvalho Chehab 
560cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
561cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_output_level = 0;
562cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_min_level = 0;
563cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_max_level = 0;
564cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_if_agc_speed = 3;
5659a0bf528SMauro Carvalho Chehab 
566cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
567cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_output_level = 0;
568cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_min_level = 0;
569cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_max_level = 0;
570cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_top = 9500;
571cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_cut_off_current = 4000;
572cd7a67a4SMauro Carvalho Chehab 	u32 ul_atv_rf_agc_speed = 3;
5739a0bf528SMauro Carvalho Chehab 
5749a0bf528SMauro Carvalho Chehab 	u32 ulQual83 = DEFAULT_MER_83;
5759a0bf528SMauro Carvalho Chehab 	u32 ulQual93 = DEFAULT_MER_93;
5769a0bf528SMauro Carvalho Chehab 
577cd7a67a4SMauro Carvalho Chehab 	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
578cd7a67a4SMauro Carvalho Chehab 	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
5799a0bf528SMauro Carvalho Chehab 
5809a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
5819a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_mode output mode is drive always */
5829a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
583cd7a67a4SMauro Carvalho Chehab 	u32 ul_gpio_cfg = 0x0113;
584cd7a67a4SMauro Carvalho Chehab 	u32 ul_invert_ts_clock = 0;
585cd7a67a4SMauro Carvalho Chehab 	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
586cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbt_bitrate = 50000000;
587cd7a67a4SMauro Carvalho Chehab 	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
5889a0bf528SMauro Carvalho Chehab 
589cd7a67a4SMauro Carvalho Chehab 	u32 ul_insert_rs_byte = 0;
5909a0bf528SMauro Carvalho Chehab 
591cd7a67a4SMauro Carvalho Chehab 	u32 ul_rf_mirror = 1;
592cd7a67a4SMauro Carvalho Chehab 	u32 ul_power_down = 0;
5939a0bf528SMauro Carvalho Chehab 
5949a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5959a0bf528SMauro Carvalho Chehab 
596cd7a67a4SMauro Carvalho Chehab 	state->m_has_lna = false;
597cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbt = false;
598cd7a67a4SMauro Carvalho Chehab 	state->m_has_dvbc = false;
599cd7a67a4SMauro Carvalho Chehab 	state->m_has_atv = false;
600cd7a67a4SMauro Carvalho Chehab 	state->m_has_oob = false;
601cd7a67a4SMauro Carvalho Chehab 	state->m_has_audio = false;
6029a0bf528SMauro Carvalho Chehab 
603cd7a67a4SMauro Carvalho Chehab 	if (!state->m_chunk_size)
604cd7a67a4SMauro Carvalho Chehab 		state->m_chunk_size = 124;
6059a0bf528SMauro Carvalho Chehab 
606cd7a67a4SMauro Carvalho Chehab 	state->m_osc_clock_freq = 0;
607cd7a67a4SMauro Carvalho Chehab 	state->m_smart_ant_inverted = false;
608cd7a67a4SMauro Carvalho Chehab 	state->m_b_p_down_open_bridge = false;
6099a0bf528SMauro Carvalho Chehab 
6109a0bf528SMauro Carvalho Chehab 	/* real system clock frequency in kHz */
611cd7a67a4SMauro Carvalho Chehab 	state->m_sys_clock_freq = 151875;
6129a0bf528SMauro Carvalho Chehab 	/* Timing div, 250ns/Psys */
6139a0bf528SMauro Carvalho Chehab 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
614cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
6159a0bf528SMauro Carvalho Chehab 				   HI_I2C_DELAY) / 1000;
6169a0bf528SMauro Carvalho Chehab 	/* Clipping */
617cd7a67a4SMauro Carvalho Chehab 	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
618cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
619cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
6209a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
621cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
6229a0bf528SMauro Carvalho Chehab 
623cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = (ul_power_down != 0);
6249a0bf528SMauro Carvalho Chehab 
625cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_a3_patch_code = false;
6269a0bf528SMauro Carvalho Chehab 
6279a0bf528SMauro Carvalho Chehab 	/* Init AGC and PGA parameters */
6289a0bf528SMauro Carvalho Chehab 	/* VSB IF */
629949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
630949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
631949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
632949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
633949dd08dSMauro Carvalho Chehab 	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
634cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pga_cfg = 140;
6359a0bf528SMauro Carvalho Chehab 
6369a0bf528SMauro Carvalho Chehab 	/* VSB RF */
637949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
638949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
639949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
640949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
641949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
642949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
643949dd08dSMauro Carvalho Chehab 	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
644cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.reference = 0x07;
645cd7a67a4SMauro Carvalho Chehab 	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
6469a0bf528SMauro Carvalho Chehab 
6479a0bf528SMauro Carvalho Chehab 	state->m_Quality83percent = DEFAULT_MER_83;
6489a0bf528SMauro Carvalho Chehab 	state->m_Quality93percent = DEFAULT_MER_93;
6499a0bf528SMauro Carvalho Chehab 	if (ulQual93 <= 500 && ulQual83 < ulQual93) {
6509a0bf528SMauro Carvalho Chehab 		state->m_Quality83percent = ulQual83;
6519a0bf528SMauro Carvalho Chehab 		state->m_Quality93percent = ulQual93;
6529a0bf528SMauro Carvalho Chehab 	}
6539a0bf528SMauro Carvalho Chehab 
6549a0bf528SMauro Carvalho Chehab 	/* ATV IF */
655949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
656949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
657949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
658949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
659949dd08dSMauro Carvalho Chehab 	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
6609a0bf528SMauro Carvalho Chehab 
6619a0bf528SMauro Carvalho Chehab 	/* ATV RF */
662949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
663949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
664949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
665949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
666949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
667949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
668949dd08dSMauro Carvalho Chehab 	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
669cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.reference = 0x04;
670cd7a67a4SMauro Carvalho Chehab 	state->m_atv_pre_saw_cfg.use_pre_saw = true;
6719a0bf528SMauro Carvalho Chehab 
6729a0bf528SMauro Carvalho Chehab 
6739a0bf528SMauro Carvalho Chehab 	/* DVBT RF */
674cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
675cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.output_level = 0;
676cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
677cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
678cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.top = 0x2100;
679cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
680cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_rf_agc_cfg.speed = 1;
6819a0bf528SMauro Carvalho Chehab 
6829a0bf528SMauro Carvalho Chehab 
6839a0bf528SMauro Carvalho Chehab 	/* DVBT IF */
684cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
685cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.output_level = 0;
686cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.min_output_level = 0;
687cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
688cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.top = 13424;
689cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
690cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.speed = 3;
691cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
692cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
6939a0bf528SMauro Carvalho Chehab 	/* state->m_dvbtPgaCfg = 140; */
6949a0bf528SMauro Carvalho Chehab 
695cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.reference = 4;
696cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
6979a0bf528SMauro Carvalho Chehab 
6989a0bf528SMauro Carvalho Chehab 	/* QAM RF */
699cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
700cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.output_level = 0;
701cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.min_output_level = 6023;
702cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.max_output_level = 27000;
703cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.top = 0x2380;
704cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
705cd7a67a4SMauro Carvalho Chehab 	state->m_qam_rf_agc_cfg.speed = 3;
7069a0bf528SMauro Carvalho Chehab 
7079a0bf528SMauro Carvalho Chehab 	/* QAM IF */
708cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
709cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.output_level = 0;
710cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.min_output_level = 0;
711cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.max_output_level = 9000;
712cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.top = 0x0511;
713cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.cut_off_current = 0;
714cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.speed = 3;
715cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
716cd7a67a4SMauro Carvalho Chehab 	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
7179a0bf528SMauro Carvalho Chehab 
718cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pga_cfg = 140;
719cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.reference = 4;
720cd7a67a4SMauro Carvalho Chehab 	state->m_qam_pre_saw_cfg.use_pre_saw = false;
7219a0bf528SMauro Carvalho Chehab 
722cd7a67a4SMauro Carvalho Chehab 	state->m_operation_mode = OM_NONE;
723cd7a67a4SMauro Carvalho Chehab 	state->m_drxk_state = DRXK_UNINITIALIZED;
7249a0bf528SMauro Carvalho Chehab 
7259a0bf528SMauro Carvalho Chehab 	/* MPEG output configuration */
726cd7a67a4SMauro Carvalho Chehab 	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG ouput */
727cd7a67a4SMauro Carvalho Chehab 	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
728cd7a67a4SMauro Carvalho Chehab 	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
729cd7a67a4SMauro Carvalho Chehab 	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
730cd7a67a4SMauro Carvalho Chehab 	state->m_invert_str = false;	/* If TRUE; invert STR signals */
731cd7a67a4SMauro Carvalho Chehab 	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
732cd7a67a4SMauro Carvalho Chehab 	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
7339a0bf528SMauro Carvalho Chehab 
7349a0bf528SMauro Carvalho Chehab 	/* If TRUE; static MPEG clockrate will be used;
7359a0bf528SMauro Carvalho Chehab 	   otherwise clockrate will adapt to the bitrate of the TS */
7369a0bf528SMauro Carvalho Chehab 
737cd7a67a4SMauro Carvalho Chehab 	state->m_dvbt_bitrate = ul_dvbt_bitrate;
738cd7a67a4SMauro Carvalho Chehab 	state->m_dvbc_bitrate = ul_dvbc_bitrate;
7399a0bf528SMauro Carvalho Chehab 
740cd7a67a4SMauro Carvalho Chehab 	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
7419a0bf528SMauro Carvalho Chehab 
7429a0bf528SMauro Carvalho Chehab 	/* Maximum bitrate in b/s in case static clockrate is selected */
743cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_ts_static_bitrate = 19392658;
744cd7a67a4SMauro Carvalho Chehab 	state->m_disable_te_ihandling = false;
7459a0bf528SMauro Carvalho Chehab 
746cd7a67a4SMauro Carvalho Chehab 	if (ul_insert_rs_byte)
747cd7a67a4SMauro Carvalho Chehab 		state->m_insert_rs_byte = true;
7489a0bf528SMauro Carvalho Chehab 
749cd7a67a4SMauro Carvalho Chehab 	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
750cd7a67a4SMauro Carvalho Chehab 	if (ul_mpeg_lock_time_out < 10000)
751cd7a67a4SMauro Carvalho Chehab 		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
752cd7a67a4SMauro Carvalho Chehab 	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
753cd7a67a4SMauro Carvalho Chehab 	if (ul_demod_lock_time_out < 10000)
754cd7a67a4SMauro Carvalho Chehab 		state->m_demod_lock_time_out = ul_demod_lock_time_out;
7559a0bf528SMauro Carvalho Chehab 
7569a0bf528SMauro Carvalho Chehab 	/* QAM defaults */
757cd7a67a4SMauro Carvalho Chehab 	state->m_constellation = DRX_CONSTELLATION_AUTO;
758cd7a67a4SMauro Carvalho Chehab 	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
759cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
760cd7a67a4SMauro Carvalho Chehab 	state->m_fec_rs_prescale = 1;
7619a0bf528SMauro Carvalho Chehab 
762cd7a67a4SMauro Carvalho Chehab 	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
763cd7a67a4SMauro Carvalho Chehab 	state->m_agcfast_clip_ctrl_delay = 0;
7649a0bf528SMauro Carvalho Chehab 
765949dd08dSMauro Carvalho Chehab 	state->m_gpio_cfg = ul_gpio_cfg;
7669a0bf528SMauro Carvalho Chehab 
767cd7a67a4SMauro Carvalho Chehab 	state->m_b_power_down = false;
768cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = DRX_POWER_DOWN;
7699a0bf528SMauro Carvalho Chehab 
770cd7a67a4SMauro Carvalho Chehab 	state->m_rfmirror = (ul_rf_mirror == 0);
771cd7a67a4SMauro Carvalho Chehab 	state->m_if_agc_pol = false;
7729a0bf528SMauro Carvalho Chehab 	return 0;
7739a0bf528SMauro Carvalho Chehab }
7749a0bf528SMauro Carvalho Chehab 
775cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state)
7769a0bf528SMauro Carvalho Chehab {
7779a0bf528SMauro Carvalho Chehab 	int status = 0;
7789a0bf528SMauro Carvalho Chehab 	u32 jtag = 0;
7799a0bf528SMauro Carvalho Chehab 	u16 bid = 0;
7809a0bf528SMauro Carvalho Chehab 	u16 key = 0;
7819a0bf528SMauro Carvalho Chehab 
7829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
7839a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
784ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
785ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7869a0bf528SMauro Carvalho Chehab 	if (status < 0)
7879a0bf528SMauro Carvalho Chehab 		goto error;
7889a0bf528SMauro Carvalho Chehab 	/* Check device id */
7899a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_TOP_COMM_KEY__A, &key);
7909a0bf528SMauro Carvalho Chehab 	if (status < 0)
7919a0bf528SMauro Carvalho Chehab 		goto error;
7929a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7939a0bf528SMauro Carvalho Chehab 	if (status < 0)
7949a0bf528SMauro Carvalho Chehab 		goto error;
7959a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
7969a0bf528SMauro Carvalho Chehab 	if (status < 0)
7979a0bf528SMauro Carvalho Chehab 		goto error;
7989a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
7999a0bf528SMauro Carvalho Chehab 	if (status < 0)
8009a0bf528SMauro Carvalho Chehab 		goto error;
8019a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
8029a0bf528SMauro Carvalho Chehab error:
8039a0bf528SMauro Carvalho Chehab 	if (status < 0)
8043a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
8059a0bf528SMauro Carvalho Chehab 	return status;
8069a0bf528SMauro Carvalho Chehab }
8079a0bf528SMauro Carvalho Chehab 
808cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state)
8099a0bf528SMauro Carvalho Chehab {
810cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_ohw_cfg = 0;
811cd7a67a4SMauro Carvalho Chehab 	u32 sio_top_jtagid_lo = 0;
8129a0bf528SMauro Carvalho Chehab 	int status;
8139a0bf528SMauro Carvalho Chehab 	const char *spin = "";
8149a0bf528SMauro Carvalho Chehab 
8159a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
8169a0bf528SMauro Carvalho Chehab 
8179a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
8189a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
819ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
820ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
8219a0bf528SMauro Carvalho Chehab 	if (status < 0)
8229a0bf528SMauro Carvalho Chehab 		goto error;
8238418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
8249a0bf528SMauro Carvalho Chehab 	if (status < 0)
8259a0bf528SMauro Carvalho Chehab 		goto error;
826cd7a67a4SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
8279a0bf528SMauro Carvalho Chehab 	if (status < 0)
8289a0bf528SMauro Carvalho Chehab 		goto error;
8299a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
8309a0bf528SMauro Carvalho Chehab 	if (status < 0)
8319a0bf528SMauro Carvalho Chehab 		goto error;
8329a0bf528SMauro Carvalho Chehab 
833cd7a67a4SMauro Carvalho Chehab 	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
8349a0bf528SMauro Carvalho Chehab 	case 0:
8359a0bf528SMauro Carvalho Chehab 		/* ignore (bypass ?) */
8369a0bf528SMauro Carvalho Chehab 		break;
8379a0bf528SMauro Carvalho Chehab 	case 1:
8389a0bf528SMauro Carvalho Chehab 		/* 27 MHz */
839cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 27000;
8409a0bf528SMauro Carvalho Chehab 		break;
8419a0bf528SMauro Carvalho Chehab 	case 2:
8429a0bf528SMauro Carvalho Chehab 		/* 20.25 MHz */
843cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8449a0bf528SMauro Carvalho Chehab 		break;
8459a0bf528SMauro Carvalho Chehab 	case 3:
8469a0bf528SMauro Carvalho Chehab 		/* 4 MHz */
847cd7a67a4SMauro Carvalho Chehab 		state->m_osc_clock_freq = 20250;
8489a0bf528SMauro Carvalho Chehab 		break;
8499a0bf528SMauro Carvalho Chehab 	default:
8503a4398f5SMauro Carvalho Chehab 		pr_err("Clock Frequency is unknown\n");
8519a0bf528SMauro Carvalho Chehab 		return -EINVAL;
8529a0bf528SMauro Carvalho Chehab 	}
8539a0bf528SMauro Carvalho Chehab 	/*
8549a0bf528SMauro Carvalho Chehab 		Determine device capabilities
8559a0bf528SMauro Carvalho Chehab 		Based on pinning v14
8569a0bf528SMauro Carvalho Chehab 		*/
857cd7a67a4SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
8589a0bf528SMauro Carvalho Chehab 	if (status < 0)
8599a0bf528SMauro Carvalho Chehab 		goto error;
8609a0bf528SMauro Carvalho Chehab 
8613a4398f5SMauro Carvalho Chehab 	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
8629a0bf528SMauro Carvalho Chehab 
8639a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
864cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
8659a0bf528SMauro Carvalho Chehab 	case 0:
866cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A1;
8679a0bf528SMauro Carvalho Chehab 		spin = "A1";
8689a0bf528SMauro Carvalho Chehab 		break;
8699a0bf528SMauro Carvalho Chehab 	case 2:
870cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A2;
8719a0bf528SMauro Carvalho Chehab 		spin = "A2";
8729a0bf528SMauro Carvalho Chehab 		break;
8739a0bf528SMauro Carvalho Chehab 	case 3:
874cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_A3;
8759a0bf528SMauro Carvalho Chehab 		spin = "A3";
8769a0bf528SMauro Carvalho Chehab 		break;
8779a0bf528SMauro Carvalho Chehab 	default:
878cd7a67a4SMauro Carvalho Chehab 		state->m_device_spin = DRXK_SPIN_UNKNOWN;
8799a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
8803a4398f5SMauro Carvalho Chehab 		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
8819a0bf528SMauro Carvalho Chehab 		goto error2;
8829a0bf528SMauro Carvalho Chehab 	}
883cd7a67a4SMauro Carvalho Chehab 	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
8849a0bf528SMauro Carvalho Chehab 	case 0x13:
8859a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3913K_TYPE_ID */
886cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
887cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
888cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = false;
889cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
890cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
891cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
892cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
893cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = false;
894cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = false;
895cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
8969a0bf528SMauro Carvalho Chehab 		break;
8979a0bf528SMauro Carvalho Chehab 	case 0x15:
8989a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3915K_TYPE_ID */
899cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
900cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
901cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
902cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
903cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
904cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
905cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
906cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
907cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
908cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9099a0bf528SMauro Carvalho Chehab 		break;
9109a0bf528SMauro Carvalho Chehab 	case 0x16:
9119a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3916K_TYPE_ID */
912cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
913cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
914cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
915cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
916cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
917cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
918cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
919cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
920cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
921cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9229a0bf528SMauro Carvalho Chehab 		break;
9239a0bf528SMauro Carvalho Chehab 	case 0x18:
9249a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3918K_TYPE_ID */
925cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
926cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
927cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
928cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
929cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
930cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = false;
931cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
932cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
933cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
934cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9359a0bf528SMauro Carvalho Chehab 		break;
9369a0bf528SMauro Carvalho Chehab 	case 0x21:
9379a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3921K_TYPE_ID */
938cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
939cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
940cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
941cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
942cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
943cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
944cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
945cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
946cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
947cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9489a0bf528SMauro Carvalho Chehab 		break;
9499a0bf528SMauro Carvalho Chehab 	case 0x23:
9509a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3923K_TYPE_ID */
951cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
952cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
953cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
954cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
955cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
956cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
957cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
958cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
959cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
960cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9619a0bf528SMauro Carvalho Chehab 		break;
9629a0bf528SMauro Carvalho Chehab 	case 0x25:
9639a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3925K_TYPE_ID */
964cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
965cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
966cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
967cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = true;
968cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
969cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
970cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
971cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
972cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
973cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9749a0bf528SMauro Carvalho Chehab 		break;
9759a0bf528SMauro Carvalho Chehab 	case 0x26:
9769a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3926K_TYPE_ID */
977cd7a67a4SMauro Carvalho Chehab 		state->m_has_lna = false;
978cd7a67a4SMauro Carvalho Chehab 		state->m_has_oob = false;
979cd7a67a4SMauro Carvalho Chehab 		state->m_has_atv = true;
980cd7a67a4SMauro Carvalho Chehab 		state->m_has_audio = false;
981cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbt = true;
982cd7a67a4SMauro Carvalho Chehab 		state->m_has_dvbc = true;
983cd7a67a4SMauro Carvalho Chehab 		state->m_has_sawsw = true;
984cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio2 = true;
985cd7a67a4SMauro Carvalho Chehab 		state->m_has_gpio1 = true;
986cd7a67a4SMauro Carvalho Chehab 		state->m_has_irqn = false;
9879a0bf528SMauro Carvalho Chehab 		break;
9889a0bf528SMauro Carvalho Chehab 	default:
9893a4398f5SMauro Carvalho Chehab 		pr_err("DeviceID 0x%02x not supported\n",
990cd7a67a4SMauro Carvalho Chehab 			((sio_top_jtagid_lo >> 12) & 0xFF));
9919a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
9929a0bf528SMauro Carvalho Chehab 		goto error2;
9939a0bf528SMauro Carvalho Chehab 	}
9949a0bf528SMauro Carvalho Chehab 
9953a4398f5SMauro Carvalho Chehab 	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
996cd7a67a4SMauro Carvalho Chehab 	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
997cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq / 1000,
998cd7a67a4SMauro Carvalho Chehab 	       state->m_osc_clock_freq % 1000);
9999a0bf528SMauro Carvalho Chehab 
10009a0bf528SMauro Carvalho Chehab error:
10019a0bf528SMauro Carvalho Chehab 	if (status < 0)
10023a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10039a0bf528SMauro Carvalho Chehab 
10049a0bf528SMauro Carvalho Chehab error2:
10059a0bf528SMauro Carvalho Chehab 	return status;
10069a0bf528SMauro Carvalho Chehab }
10079a0bf528SMauro Carvalho Chehab 
1008cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
10099a0bf528SMauro Carvalho Chehab {
10109a0bf528SMauro Carvalho Chehab 	int status;
10119a0bf528SMauro Carvalho Chehab 	bool powerdown_cmd;
10129a0bf528SMauro Carvalho Chehab 
10139a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10149a0bf528SMauro Carvalho Chehab 
10159a0bf528SMauro Carvalho Chehab 	/* Write command */
10169a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
10179a0bf528SMauro Carvalho Chehab 	if (status < 0)
10189a0bf528SMauro Carvalho Chehab 		goto error;
10199a0bf528SMauro Carvalho Chehab 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1020b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
10219a0bf528SMauro Carvalho Chehab 
10229a0bf528SMauro Carvalho Chehab 	powerdown_cmd =
10239a0bf528SMauro Carvalho Chehab 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1024cd7a67a4SMauro Carvalho Chehab 		    ((state->m_hi_cfg_ctrl) &
10259a0bf528SMauro Carvalho Chehab 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
10269a0bf528SMauro Carvalho Chehab 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
10275a7f7b79SMauro Carvalho Chehab 	if (!powerdown_cmd) {
10289a0bf528SMauro Carvalho Chehab 		/* Wait until command rdy */
1029cd7a67a4SMauro Carvalho Chehab 		u32 retry_count = 0;
1030cd7a67a4SMauro Carvalho Chehab 		u16 wait_cmd;
10319a0bf528SMauro Carvalho Chehab 
10329a0bf528SMauro Carvalho Chehab 		do {
1033b72852baSMauro Carvalho Chehab 			usleep_range(1000, 2000);
1034cd7a67a4SMauro Carvalho Chehab 			retry_count += 1;
10359a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
1036cd7a67a4SMauro Carvalho Chehab 					  &wait_cmd);
1037cd7a67a4SMauro Carvalho Chehab 		} while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
1038cd7a67a4SMauro Carvalho Chehab 			 && (wait_cmd != 0));
10399a0bf528SMauro Carvalho Chehab 		if (status < 0)
10409a0bf528SMauro Carvalho Chehab 			goto error;
1041cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
10429a0bf528SMauro Carvalho Chehab 	}
10439a0bf528SMauro Carvalho Chehab error:
10449a0bf528SMauro Carvalho Chehab 	if (status < 0)
10453a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10469a0bf528SMauro Carvalho Chehab 
10479a0bf528SMauro Carvalho Chehab 	return status;
10489a0bf528SMauro Carvalho Chehab }
10499a0bf528SMauro Carvalho Chehab 
1050cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state)
10519a0bf528SMauro Carvalho Chehab {
10529a0bf528SMauro Carvalho Chehab 	int status;
10539a0bf528SMauro Carvalho Chehab 
10549a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10559a0bf528SMauro Carvalho Chehab 
10569a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
10579a0bf528SMauro Carvalho Chehab 
1058ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1059ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timeout);
10609a0bf528SMauro Carvalho Chehab 	if (status < 0)
10619a0bf528SMauro Carvalho Chehab 		goto error;
1062ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1063ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_ctrl);
10649a0bf528SMauro Carvalho Chehab 	if (status < 0)
10659a0bf528SMauro Carvalho Chehab 		goto error;
1066ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1067ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_wake_up_key);
10689a0bf528SMauro Carvalho Chehab 	if (status < 0)
10699a0bf528SMauro Carvalho Chehab 		goto error;
1070ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1071ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_bridge_delay);
10729a0bf528SMauro Carvalho Chehab 	if (status < 0)
10739a0bf528SMauro Carvalho Chehab 		goto error;
1074ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1075ab5060cdSMauro Carvalho Chehab 			 state->m_hi_cfg_timing_div);
10769a0bf528SMauro Carvalho Chehab 	if (status < 0)
10779a0bf528SMauro Carvalho Chehab 		goto error;
1078ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1079ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
10809a0bf528SMauro Carvalho Chehab 	if (status < 0)
10819a0bf528SMauro Carvalho Chehab 		goto error;
1082b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
10839a0bf528SMauro Carvalho Chehab 	if (status < 0)
10849a0bf528SMauro Carvalho Chehab 		goto error;
10859a0bf528SMauro Carvalho Chehab 
1086cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
10879a0bf528SMauro Carvalho Chehab error:
10889a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
10899a0bf528SMauro Carvalho Chehab 	if (status < 0)
10903a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
10919a0bf528SMauro Carvalho Chehab 	return status;
10929a0bf528SMauro Carvalho Chehab }
10939a0bf528SMauro Carvalho Chehab 
1094cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state)
10959a0bf528SMauro Carvalho Chehab {
10969a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
10979a0bf528SMauro Carvalho Chehab 
1098cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1099cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_timeout = 0x96FF;
11009a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
1101cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
11029a0bf528SMauro Carvalho Chehab 
1103cd7a67a4SMauro Carvalho Chehab 	return hi_cfg_command(state);
11049a0bf528SMauro Carvalho Chehab }
11059a0bf528SMauro Carvalho Chehab 
1106cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
11079a0bf528SMauro Carvalho Chehab {
11089a0bf528SMauro Carvalho Chehab 	int status = -1;
1109cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mclk_cfg = 0;
1110cd7a67a4SMauro Carvalho Chehab 	u16 sio_pdr_mdx_cfg = 0;
11119a0bf528SMauro Carvalho Chehab 	u16 err_cfg = 0;
11129a0bf528SMauro Carvalho Chehab 
11139a0bf528SMauro Carvalho Chehab 	dprintk(1, ": mpeg %s, %s mode\n",
1114cd7a67a4SMauro Carvalho Chehab 		mpeg_enable ? "enable" : "disable",
1115cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel ? "parallel" : "serial");
11169a0bf528SMauro Carvalho Chehab 
11179a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
1118ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1119ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
11209a0bf528SMauro Carvalho Chehab 	if (status < 0)
11219a0bf528SMauro Carvalho Chehab 		goto error;
11229a0bf528SMauro Carvalho Chehab 
11239a0bf528SMauro Carvalho Chehab 	/*  MPEG TS pad configuration */
11248418366dSMartin Blumenstingl 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
11259a0bf528SMauro Carvalho Chehab 	if (status < 0)
11269a0bf528SMauro Carvalho Chehab 		goto error;
11279a0bf528SMauro Carvalho Chehab 
11285a7f7b79SMauro Carvalho Chehab 	if (!mpeg_enable) {
11299a0bf528SMauro Carvalho Chehab 		/*  Set MPEG TS pads to inputmode */
11309a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
11319a0bf528SMauro Carvalho Chehab 		if (status < 0)
11329a0bf528SMauro Carvalho Chehab 			goto error;
11339a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
11349a0bf528SMauro Carvalho Chehab 		if (status < 0)
11359a0bf528SMauro Carvalho Chehab 			goto error;
11369a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
11379a0bf528SMauro Carvalho Chehab 		if (status < 0)
11389a0bf528SMauro Carvalho Chehab 			goto error;
11399a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
11409a0bf528SMauro Carvalho Chehab 		if (status < 0)
11419a0bf528SMauro Carvalho Chehab 			goto error;
11429a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
11439a0bf528SMauro Carvalho Chehab 		if (status < 0)
11449a0bf528SMauro Carvalho Chehab 			goto error;
11459a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11469a0bf528SMauro Carvalho Chehab 		if (status < 0)
11479a0bf528SMauro Carvalho Chehab 			goto error;
11489a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11499a0bf528SMauro Carvalho Chehab 		if (status < 0)
11509a0bf528SMauro Carvalho Chehab 			goto error;
11519a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11529a0bf528SMauro Carvalho Chehab 		if (status < 0)
11539a0bf528SMauro Carvalho Chehab 			goto error;
11549a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11559a0bf528SMauro Carvalho Chehab 		if (status < 0)
11569a0bf528SMauro Carvalho Chehab 			goto error;
11579a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11589a0bf528SMauro Carvalho Chehab 		if (status < 0)
11599a0bf528SMauro Carvalho Chehab 			goto error;
11609a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11619a0bf528SMauro Carvalho Chehab 		if (status < 0)
11629a0bf528SMauro Carvalho Chehab 			goto error;
11639a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
11649a0bf528SMauro Carvalho Chehab 		if (status < 0)
11659a0bf528SMauro Carvalho Chehab 			goto error;
11669a0bf528SMauro Carvalho Chehab 	} else {
11679a0bf528SMauro Carvalho Chehab 		/* Enable MPEG output */
1168cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mdx_cfg =
1169cd7a67a4SMauro Carvalho Chehab 			((state->m_ts_data_strength <<
11709a0bf528SMauro Carvalho Chehab 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1171cd7a67a4SMauro Carvalho Chehab 		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
11729a0bf528SMauro Carvalho Chehab 					SIO_PDR_MCLK_CFG_DRIVE__B) |
11739a0bf528SMauro Carvalho Chehab 					0x0003);
11749a0bf528SMauro Carvalho Chehab 
1175cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
11769a0bf528SMauro Carvalho Chehab 		if (status < 0)
11779a0bf528SMauro Carvalho Chehab 			goto error;
11789a0bf528SMauro Carvalho Chehab 
11799a0bf528SMauro Carvalho Chehab 		if (state->enable_merr_cfg)
1180cd7a67a4SMauro Carvalho Chehab 			err_cfg = sio_pdr_mdx_cfg;
11819a0bf528SMauro Carvalho Chehab 
11829a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
11839a0bf528SMauro Carvalho Chehab 		if (status < 0)
11849a0bf528SMauro Carvalho Chehab 			goto error;
11859a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
11869a0bf528SMauro Carvalho Chehab 		if (status < 0)
11879a0bf528SMauro Carvalho Chehab 			goto error;
11889a0bf528SMauro Carvalho Chehab 
11895a7f7b79SMauro Carvalho Chehab 		if (state->m_enable_parallel) {
119039c1cb2bSJonathan McCrohan 			/* parallel -> enable MD1 to MD7 */
1191ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A,
1192ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11939a0bf528SMauro Carvalho Chehab 			if (status < 0)
11949a0bf528SMauro Carvalho Chehab 				goto error;
1195ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A,
1196ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
11979a0bf528SMauro Carvalho Chehab 			if (status < 0)
11989a0bf528SMauro Carvalho Chehab 				goto error;
1199ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A,
1200ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12019a0bf528SMauro Carvalho Chehab 			if (status < 0)
12029a0bf528SMauro Carvalho Chehab 				goto error;
1203ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A,
1204ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12059a0bf528SMauro Carvalho Chehab 			if (status < 0)
12069a0bf528SMauro Carvalho Chehab 				goto error;
1207ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A,
1208ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12099a0bf528SMauro Carvalho Chehab 			if (status < 0)
12109a0bf528SMauro Carvalho Chehab 				goto error;
1211ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A,
1212ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12139a0bf528SMauro Carvalho Chehab 			if (status < 0)
12149a0bf528SMauro Carvalho Chehab 				goto error;
1215ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A,
1216ab5060cdSMauro Carvalho Chehab 					 sio_pdr_mdx_cfg);
12179a0bf528SMauro Carvalho Chehab 			if (status < 0)
12189a0bf528SMauro Carvalho Chehab 				goto error;
12199a0bf528SMauro Carvalho Chehab 		} else {
1220cd7a67a4SMauro Carvalho Chehab 			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
12219a0bf528SMauro Carvalho Chehab 						SIO_PDR_MD0_CFG_DRIVE__B)
12229a0bf528SMauro Carvalho Chehab 					| 0x0003);
12239a0bf528SMauro Carvalho Chehab 			/* serial -> disable MD1 to MD7 */
12249a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
12259a0bf528SMauro Carvalho Chehab 			if (status < 0)
12269a0bf528SMauro Carvalho Chehab 				goto error;
12279a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
12289a0bf528SMauro Carvalho Chehab 			if (status < 0)
12299a0bf528SMauro Carvalho Chehab 				goto error;
12309a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
12319a0bf528SMauro Carvalho Chehab 			if (status < 0)
12329a0bf528SMauro Carvalho Chehab 				goto error;
12339a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
12349a0bf528SMauro Carvalho Chehab 			if (status < 0)
12359a0bf528SMauro Carvalho Chehab 				goto error;
12369a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
12379a0bf528SMauro Carvalho Chehab 			if (status < 0)
12389a0bf528SMauro Carvalho Chehab 				goto error;
12399a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
12409a0bf528SMauro Carvalho Chehab 			if (status < 0)
12419a0bf528SMauro Carvalho Chehab 				goto error;
12429a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12439a0bf528SMauro Carvalho Chehab 			if (status < 0)
12449a0bf528SMauro Carvalho Chehab 				goto error;
12459a0bf528SMauro Carvalho Chehab 		}
1246cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
12479a0bf528SMauro Carvalho Chehab 		if (status < 0)
12489a0bf528SMauro Carvalho Chehab 			goto error;
1249cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
12509a0bf528SMauro Carvalho Chehab 		if (status < 0)
12519a0bf528SMauro Carvalho Chehab 			goto error;
12529a0bf528SMauro Carvalho Chehab 	}
12539a0bf528SMauro Carvalho Chehab 	/*  Enable MB output over MPEG pads and ctl input */
12549a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
12559a0bf528SMauro Carvalho Chehab 	if (status < 0)
12569a0bf528SMauro Carvalho Chehab 		goto error;
12579a0bf528SMauro Carvalho Chehab 	/*  Write nomagic word to enable pdr reg write */
12589a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
12599a0bf528SMauro Carvalho Chehab error:
12609a0bf528SMauro Carvalho Chehab 	if (status < 0)
12613a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
12629a0bf528SMauro Carvalho Chehab 	return status;
12639a0bf528SMauro Carvalho Chehab }
12649a0bf528SMauro Carvalho Chehab 
1265cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state)
12669a0bf528SMauro Carvalho Chehab {
12679a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12689a0bf528SMauro Carvalho Chehab 
1269cd7a67a4SMauro Carvalho Chehab 	return mpegts_configure_pins(state, false);
12709a0bf528SMauro Carvalho Chehab }
12719a0bf528SMauro Carvalho Chehab 
1272cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state,
1273cd7a67a4SMauro Carvalho Chehab 		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
12749a0bf528SMauro Carvalho Chehab {
1275cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
12769a0bf528SMauro Carvalho Chehab 	int status;
12779a0bf528SMauro Carvalho Chehab 	unsigned long end;
12789a0bf528SMauro Carvalho Chehab 
12799a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
12809a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
12819a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
12829a0bf528SMauro Carvalho Chehab 	if (status < 0)
12839a0bf528SMauro Carvalho Chehab 		goto error;
1284cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
12859a0bf528SMauro Carvalho Chehab 	if (status < 0)
12869a0bf528SMauro Carvalho Chehab 		goto error;
1287cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
12889a0bf528SMauro Carvalho Chehab 	if (status < 0)
12899a0bf528SMauro Carvalho Chehab 		goto error;
12909a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
12919a0bf528SMauro Carvalho Chehab 	if (status < 0)
12929a0bf528SMauro Carvalho Chehab 		goto error;
12939a0bf528SMauro Carvalho Chehab 
1294cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
12959a0bf528SMauro Carvalho Chehab 	do {
1296b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1297cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
12989a0bf528SMauro Carvalho Chehab 		if (status < 0)
12999a0bf528SMauro Carvalho Chehab 			goto error;
1300cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) &&
13019a0bf528SMauro Carvalho Chehab 			((time_is_after_jiffies(end))));
13029a0bf528SMauro Carvalho Chehab 
1303cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
13043a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
13059a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
13069a0bf528SMauro Carvalho Chehab 		goto error2;
13079a0bf528SMauro Carvalho Chehab 	}
13089a0bf528SMauro Carvalho Chehab error:
13099a0bf528SMauro Carvalho Chehab 	if (status < 0)
13103a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
13119a0bf528SMauro Carvalho Chehab error2:
13129a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
13139a0bf528SMauro Carvalho Chehab 	return status;
13149a0bf528SMauro Carvalho Chehab }
13159a0bf528SMauro Carvalho Chehab 
13169a0bf528SMauro Carvalho Chehab 
1317cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state,
1318cd7a67a4SMauro Carvalho Chehab 			     const u8 p_mc_image[], u32 length)
13199a0bf528SMauro Carvalho Chehab {
1320cd7a67a4SMauro Carvalho Chehab 	const u8 *p_src = p_mc_image;
1321cd7a67a4SMauro Carvalho Chehab 	u32 address;
1322cd7a67a4SMauro Carvalho Chehab 	u16 n_blocks;
1323cd7a67a4SMauro Carvalho Chehab 	u16 block_size;
13249a0bf528SMauro Carvalho Chehab 	u32 offset = 0;
13259a0bf528SMauro Carvalho Chehab 	u32 i;
13269a0bf528SMauro Carvalho Chehab 	int status = 0;
13279a0bf528SMauro Carvalho Chehab 
13289a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13299a0bf528SMauro Carvalho Chehab 
13309a0bf528SMauro Carvalho Chehab 	/* down the drain (we don't care about MAGIC_WORD) */
13319a0bf528SMauro Carvalho Chehab #if 0
13329a0bf528SMauro Carvalho Chehab 	/* For future reference */
1333cd7a67a4SMauro Carvalho Chehab 	drain = (p_src[0] << 8) | p_src[1];
13349a0bf528SMauro Carvalho Chehab #endif
1335cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13369a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
1337cd7a67a4SMauro Carvalho Chehab 	n_blocks = (p_src[0] << 8) | p_src[1];
1338cd7a67a4SMauro Carvalho Chehab 	p_src += sizeof(u16);
13399a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
13409a0bf528SMauro Carvalho Chehab 
1341cd7a67a4SMauro Carvalho Chehab 	for (i = 0; i < n_blocks; i += 1) {
1342cd7a67a4SMauro Carvalho Chehab 		address = (p_src[0] << 24) | (p_src[1] << 16) |
1343cd7a67a4SMauro Carvalho Chehab 		    (p_src[2] << 8) | p_src[3];
1344cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u32);
13459a0bf528SMauro Carvalho Chehab 		offset += sizeof(u32);
13469a0bf528SMauro Carvalho Chehab 
1347cd7a67a4SMauro Carvalho Chehab 		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1348cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13499a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13509a0bf528SMauro Carvalho Chehab 
13519a0bf528SMauro Carvalho Chehab #if 0
13529a0bf528SMauro Carvalho Chehab 		/* For future reference */
1353cd7a67a4SMauro Carvalho Chehab 		flags = (p_src[0] << 8) | p_src[1];
13549a0bf528SMauro Carvalho Chehab #endif
1355cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13569a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13579a0bf528SMauro Carvalho Chehab 
13589a0bf528SMauro Carvalho Chehab #if 0
13599a0bf528SMauro Carvalho Chehab 		/* For future reference */
1360cd7a67a4SMauro Carvalho Chehab 		block_crc = (p_src[0] << 8) | p_src[1];
13619a0bf528SMauro Carvalho Chehab #endif
1362cd7a67a4SMauro Carvalho Chehab 		p_src += sizeof(u16);
13639a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
13649a0bf528SMauro Carvalho Chehab 
1365cd7a67a4SMauro Carvalho Chehab 		if (offset + block_size > length) {
13663a4398f5SMauro Carvalho Chehab 			pr_err("Firmware is corrupted.\n");
13679a0bf528SMauro Carvalho Chehab 			return -EINVAL;
13689a0bf528SMauro Carvalho Chehab 		}
13699a0bf528SMauro Carvalho Chehab 
1370cd7a67a4SMauro Carvalho Chehab 		status = write_block(state, address, block_size, p_src);
13719a0bf528SMauro Carvalho Chehab 		if (status < 0) {
13723a4398f5SMauro Carvalho Chehab 			pr_err("Error %d while loading firmware\n", status);
13739a0bf528SMauro Carvalho Chehab 			break;
13749a0bf528SMauro Carvalho Chehab 		}
1375cd7a67a4SMauro Carvalho Chehab 		p_src += block_size;
1376cd7a67a4SMauro Carvalho Chehab 		offset += block_size;
13779a0bf528SMauro Carvalho Chehab 	}
13789a0bf528SMauro Carvalho Chehab 	return status;
13799a0bf528SMauro Carvalho Chehab }
13809a0bf528SMauro Carvalho Chehab 
1381cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
13829a0bf528SMauro Carvalho Chehab {
13839a0bf528SMauro Carvalho Chehab 	int status;
13849a0bf528SMauro Carvalho Chehab 	u16 data = 0;
1385cd7a67a4SMauro Carvalho Chehab 	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1386cd7a67a4SMauro Carvalho Chehab 	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
13879a0bf528SMauro Carvalho Chehab 	unsigned long end;
13889a0bf528SMauro Carvalho Chehab 
13899a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13909a0bf528SMauro Carvalho Chehab 
13915a7f7b79SMauro Carvalho Chehab 	if (!enable) {
1392cd7a67a4SMauro Carvalho Chehab 		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1393cd7a67a4SMauro Carvalho Chehab 		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
13949a0bf528SMauro Carvalho Chehab 	}
13959a0bf528SMauro Carvalho Chehab 
13969a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1397cd7a67a4SMauro Carvalho Chehab 	if (status >= 0 && data == desired_status) {
13989a0bf528SMauro Carvalho Chehab 		/* tokenring already has correct status */
13999a0bf528SMauro Carvalho Chehab 		return status;
14009a0bf528SMauro Carvalho Chehab 	}
14019a0bf528SMauro Carvalho Chehab 	/* Disable/enable dvbt tokenring bridge   */
1402cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
14039a0bf528SMauro Carvalho Chehab 
14049a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
14059a0bf528SMauro Carvalho Chehab 	do {
14069a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1407ab5060cdSMauro Carvalho Chehab 		if ((status >= 0 && data == desired_status)
1408ab5060cdSMauro Carvalho Chehab 		    || time_is_after_jiffies(end))
14099a0bf528SMauro Carvalho Chehab 			break;
1410b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
14119a0bf528SMauro Carvalho Chehab 	} while (1);
1412cd7a67a4SMauro Carvalho Chehab 	if (data != desired_status) {
14133a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
14149a0bf528SMauro Carvalho Chehab 		return -EINVAL;
14159a0bf528SMauro Carvalho Chehab 	}
14169a0bf528SMauro Carvalho Chehab 	return status;
14179a0bf528SMauro Carvalho Chehab }
14189a0bf528SMauro Carvalho Chehab 
1419cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state)
14209a0bf528SMauro Carvalho Chehab {
14219a0bf528SMauro Carvalho Chehab 	int status = 0;
1422cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
1423cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_ipr_mode = 0;
14249a0bf528SMauro Carvalho Chehab 
14259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14269a0bf528SMauro Carvalho Chehab 
142739c1cb2bSJonathan McCrohan 	/* Graceful shutdown (byte boundaries) */
1428cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
14299a0bf528SMauro Carvalho Chehab 	if (status < 0)
14309a0bf528SMauro Carvalho Chehab 		goto error;
1431cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1432cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
14339a0bf528SMauro Carvalho Chehab 	if (status < 0)
14349a0bf528SMauro Carvalho Chehab 		goto error;
14359a0bf528SMauro Carvalho Chehab 
14369a0bf528SMauro Carvalho Chehab 	/* Suppress MCLK during absence of data */
1437cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
14389a0bf528SMauro Carvalho Chehab 	if (status < 0)
14399a0bf528SMauro Carvalho Chehab 		goto error;
1440cd7a67a4SMauro Carvalho Chehab 	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1441cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
14429a0bf528SMauro Carvalho Chehab 
14439a0bf528SMauro Carvalho Chehab error:
14449a0bf528SMauro Carvalho Chehab 	if (status < 0)
14453a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14469a0bf528SMauro Carvalho Chehab 
14479a0bf528SMauro Carvalho Chehab 	return status;
14489a0bf528SMauro Carvalho Chehab }
14499a0bf528SMauro Carvalho Chehab 
14509a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
1451cd7a67a4SMauro Carvalho Chehab 		       u16 cmd, u8 parameter_len,
1452cd7a67a4SMauro Carvalho Chehab 		       u16 *parameter, u8 result_len, u16 *result)
14539a0bf528SMauro Carvalho Chehab {
14549a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
14559a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
14569a0bf528SMauro Carvalho Chehab #endif
1457cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
14589a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
14599a0bf528SMauro Carvalho Chehab 	unsigned long end;
14609a0bf528SMauro Carvalho Chehab 	u8 buffer[34];
14619a0bf528SMauro Carvalho Chehab 	int cnt = 0, ii;
14629a0bf528SMauro Carvalho Chehab 	const char *p;
14639a0bf528SMauro Carvalho Chehab 	char errname[30];
14649a0bf528SMauro Carvalho Chehab 
14659a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14669a0bf528SMauro Carvalho Chehab 
1467cd7a67a4SMauro Carvalho Chehab 	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1468cd7a67a4SMauro Carvalho Chehab 	    ((result_len > 0) && (result == NULL))) {
14693a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
14709a0bf528SMauro Carvalho Chehab 		return status;
14719a0bf528SMauro Carvalho Chehab 	}
14729a0bf528SMauro Carvalho Chehab 
14739a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
14749a0bf528SMauro Carvalho Chehab 
14759a0bf528SMauro Carvalho Chehab 	/* assume that the command register is ready
14769a0bf528SMauro Carvalho Chehab 		since it is checked afterwards */
1477cd7a67a4SMauro Carvalho Chehab 	for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
14789a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = (parameter[ii] & 0xFF);
14799a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
14809a0bf528SMauro Carvalho Chehab 	}
14819a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = (cmd & 0xFF);
14829a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
14839a0bf528SMauro Carvalho Chehab 
14849a0bf528SMauro Carvalho Chehab 	write_block(state, SCU_RAM_PARAM_0__A -
1485cd7a67a4SMauro Carvalho Chehab 			(parameter_len - 1), cnt, buffer);
14869a0bf528SMauro Carvalho Chehab 	/* Wait until SCU has processed command */
14879a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
14889a0bf528SMauro Carvalho Chehab 	do {
1489b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
1490cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
14919a0bf528SMauro Carvalho Chehab 		if (status < 0)
14929a0bf528SMauro Carvalho Chehab 			goto error;
1493cd7a67a4SMauro Carvalho Chehab 	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1494cd7a67a4SMauro Carvalho Chehab 	if (cur_cmd != DRX_SCU_READY) {
14953a4398f5SMauro Carvalho Chehab 		pr_err("SCU not ready\n");
14969a0bf528SMauro Carvalho Chehab 		status = -EIO;
14979a0bf528SMauro Carvalho Chehab 		goto error2;
14989a0bf528SMauro Carvalho Chehab 	}
14999a0bf528SMauro Carvalho Chehab 	/* read results */
1500cd7a67a4SMauro Carvalho Chehab 	if ((result_len > 0) && (result != NULL)) {
15019a0bf528SMauro Carvalho Chehab 		s16 err;
15029a0bf528SMauro Carvalho Chehab 		int ii;
15039a0bf528SMauro Carvalho Chehab 
1504cd7a67a4SMauro Carvalho Chehab 		for (ii = result_len - 1; ii >= 0; ii -= 1) {
1505ab5060cdSMauro Carvalho Chehab 			status = read16(state, SCU_RAM_PARAM_0__A - ii,
1506ab5060cdSMauro Carvalho Chehab 					&result[ii]);
15079a0bf528SMauro Carvalho Chehab 			if (status < 0)
15089a0bf528SMauro Carvalho Chehab 				goto error;
15099a0bf528SMauro Carvalho Chehab 		}
15109a0bf528SMauro Carvalho Chehab 
15119a0bf528SMauro Carvalho Chehab 		/* Check if an error was reported by SCU */
15129a0bf528SMauro Carvalho Chehab 		err = (s16)result[0];
15139a0bf528SMauro Carvalho Chehab 		if (err >= 0)
15149a0bf528SMauro Carvalho Chehab 			goto error;
15159a0bf528SMauro Carvalho Chehab 
15169a0bf528SMauro Carvalho Chehab 		/* check for the known error codes */
15179a0bf528SMauro Carvalho Chehab 		switch (err) {
15189a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKCMD:
15199a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKCMD";
15209a0bf528SMauro Carvalho Chehab 			break;
15219a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKSTD:
15229a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKSTD";
15239a0bf528SMauro Carvalho Chehab 			break;
15249a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_SIZE:
15259a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_SIZE";
15269a0bf528SMauro Carvalho Chehab 			break;
15279a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_INVPAR:
15289a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_INVPAR";
15299a0bf528SMauro Carvalho Chehab 			break;
15309a0bf528SMauro Carvalho Chehab 		default: /* Other negative values are errors */
15319a0bf528SMauro Carvalho Chehab 			sprintf(errname, "ERROR: %d\n", err);
15329a0bf528SMauro Carvalho Chehab 			p = errname;
15339a0bf528SMauro Carvalho Chehab 		}
15343a4398f5SMauro Carvalho Chehab 		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
15359a0bf528SMauro Carvalho Chehab 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
15369a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
15379a0bf528SMauro Carvalho Chehab 		goto error2;
15389a0bf528SMauro Carvalho Chehab 	}
15399a0bf528SMauro Carvalho Chehab 
15409a0bf528SMauro Carvalho Chehab error:
15419a0bf528SMauro Carvalho Chehab 	if (status < 0)
15423a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15439a0bf528SMauro Carvalho Chehab error2:
15449a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
15459a0bf528SMauro Carvalho Chehab 	return status;
15469a0bf528SMauro Carvalho Chehab }
15479a0bf528SMauro Carvalho Chehab 
1548cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active)
15499a0bf528SMauro Carvalho Chehab {
15509a0bf528SMauro Carvalho Chehab 	u16 data = 0;
15519a0bf528SMauro Carvalho Chehab 	int status;
15529a0bf528SMauro Carvalho Chehab 
15539a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15549a0bf528SMauro Carvalho Chehab 
15559a0bf528SMauro Carvalho Chehab 	/* Configure IQM */
15569a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_STDBY__A, &data);
15579a0bf528SMauro Carvalho Chehab 	if (status < 0)
15589a0bf528SMauro Carvalho Chehab 		goto error;
15599a0bf528SMauro Carvalho Chehab 
15609a0bf528SMauro Carvalho Chehab 	if (!active) {
15619a0bf528SMauro Carvalho Chehab 		data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
15629a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_AMP_STANDBY
15639a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_PD_STANDBY
15649a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
15659a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
15669a0bf528SMauro Carvalho Chehab 	} else {
15679a0bf528SMauro Carvalho Chehab 		data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
15689a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
15699a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_PD_STANDBY)
15709a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
15719a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
15729a0bf528SMauro Carvalho Chehab 			);
15739a0bf528SMauro Carvalho Chehab 	}
15749a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_STDBY__A, data);
15759a0bf528SMauro Carvalho Chehab 
15769a0bf528SMauro Carvalho Chehab error:
15779a0bf528SMauro Carvalho Chehab 	if (status < 0)
15783a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
15799a0bf528SMauro Carvalho Chehab 	return status;
15809a0bf528SMauro Carvalho Chehab }
15819a0bf528SMauro Carvalho Chehab 
1582cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
15839a0bf528SMauro Carvalho Chehab {
15849a0bf528SMauro Carvalho Chehab 	int status = 0;
1585cd7a67a4SMauro Carvalho Chehab 	u16 sio_cc_pwd_mode = 0;
15869a0bf528SMauro Carvalho Chehab 
15879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15889a0bf528SMauro Carvalho Chehab 
15899a0bf528SMauro Carvalho Chehab 	/* Check arguments */
15909a0bf528SMauro Carvalho Chehab 	if (mode == NULL)
15919a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15929a0bf528SMauro Carvalho Chehab 
15939a0bf528SMauro Carvalho Chehab 	switch (*mode) {
15949a0bf528SMauro Carvalho Chehab 	case DRX_POWER_UP:
1595cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
15969a0bf528SMauro Carvalho Chehab 		break;
15979a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_OFDM:
1598cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
15999a0bf528SMauro Carvalho Chehab 		break;
16009a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_CORE:
1601cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
16029a0bf528SMauro Carvalho Chehab 		break;
16039a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_PLL:
1604cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
16059a0bf528SMauro Carvalho Chehab 		break;
16069a0bf528SMauro Carvalho Chehab 	case DRX_POWER_DOWN:
1607cd7a67a4SMauro Carvalho Chehab 		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
16089a0bf528SMauro Carvalho Chehab 		break;
16099a0bf528SMauro Carvalho Chehab 	default:
16109a0bf528SMauro Carvalho Chehab 		/* Unknow sleep mode */
16119a0bf528SMauro Carvalho Chehab 		return -EINVAL;
16129a0bf528SMauro Carvalho Chehab 	}
16139a0bf528SMauro Carvalho Chehab 
16149a0bf528SMauro Carvalho Chehab 	/* If already in requested power mode, do nothing */
1615cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode == *mode)
16169a0bf528SMauro Carvalho Chehab 		return 0;
16179a0bf528SMauro Carvalho Chehab 
16189a0bf528SMauro Carvalho Chehab 	/* For next steps make sure to start from DRX_POWER_UP mode */
1619cd7a67a4SMauro Carvalho Chehab 	if (state->m_current_power_mode != DRX_POWER_UP) {
1620cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
16219a0bf528SMauro Carvalho Chehab 		if (status < 0)
16229a0bf528SMauro Carvalho Chehab 			goto error;
1623cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, true);
16249a0bf528SMauro Carvalho Chehab 		if (status < 0)
16259a0bf528SMauro Carvalho Chehab 			goto error;
16269a0bf528SMauro Carvalho Chehab 	}
16279a0bf528SMauro Carvalho Chehab 
16289a0bf528SMauro Carvalho Chehab 	if (*mode == DRX_POWER_UP) {
16292c149601SMasahiro Yamada 		/* Restore analog & pin configuration */
16309a0bf528SMauro Carvalho Chehab 	} else {
16319a0bf528SMauro Carvalho Chehab 		/* Power down to requested mode */
16329a0bf528SMauro Carvalho Chehab 		/* Backup some register settings */
16339a0bf528SMauro Carvalho Chehab 		/* Set pins with possible pull-ups connected
16349a0bf528SMauro Carvalho Chehab 		   to them in input mode */
16359a0bf528SMauro Carvalho Chehab 		/* Analog power down */
16369a0bf528SMauro Carvalho Chehab 		/* ADC power down */
16379a0bf528SMauro Carvalho Chehab 		/* Power down device */
16389a0bf528SMauro Carvalho Chehab 		/* stop all comm_exec */
16399a0bf528SMauro Carvalho Chehab 		/* Stop and power down previous standard */
1640cd7a67a4SMauro Carvalho Chehab 		switch (state->m_operation_mode) {
16419a0bf528SMauro Carvalho Chehab 		case OM_DVBT:
1642cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16439a0bf528SMauro Carvalho Chehab 			if (status < 0)
16449a0bf528SMauro Carvalho Chehab 				goto error;
1645cd7a67a4SMauro Carvalho Chehab 			status = power_down_dvbt(state, false);
16469a0bf528SMauro Carvalho Chehab 			if (status < 0)
16479a0bf528SMauro Carvalho Chehab 				goto error;
16489a0bf528SMauro Carvalho Chehab 			break;
16499a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_A:
16509a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_C:
1651cd7a67a4SMauro Carvalho Chehab 			status = mpegts_stop(state);
16529a0bf528SMauro Carvalho Chehab 			if (status < 0)
16539a0bf528SMauro Carvalho Chehab 				goto error;
1654cd7a67a4SMauro Carvalho Chehab 			status = power_down_qam(state);
16559a0bf528SMauro Carvalho Chehab 			if (status < 0)
16569a0bf528SMauro Carvalho Chehab 				goto error;
16579a0bf528SMauro Carvalho Chehab 			break;
16589a0bf528SMauro Carvalho Chehab 		default:
16599a0bf528SMauro Carvalho Chehab 			break;
16609a0bf528SMauro Carvalho Chehab 		}
1661cd7a67a4SMauro Carvalho Chehab 		status = dvbt_enable_ofdm_token_ring(state, false);
16629a0bf528SMauro Carvalho Chehab 		if (status < 0)
16639a0bf528SMauro Carvalho Chehab 			goto error;
1664cd7a67a4SMauro Carvalho Chehab 		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
16659a0bf528SMauro Carvalho Chehab 		if (status < 0)
16669a0bf528SMauro Carvalho Chehab 			goto error;
16679a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
16689a0bf528SMauro Carvalho Chehab 		if (status < 0)
16699a0bf528SMauro Carvalho Chehab 			goto error;
16709a0bf528SMauro Carvalho Chehab 
16719a0bf528SMauro Carvalho Chehab 		if (*mode != DRXK_POWER_DOWN_OFDM) {
1672cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_ctrl |=
16739a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1674cd7a67a4SMauro Carvalho Chehab 			status = hi_cfg_command(state);
16759a0bf528SMauro Carvalho Chehab 			if (status < 0)
16769a0bf528SMauro Carvalho Chehab 				goto error;
16779a0bf528SMauro Carvalho Chehab 		}
16789a0bf528SMauro Carvalho Chehab 	}
1679cd7a67a4SMauro Carvalho Chehab 	state->m_current_power_mode = *mode;
16809a0bf528SMauro Carvalho Chehab 
16819a0bf528SMauro Carvalho Chehab error:
16829a0bf528SMauro Carvalho Chehab 	if (status < 0)
16833a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
16849a0bf528SMauro Carvalho Chehab 
16859a0bf528SMauro Carvalho Chehab 	return status;
16869a0bf528SMauro Carvalho Chehab }
16879a0bf528SMauro Carvalho Chehab 
1688cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
16899a0bf528SMauro Carvalho Chehab {
1690cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1691cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
16929a0bf528SMauro Carvalho Chehab 	u16 data = 0;
16939a0bf528SMauro Carvalho Chehab 	int status;
16949a0bf528SMauro Carvalho Chehab 
16959a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
16969a0bf528SMauro Carvalho Chehab 
16979a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
16989a0bf528SMauro Carvalho Chehab 	if (status < 0)
16999a0bf528SMauro Carvalho Chehab 		goto error;
17009a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
17019a0bf528SMauro Carvalho Chehab 		/* Send OFDM stop command */
1702ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1703ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1704ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1705ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
17069a0bf528SMauro Carvalho Chehab 		if (status < 0)
17079a0bf528SMauro Carvalho Chehab 			goto error;
17089a0bf528SMauro Carvalho Chehab 		/* Send OFDM reset command */
1709ab5060cdSMauro Carvalho Chehab 		status = scu_command(state,
1710ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_OFDM
1711ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1712ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
17139a0bf528SMauro Carvalho Chehab 		if (status < 0)
17149a0bf528SMauro Carvalho Chehab 			goto error;
17159a0bf528SMauro Carvalho Chehab 	}
17169a0bf528SMauro Carvalho Chehab 
17179a0bf528SMauro Carvalho Chehab 	/* Reset datapath for OFDM, processors first */
17189a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
17199a0bf528SMauro Carvalho Chehab 	if (status < 0)
17209a0bf528SMauro Carvalho Chehab 		goto error;
17219a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
17229a0bf528SMauro Carvalho Chehab 	if (status < 0)
17239a0bf528SMauro Carvalho Chehab 		goto error;
17249a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
17259a0bf528SMauro Carvalho Chehab 	if (status < 0)
17269a0bf528SMauro Carvalho Chehab 		goto error;
17279a0bf528SMauro Carvalho Chehab 
17289a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
1729cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
17309a0bf528SMauro Carvalho Chehab 	if (status < 0)
17319a0bf528SMauro Carvalho Chehab 		goto error;
17329a0bf528SMauro Carvalho Chehab 
17339a0bf528SMauro Carvalho Chehab 	/* powerdown to OFDM mode          */
1734cd7a67a4SMauro Carvalho Chehab 	if (set_power_mode) {
1735cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
17369a0bf528SMauro Carvalho Chehab 		if (status < 0)
17379a0bf528SMauro Carvalho Chehab 			goto error;
17389a0bf528SMauro Carvalho Chehab 	}
17399a0bf528SMauro Carvalho Chehab error:
17409a0bf528SMauro Carvalho Chehab 	if (status < 0)
17413a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
17429a0bf528SMauro Carvalho Chehab 	return status;
17439a0bf528SMauro Carvalho Chehab }
17449a0bf528SMauro Carvalho Chehab 
1745cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state,
1746cd7a67a4SMauro Carvalho Chehab 			    enum operation_mode o_mode)
17479a0bf528SMauro Carvalho Chehab {
17489a0bf528SMauro Carvalho Chehab 	int status = 0;
17499a0bf528SMauro Carvalho Chehab 
17509a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17519a0bf528SMauro Carvalho Chehab 	/*
17529a0bf528SMauro Carvalho Chehab 	   Stop and power down previous standard
17539a0bf528SMauro Carvalho Chehab 	   TODO investigate total power down instead of partial
17549a0bf528SMauro Carvalho Chehab 	   power down depending on "previous" standard.
17559a0bf528SMauro Carvalho Chehab 	 */
17569a0bf528SMauro Carvalho Chehab 
17579a0bf528SMauro Carvalho Chehab 	/* disable HW lock indicator */
1758ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
1759ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
17609a0bf528SMauro Carvalho Chehab 	if (status < 0)
17619a0bf528SMauro Carvalho Chehab 		goto error;
17629a0bf528SMauro Carvalho Chehab 
17639a0bf528SMauro Carvalho Chehab 	/* Device is already at the required mode */
1764cd7a67a4SMauro Carvalho Chehab 	if (state->m_operation_mode == o_mode)
17659a0bf528SMauro Carvalho Chehab 		return 0;
17669a0bf528SMauro Carvalho Chehab 
1767cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
17689a0bf528SMauro Carvalho Chehab 		/* OM_NONE was added for start up */
17699a0bf528SMauro Carvalho Chehab 	case OM_NONE:
17709a0bf528SMauro Carvalho Chehab 		break;
17719a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1772cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17739a0bf528SMauro Carvalho Chehab 		if (status < 0)
17749a0bf528SMauro Carvalho Chehab 			goto error;
1775cd7a67a4SMauro Carvalho Chehab 		status = power_down_dvbt(state, true);
17769a0bf528SMauro Carvalho Chehab 		if (status < 0)
17779a0bf528SMauro Carvalho Chehab 			goto error;
1778cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17799a0bf528SMauro Carvalho Chehab 		break;
17809a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
17819a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1782cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
17839a0bf528SMauro Carvalho Chehab 		if (status < 0)
17849a0bf528SMauro Carvalho Chehab 			goto error;
1785cd7a67a4SMauro Carvalho Chehab 		status = power_down_qam(state);
17869a0bf528SMauro Carvalho Chehab 		if (status < 0)
17879a0bf528SMauro Carvalho Chehab 			goto error;
1788cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = OM_NONE;
17899a0bf528SMauro Carvalho Chehab 		break;
17909a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
17919a0bf528SMauro Carvalho Chehab 	default:
17929a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
17939a0bf528SMauro Carvalho Chehab 		goto error;
17949a0bf528SMauro Carvalho Chehab 	}
17959a0bf528SMauro Carvalho Chehab 
17969a0bf528SMauro Carvalho Chehab 	/*
17979a0bf528SMauro Carvalho Chehab 		Power up new standard
17989a0bf528SMauro Carvalho Chehab 		*/
1799cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
18009a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
18019a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-T\n");
1802cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1803cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt_standard(state, o_mode);
18049a0bf528SMauro Carvalho Chehab 		if (status < 0)
18059a0bf528SMauro Carvalho Chehab 			goto error;
18069a0bf528SMauro Carvalho Chehab 		break;
18079a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
18089a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
18099a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-C Annex %c\n",
1810cd7a67a4SMauro Carvalho Chehab 			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1811cd7a67a4SMauro Carvalho Chehab 		state->m_operation_mode = o_mode;
1812cd7a67a4SMauro Carvalho Chehab 		status = set_qam_standard(state, o_mode);
18139a0bf528SMauro Carvalho Chehab 		if (status < 0)
18149a0bf528SMauro Carvalho Chehab 			goto error;
18159a0bf528SMauro Carvalho Chehab 		break;
18169a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18179a0bf528SMauro Carvalho Chehab 	default:
18189a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
18199a0bf528SMauro Carvalho Chehab 	}
18209a0bf528SMauro Carvalho Chehab error:
18219a0bf528SMauro Carvalho Chehab 	if (status < 0)
18223a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18239a0bf528SMauro Carvalho Chehab 	return status;
18249a0bf528SMauro Carvalho Chehab }
18259a0bf528SMauro Carvalho Chehab 
1826cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq,
1827cd7a67a4SMauro Carvalho Chehab 		 s32 intermediate_frequency)
18289a0bf528SMauro Carvalho Chehab {
18299a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18309a0bf528SMauro Carvalho Chehab 
1831cd7a67a4SMauro Carvalho Chehab 	u16 i_freqk_hz;
1832cd7a67a4SMauro Carvalho Chehab 	s32 offsetk_hz = offset_freq / 1000;
18339a0bf528SMauro Carvalho Chehab 
18349a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
1835cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state != DRXK_STOPPED &&
1836cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state != DRXK_DTV_STARTED)
18379a0bf528SMauro Carvalho Chehab 		goto error;
18389a0bf528SMauro Carvalho Chehab 
1839cd7a67a4SMauro Carvalho Chehab 	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
18409a0bf528SMauro Carvalho Chehab 
1841cd7a67a4SMauro Carvalho Chehab 	if (intermediate_frequency < 0) {
1842cd7a67a4SMauro Carvalho Chehab 		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1843cd7a67a4SMauro Carvalho Chehab 		intermediate_frequency = -intermediate_frequency;
18449a0bf528SMauro Carvalho Chehab 	}
18459a0bf528SMauro Carvalho Chehab 
1846cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18479a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18489a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1849cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1850cd7a67a4SMauro Carvalho Chehab 		status = set_qam(state, i_freqk_hz, offsetk_hz);
18519a0bf528SMauro Carvalho Chehab 		if (status < 0)
18529a0bf528SMauro Carvalho Chehab 			goto error;
1853cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18549a0bf528SMauro Carvalho Chehab 		break;
18559a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1856cd7a67a4SMauro Carvalho Chehab 		i_freqk_hz = (intermediate_frequency / 1000);
1857cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
18589a0bf528SMauro Carvalho Chehab 		if (status < 0)
18599a0bf528SMauro Carvalho Chehab 			goto error;
1860cd7a67a4SMauro Carvalho Chehab 		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
18619a0bf528SMauro Carvalho Chehab 		if (status < 0)
18629a0bf528SMauro Carvalho Chehab 			goto error;
1863cd7a67a4SMauro Carvalho Chehab 		status = dvbt_start(state);
18649a0bf528SMauro Carvalho Chehab 		if (status < 0)
18659a0bf528SMauro Carvalho Chehab 			goto error;
1866cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_DTV_STARTED;
18679a0bf528SMauro Carvalho Chehab 		break;
18689a0bf528SMauro Carvalho Chehab 	default:
18699a0bf528SMauro Carvalho Chehab 		break;
18709a0bf528SMauro Carvalho Chehab 	}
18719a0bf528SMauro Carvalho Chehab error:
18729a0bf528SMauro Carvalho Chehab 	if (status < 0)
18733a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
18749a0bf528SMauro Carvalho Chehab 	return status;
18759a0bf528SMauro Carvalho Chehab }
18769a0bf528SMauro Carvalho Chehab 
1877cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state)
18789a0bf528SMauro Carvalho Chehab {
18799a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18809a0bf528SMauro Carvalho Chehab 
1881cd7a67a4SMauro Carvalho Chehab 	mpegts_stop(state);
18829a0bf528SMauro Carvalho Chehab 	return 0;
18839a0bf528SMauro Carvalho Chehab }
18849a0bf528SMauro Carvalho Chehab 
1885cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
18869a0bf528SMauro Carvalho Chehab {
18879a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
18889a0bf528SMauro Carvalho Chehab 
18899a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18909a0bf528SMauro Carvalho Chehab 
1891cd7a67a4SMauro Carvalho Chehab 	if (p_lock_status == NULL)
18929a0bf528SMauro Carvalho Chehab 		goto error;
18939a0bf528SMauro Carvalho Chehab 
1894cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
18959a0bf528SMauro Carvalho Chehab 
18969a0bf528SMauro Carvalho Chehab 	/* define the SCU command code */
1897cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
18989a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
18999a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
19009a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
1901cd7a67a4SMauro Carvalho Chehab 		status = get_qam_lock_status(state, p_lock_status);
19029a0bf528SMauro Carvalho Chehab 		break;
19039a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
1904cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_lock_status(state, p_lock_status);
19059a0bf528SMauro Carvalho Chehab 		break;
19069a0bf528SMauro Carvalho Chehab 	default:
1907b73bb2abSDaniel Scheller 		pr_debug("Unsupported operation mode %d in %s\n",
1908b73bb2abSDaniel Scheller 			state->m_operation_mode, __func__);
1909b73bb2abSDaniel Scheller 		return 0;
19109a0bf528SMauro Carvalho Chehab 	}
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_start(struct drxk_state *state)
19189a0bf528SMauro Carvalho Chehab {
19199a0bf528SMauro Carvalho Chehab 	int status;
19209a0bf528SMauro Carvalho Chehab 
1921cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_snc_mode = 0;
19229a0bf528SMauro Carvalho Chehab 
19239a0bf528SMauro Carvalho Chehab 	/* Allow OC to sync again */
1924cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
19259a0bf528SMauro Carvalho Chehab 	if (status < 0)
19269a0bf528SMauro Carvalho Chehab 		goto error;
1927cd7a67a4SMauro Carvalho Chehab 	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1928cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
19299a0bf528SMauro Carvalho Chehab 	if (status < 0)
19309a0bf528SMauro Carvalho Chehab 		goto error;
19319a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
19329a0bf528SMauro Carvalho Chehab error:
19339a0bf528SMauro Carvalho Chehab 	if (status < 0)
19343a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19359a0bf528SMauro Carvalho Chehab 	return status;
19369a0bf528SMauro Carvalho Chehab }
19379a0bf528SMauro Carvalho Chehab 
1938cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state)
19399a0bf528SMauro Carvalho Chehab {
19409a0bf528SMauro Carvalho Chehab 	int status;
19419a0bf528SMauro Carvalho Chehab 
19429a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19439a0bf528SMauro Carvalho Chehab 
19449a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
19459a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
19469a0bf528SMauro Carvalho Chehab 	if (status < 0)
19479a0bf528SMauro Carvalho Chehab 		goto error;
19489a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
19499a0bf528SMauro Carvalho Chehab 	if (status < 0)
19509a0bf528SMauro Carvalho Chehab 		goto error;
19519a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
19529a0bf528SMauro Carvalho Chehab 	if (status < 0)
19539a0bf528SMauro Carvalho Chehab 		goto error;
19549a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
19559a0bf528SMauro Carvalho Chehab 	if (status < 0)
19569a0bf528SMauro Carvalho Chehab 		goto error;
19579a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
19589a0bf528SMauro Carvalho Chehab 	if (status < 0)
19599a0bf528SMauro Carvalho Chehab 		goto error;
19609a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
19619a0bf528SMauro Carvalho Chehab 	if (status < 0)
19629a0bf528SMauro Carvalho Chehab 		goto error;
19639a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
19649a0bf528SMauro Carvalho Chehab 	if (status < 0)
19659a0bf528SMauro Carvalho Chehab 		goto error;
19669a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
19679a0bf528SMauro Carvalho Chehab 	if (status < 0)
19689a0bf528SMauro Carvalho Chehab 		goto error;
19699a0bf528SMauro Carvalho Chehab 
19709a0bf528SMauro Carvalho Chehab 	/* Additional configuration */
19719a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_OCR_INVERT__A, 0);
19729a0bf528SMauro Carvalho Chehab 	if (status < 0)
19739a0bf528SMauro Carvalho Chehab 		goto error;
19749a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_LWM__A, 2);
19759a0bf528SMauro Carvalho Chehab 	if (status < 0)
19769a0bf528SMauro Carvalho Chehab 		goto error;
19779a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
19789a0bf528SMauro Carvalho Chehab error:
19799a0bf528SMauro Carvalho Chehab 	if (status < 0)
19803a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
19819a0bf528SMauro Carvalho Chehab 
19829a0bf528SMauro Carvalho Chehab 	return status;
19839a0bf528SMauro Carvalho Chehab }
19849a0bf528SMauro Carvalho Chehab 
1985cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state,
1986cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
19879a0bf528SMauro Carvalho Chehab {
19889a0bf528SMauro Carvalho Chehab 	int status;
19899a0bf528SMauro Carvalho Chehab 
1990cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
1991cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
1992cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1993cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
1994cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
1995cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
1996cd7a67a4SMauro Carvalho Chehab 	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
1997cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_mode = 0;
1998cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_tmd_int_upd_rate = 0;
1999cd7a67a4SMauro Carvalho Chehab 	u32 max_bit_rate = 0;
2000cd7a67a4SMauro Carvalho Chehab 	bool static_clk = false;
20019a0bf528SMauro Carvalho Chehab 
20029a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
20039a0bf528SMauro Carvalho Chehab 
20049a0bf528SMauro Carvalho Chehab 	/* Check insertion of the Reed-Solomon parity bytes */
2005cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
20069a0bf528SMauro Carvalho Chehab 	if (status < 0)
20079a0bf528SMauro Carvalho Chehab 		goto error;
2008cd7a67a4SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
20099a0bf528SMauro Carvalho Chehab 	if (status < 0)
20109a0bf528SMauro Carvalho Chehab 		goto error;
2011cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2012cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
20135a7f7b79SMauro Carvalho Chehab 	if (state->m_insert_rs_byte) {
20149a0bf528SMauro Carvalho Chehab 		/* enable parity symbol forward */
2015cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
20169a0bf528SMauro Carvalho Chehab 		/* MVAL disable during parity bytes */
2017cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
20189a0bf528SMauro Carvalho Chehab 		/* TS burst length to 204 */
2019cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_burst_len = 204;
20209a0bf528SMauro Carvalho Chehab 	}
20219a0bf528SMauro Carvalho Chehab 
202239c1cb2bSJonathan McCrohan 	/* Check serial or parallel output */
2023cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
20245a7f7b79SMauro Carvalho Chehab 	if (!state->m_enable_parallel) {
20259a0bf528SMauro Carvalho Chehab 		/* MPEG data output is serial -> set ipr_mode[0] */
2026cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
20279a0bf528SMauro Carvalho Chehab 	}
20289a0bf528SMauro Carvalho Chehab 
2029cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
20309a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2031cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbt_bitrate;
2032cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 3;
2033cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xC00000;
2034cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbt_static_clk;
20359a0bf528SMauro Carvalho Chehab 		break;
20369a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
20379a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2038cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_mode = 0x0004;
2039cd7a67a4SMauro Carvalho Chehab 		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
2040cd7a67a4SMauro Carvalho Chehab 		max_bit_rate = state->m_dvbc_bitrate;
2041cd7a67a4SMauro Carvalho Chehab 		static_clk = state->m_dvbc_static_clk;
20429a0bf528SMauro Carvalho Chehab 		break;
20439a0bf528SMauro Carvalho Chehab 	default:
20449a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
20459a0bf528SMauro Carvalho Chehab 	}		/* switch (standard) */
20469a0bf528SMauro Carvalho Chehab 	if (status < 0)
20479a0bf528SMauro Carvalho Chehab 		goto error;
20489a0bf528SMauro Carvalho Chehab 
20499a0bf528SMauro Carvalho Chehab 	/* Configure DTO's */
2050cd7a67a4SMauro Carvalho Chehab 	if (static_clk) {
2051cd7a67a4SMauro Carvalho Chehab 		u32 bit_rate = 0;
20529a0bf528SMauro Carvalho Chehab 
20539a0bf528SMauro Carvalho Chehab 		/* Rational DTO for MCLK source (static MCLK rate),
20549a0bf528SMauro Carvalho Chehab 			Dynamic DTO for optimal grouping
20559a0bf528SMauro Carvalho Chehab 			(avoid intra-packet gaps),
20569a0bf528SMauro Carvalho Chehab 			DTO offset enable to sync TS burst with MSTRT */
2057cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
20589a0bf528SMauro Carvalho Chehab 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2059cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
20609a0bf528SMauro Carvalho Chehab 				FEC_OC_FCT_MODE_VIRT_ENA__M);
20619a0bf528SMauro Carvalho Chehab 
20629a0bf528SMauro Carvalho Chehab 		/* Check user defined bitrate */
2063cd7a67a4SMauro Carvalho Chehab 		bit_rate = max_bit_rate;
2064cd7a67a4SMauro Carvalho Chehab 		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
2065cd7a67a4SMauro Carvalho Chehab 			bit_rate = 75900000UL;
20669a0bf528SMauro Carvalho Chehab 		}
20679a0bf528SMauro Carvalho Chehab 		/* Rational DTO period:
20689a0bf528SMauro Carvalho Chehab 			dto_period = (Fsys / bitrate) - 2
20699a0bf528SMauro Carvalho Chehab 
2070cd7a67a4SMauro Carvalho Chehab 			result should be floored,
20719a0bf528SMauro Carvalho Chehab 			to make sure >= requested bitrate
20729a0bf528SMauro Carvalho Chehab 			*/
2073cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2074cd7a67a4SMauro Carvalho Chehab 						* 1000) / bit_rate);
2075cd7a67a4SMauro Carvalho Chehab 		if (fec_oc_dto_period <= 2)
2076cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period = 0;
20779a0bf528SMauro Carvalho Chehab 		else
2078cd7a67a4SMauro Carvalho Chehab 			fec_oc_dto_period -= 2;
2079cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 8;
20809a0bf528SMauro Carvalho Chehab 	} else {
2081cd7a67a4SMauro Carvalho Chehab 		/* (commonAttr->static_clk == false) => dynamic mode */
2082cd7a67a4SMauro Carvalho Chehab 		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2083cd7a67a4SMauro Carvalho Chehab 		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2084cd7a67a4SMauro Carvalho Chehab 		fec_oc_tmd_int_upd_rate = 5;
20859a0bf528SMauro Carvalho Chehab 	}
20869a0bf528SMauro Carvalho Chehab 
20879a0bf528SMauro Carvalho Chehab 	/* Write appropriate registers with requested configuration */
2088cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
20899a0bf528SMauro Carvalho Chehab 	if (status < 0)
20909a0bf528SMauro Carvalho Chehab 		goto error;
2091cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
20929a0bf528SMauro Carvalho Chehab 	if (status < 0)
20939a0bf528SMauro Carvalho Chehab 		goto error;
2094cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
20959a0bf528SMauro Carvalho Chehab 	if (status < 0)
20969a0bf528SMauro Carvalho Chehab 		goto error;
2097cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
20989a0bf528SMauro Carvalho Chehab 	if (status < 0)
20999a0bf528SMauro Carvalho Chehab 		goto error;
2100cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
21019a0bf528SMauro Carvalho Chehab 	if (status < 0)
21029a0bf528SMauro Carvalho Chehab 		goto error;
2103cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
21049a0bf528SMauro Carvalho Chehab 	if (status < 0)
21059a0bf528SMauro Carvalho Chehab 		goto error;
21069a0bf528SMauro Carvalho Chehab 
21079a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
2108cd7a67a4SMauro Carvalho Chehab 	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
21099a0bf528SMauro Carvalho Chehab 	if (status < 0)
21109a0bf528SMauro Carvalho Chehab 		goto error;
2111ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2112ab5060cdSMauro Carvalho Chehab 			 fec_oc_tmd_int_upd_rate);
21139a0bf528SMauro Carvalho Chehab 	if (status < 0)
21149a0bf528SMauro Carvalho Chehab 		goto error;
2115cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
21169a0bf528SMauro Carvalho Chehab error:
21179a0bf528SMauro Carvalho Chehab 	if (status < 0)
21183a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
21199a0bf528SMauro Carvalho Chehab 	return status;
21209a0bf528SMauro Carvalho Chehab }
21219a0bf528SMauro Carvalho Chehab 
2122cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state)
21239a0bf528SMauro Carvalho Chehab {
2124cd7a67a4SMauro Carvalho Chehab 	u16 fec_oc_reg_ipr_invert = 0;
21259a0bf528SMauro Carvalho Chehab 
21269a0bf528SMauro Carvalho Chehab 	/* Data mask for the output data byte */
2127cd7a67a4SMauro Carvalho Chehab 	u16 invert_data_mask =
21289a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
21299a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
21309a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
21319a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
21329a0bf528SMauro Carvalho Chehab 
21339a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21349a0bf528SMauro Carvalho Chehab 
21359a0bf528SMauro Carvalho Chehab 	/* Control selective inversion of output bits */
2136cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
21375a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_data)
2138cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= invert_data_mask;
2139cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
21405a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_err)
2141cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2142cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
21435a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_str)
2144cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2145cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
21465a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_val)
2147cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2148cd7a67a4SMauro Carvalho Chehab 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
21495a7f7b79SMauro Carvalho Chehab 	if (state->m_invert_clk)
2150cd7a67a4SMauro Carvalho Chehab 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
21519a0bf528SMauro Carvalho Chehab 
2152cd7a67a4SMauro Carvalho Chehab 	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
21539a0bf528SMauro Carvalho Chehab }
21549a0bf528SMauro Carvalho Chehab 
21559a0bf528SMauro Carvalho Chehab #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
21569a0bf528SMauro Carvalho Chehab 
2157cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state,
2158cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
21599a0bf528SMauro Carvalho Chehab {
21609a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
21619a0bf528SMauro Carvalho Chehab 	u16 data = 0;
2162cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_if_agc_settings;
21639a0bf528SMauro Carvalho Chehab 
21649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
21659a0bf528SMauro Carvalho Chehab 
2166cd7a67a4SMauro Carvalho Chehab 	if (p_agc_cfg == NULL)
21679a0bf528SMauro Carvalho Chehab 		goto error;
21689a0bf528SMauro Carvalho Chehab 
2169cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
21709a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
21719a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
21729a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
21739a0bf528SMauro Carvalho Chehab 		if (status < 0)
21749a0bf528SMauro Carvalho Chehab 			goto error;
21759a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
21769a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
21779a0bf528SMauro Carvalho Chehab 		if (status < 0)
21789a0bf528SMauro Carvalho Chehab 			goto error;
21799a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
21809a0bf528SMauro Carvalho Chehab 		if (status < 0)
21819a0bf528SMauro Carvalho Chehab 			goto error;
21829a0bf528SMauro Carvalho Chehab 
21839a0bf528SMauro Carvalho Chehab 		/* Enable SCU RF AGC loop */
21849a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
21859a0bf528SMauro Carvalho Chehab 
21869a0bf528SMauro Carvalho Chehab 		/* Polarity */
2187cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
21889a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21899a0bf528SMauro Carvalho Chehab 		else
21909a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21919a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
21929a0bf528SMauro Carvalho Chehab 		if (status < 0)
21939a0bf528SMauro Carvalho Chehab 			goto error;
21949a0bf528SMauro Carvalho Chehab 
21959a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
21969a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
21979a0bf528SMauro Carvalho Chehab 		if (status < 0)
21989a0bf528SMauro Carvalho Chehab 			goto error;
21999a0bf528SMauro Carvalho Chehab 
22009a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2201cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
22029a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
22039a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
22049a0bf528SMauro Carvalho Chehab 
22059a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
22069a0bf528SMauro Carvalho Chehab 		if (status < 0)
22079a0bf528SMauro Carvalho Chehab 			goto error;
22089a0bf528SMauro Carvalho Chehab 
2209cd7a67a4SMauro Carvalho Chehab 		if (is_dvbt(state))
2210cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2211cd7a67a4SMauro Carvalho Chehab 		else if (is_qam(state))
2212cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_qam_if_agc_cfg;
22139a0bf528SMauro Carvalho Chehab 		else
2214cd7a67a4SMauro Carvalho Chehab 			p_if_agc_settings = &state->m_atv_if_agc_cfg;
2215cd7a67a4SMauro Carvalho Chehab 		if (p_if_agc_settings == NULL) {
22169a0bf528SMauro Carvalho Chehab 			status = -EINVAL;
22179a0bf528SMauro Carvalho Chehab 			goto error;
22189a0bf528SMauro Carvalho Chehab 		}
22199a0bf528SMauro Carvalho Chehab 
22209a0bf528SMauro Carvalho Chehab 		/* Set TOP, only if IF-AGC is in AUTO mode */
222189fffac8SMauro Carvalho Chehab 		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
2222ab5060cdSMauro Carvalho Chehab 			status = write16(state,
2223ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2224ab5060cdSMauro Carvalho Chehab 					 p_agc_cfg->top);
22259a0bf528SMauro Carvalho Chehab 			if (status < 0)
22269a0bf528SMauro Carvalho Chehab 				goto error;
222789fffac8SMauro Carvalho Chehab 		}
22289a0bf528SMauro Carvalho Chehab 
22299a0bf528SMauro Carvalho Chehab 		/* Cut-Off current */
2230ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2231ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->cut_off_current);
22329a0bf528SMauro Carvalho Chehab 		if (status < 0)
22339a0bf528SMauro Carvalho Chehab 			goto error;
22349a0bf528SMauro Carvalho Chehab 
22359a0bf528SMauro Carvalho Chehab 		/* Max. output level */
2236ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2237ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->max_output_level);
22389a0bf528SMauro Carvalho Chehab 		if (status < 0)
22399a0bf528SMauro Carvalho Chehab 			goto error;
22409a0bf528SMauro Carvalho Chehab 
22419a0bf528SMauro Carvalho Chehab 		break;
22429a0bf528SMauro Carvalho Chehab 
22439a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
22449a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
22459a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22469a0bf528SMauro Carvalho Chehab 		if (status < 0)
22479a0bf528SMauro Carvalho Chehab 			goto error;
22489a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22499a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22509a0bf528SMauro Carvalho Chehab 		if (status < 0)
22519a0bf528SMauro Carvalho Chehab 			goto error;
22529a0bf528SMauro Carvalho Chehab 
22539a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22549a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22559a0bf528SMauro Carvalho Chehab 		if (status < 0)
22569a0bf528SMauro Carvalho Chehab 			goto error;
22579a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2258cd7a67a4SMauro Carvalho Chehab 		if (state->m_rf_agc_pol)
22599a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22609a0bf528SMauro Carvalho Chehab 		else
22619a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22629a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22639a0bf528SMauro Carvalho Chehab 		if (status < 0)
22649a0bf528SMauro Carvalho Chehab 			goto error;
22659a0bf528SMauro Carvalho Chehab 
22669a0bf528SMauro Carvalho Chehab 		/* SCU c.o.c. to 0, enabling full control range */
22679a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
22689a0bf528SMauro Carvalho Chehab 		if (status < 0)
22699a0bf528SMauro Carvalho Chehab 			goto error;
22709a0bf528SMauro Carvalho Chehab 
22719a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2272ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2273ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
22749a0bf528SMauro Carvalho Chehab 		if (status < 0)
22759a0bf528SMauro Carvalho Chehab 			goto error;
22769a0bf528SMauro Carvalho Chehab 		break;
22779a0bf528SMauro Carvalho Chehab 
22789a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
22799a0bf528SMauro Carvalho Chehab 		/* Disable RF AGC DAC */
22809a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22819a0bf528SMauro Carvalho Chehab 		if (status < 0)
22829a0bf528SMauro Carvalho Chehab 			goto error;
22839a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22849a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22859a0bf528SMauro Carvalho Chehab 		if (status < 0)
22869a0bf528SMauro Carvalho Chehab 			goto error;
22879a0bf528SMauro Carvalho Chehab 
22889a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
22899a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22909a0bf528SMauro Carvalho Chehab 		if (status < 0)
22919a0bf528SMauro Carvalho Chehab 			goto error;
22929a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22939a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22949a0bf528SMauro Carvalho Chehab 		if (status < 0)
22959a0bf528SMauro Carvalho Chehab 			goto error;
22969a0bf528SMauro Carvalho Chehab 		break;
22979a0bf528SMauro Carvalho Chehab 
22989a0bf528SMauro Carvalho Chehab 	default:
22999a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
23009a0bf528SMauro Carvalho Chehab 
23019a0bf528SMauro Carvalho Chehab 	}
23029a0bf528SMauro Carvalho Chehab error:
23039a0bf528SMauro Carvalho Chehab 	if (status < 0)
23043a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
23059a0bf528SMauro Carvalho Chehab 	return status;
23069a0bf528SMauro Carvalho Chehab }
23079a0bf528SMauro Carvalho Chehab 
23089a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
23099a0bf528SMauro Carvalho Chehab 
2310cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state,
2311cd7a67a4SMauro Carvalho Chehab 		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
23129a0bf528SMauro Carvalho Chehab {
23139a0bf528SMauro Carvalho Chehab 	u16 data = 0;
23149a0bf528SMauro Carvalho Chehab 	int status = 0;
2315cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc *p_rf_agc_settings;
23169a0bf528SMauro Carvalho Chehab 
23179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
23189a0bf528SMauro Carvalho Chehab 
2319cd7a67a4SMauro Carvalho Chehab 	switch (p_agc_cfg->ctrl_mode) {
23209a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
23219a0bf528SMauro Carvalho Chehab 
23229a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23239a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23249a0bf528SMauro Carvalho Chehab 		if (status < 0)
23259a0bf528SMauro Carvalho Chehab 			goto error;
23269a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23279a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23289a0bf528SMauro Carvalho Chehab 		if (status < 0)
23299a0bf528SMauro Carvalho Chehab 			goto error;
23309a0bf528SMauro Carvalho Chehab 
23319a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23329a0bf528SMauro Carvalho Chehab 		if (status < 0)
23339a0bf528SMauro Carvalho Chehab 			goto error;
23349a0bf528SMauro Carvalho Chehab 
23359a0bf528SMauro Carvalho Chehab 		/* Enable SCU IF AGC loop */
23369a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23379a0bf528SMauro Carvalho Chehab 
23389a0bf528SMauro Carvalho Chehab 		/* Polarity */
2339cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23409a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23419a0bf528SMauro Carvalho Chehab 		else
23429a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23439a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23449a0bf528SMauro Carvalho Chehab 		if (status < 0)
23459a0bf528SMauro Carvalho Chehab 			goto error;
23469a0bf528SMauro Carvalho Chehab 
23479a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
23489a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
23499a0bf528SMauro Carvalho Chehab 		if (status < 0)
23509a0bf528SMauro Carvalho Chehab 			goto error;
23519a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2352cd7a67a4SMauro Carvalho Chehab 		data |= (~(p_agc_cfg->speed <<
23539a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
23549a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
23559a0bf528SMauro Carvalho Chehab 
23569a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
23579a0bf528SMauro Carvalho Chehab 		if (status < 0)
23589a0bf528SMauro Carvalho Chehab 			goto error;
23599a0bf528SMauro Carvalho Chehab 
2360cd7a67a4SMauro Carvalho Chehab 		if (is_qam(state))
2361cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
23629a0bf528SMauro Carvalho Chehab 		else
2363cd7a67a4SMauro Carvalho Chehab 			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2364cd7a67a4SMauro Carvalho Chehab 		if (p_rf_agc_settings == NULL)
23659a0bf528SMauro Carvalho Chehab 			return -1;
23669a0bf528SMauro Carvalho Chehab 		/* Restore TOP */
2367ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2368ab5060cdSMauro Carvalho Chehab 				 p_rf_agc_settings->top);
23699a0bf528SMauro Carvalho Chehab 		if (status < 0)
23709a0bf528SMauro Carvalho Chehab 			goto error;
23719a0bf528SMauro Carvalho Chehab 		break;
23729a0bf528SMauro Carvalho Chehab 
23739a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
23749a0bf528SMauro Carvalho Chehab 
23759a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23769a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23779a0bf528SMauro Carvalho Chehab 		if (status < 0)
23789a0bf528SMauro Carvalho Chehab 			goto error;
23799a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23809a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23819a0bf528SMauro Carvalho Chehab 		if (status < 0)
23829a0bf528SMauro Carvalho Chehab 			goto error;
23839a0bf528SMauro Carvalho Chehab 
23849a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23859a0bf528SMauro Carvalho Chehab 		if (status < 0)
23869a0bf528SMauro Carvalho Chehab 			goto error;
23879a0bf528SMauro Carvalho Chehab 
23889a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
23899a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23909a0bf528SMauro Carvalho Chehab 
23919a0bf528SMauro Carvalho Chehab 		/* Polarity */
2392cd7a67a4SMauro Carvalho Chehab 		if (state->m_if_agc_pol)
23939a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23949a0bf528SMauro Carvalho Chehab 		else
23959a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23969a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23979a0bf528SMauro Carvalho Chehab 		if (status < 0)
23989a0bf528SMauro Carvalho Chehab 			goto error;
23999a0bf528SMauro Carvalho Chehab 
24009a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
2401ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2402ab5060cdSMauro Carvalho Chehab 				 p_agc_cfg->output_level);
24039a0bf528SMauro Carvalho Chehab 		if (status < 0)
24049a0bf528SMauro Carvalho Chehab 			goto error;
24059a0bf528SMauro Carvalho Chehab 		break;
24069a0bf528SMauro Carvalho Chehab 
24079a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
24089a0bf528SMauro Carvalho Chehab 
24099a0bf528SMauro Carvalho Chehab 		/* Disable If AGC DAC */
24109a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
24119a0bf528SMauro Carvalho Chehab 		if (status < 0)
24129a0bf528SMauro Carvalho Chehab 			goto error;
24139a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
24149a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
24159a0bf528SMauro Carvalho Chehab 		if (status < 0)
24169a0bf528SMauro Carvalho Chehab 			goto error;
24179a0bf528SMauro Carvalho Chehab 
24189a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
24199a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
24209a0bf528SMauro Carvalho Chehab 		if (status < 0)
24219a0bf528SMauro Carvalho Chehab 			goto error;
24229a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24239a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24249a0bf528SMauro Carvalho Chehab 		if (status < 0)
24259a0bf528SMauro Carvalho Chehab 			goto error;
24269a0bf528SMauro Carvalho Chehab 		break;
2427cd7a67a4SMauro Carvalho Chehab 	}		/* switch (agcSettingsIf->ctrl_mode) */
24289a0bf528SMauro Carvalho Chehab 
24299a0bf528SMauro Carvalho Chehab 	/* always set the top to support
24309a0bf528SMauro Carvalho Chehab 		configurations without if-loop */
2431cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
24329a0bf528SMauro Carvalho Chehab error:
24339a0bf528SMauro Carvalho Chehab 	if (status < 0)
24343a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24359a0bf528SMauro Carvalho Chehab 	return status;
24369a0bf528SMauro Carvalho Chehab }
24379a0bf528SMauro Carvalho Chehab 
2438cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state,
2439cd7a67a4SMauro Carvalho Chehab 			       s32 *p_signal_to_noise)
24409a0bf528SMauro Carvalho Chehab {
24419a0bf528SMauro Carvalho Chehab 	int status = 0;
2442cd7a67a4SMauro Carvalho Chehab 	u16 qam_sl_err_power = 0;	/* accum. error between
24439a0bf528SMauro Carvalho Chehab 					raw and sliced symbols */
2444cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
24459a0bf528SMauro Carvalho Chehab 					QAM modulation */
2446cd7a67a4SMauro Carvalho Chehab 	u32 qam_sl_mer = 0;	/* QAM MER */
24479a0bf528SMauro Carvalho Chehab 
24489a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
24499a0bf528SMauro Carvalho Chehab 
24509a0bf528SMauro Carvalho Chehab 	/* MER calculation */
24519a0bf528SMauro Carvalho Chehab 
24529a0bf528SMauro Carvalho Chehab 	/* get the register value needed for MER */
2453cd7a67a4SMauro Carvalho Chehab 	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
24549a0bf528SMauro Carvalho Chehab 	if (status < 0) {
24553a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
24569a0bf528SMauro Carvalho Chehab 		return -EINVAL;
24579a0bf528SMauro Carvalho Chehab 	}
24589a0bf528SMauro Carvalho Chehab 
24599a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
24609a0bf528SMauro Carvalho Chehab 	case QAM_16:
2461cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
24629a0bf528SMauro Carvalho Chehab 		break;
24639a0bf528SMauro Carvalho Chehab 	case QAM_32:
2464cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
24659a0bf528SMauro Carvalho Chehab 		break;
24669a0bf528SMauro Carvalho Chehab 	case QAM_64:
2467cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
24689a0bf528SMauro Carvalho Chehab 		break;
24699a0bf528SMauro Carvalho Chehab 	case QAM_128:
2470cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
24719a0bf528SMauro Carvalho Chehab 		break;
24729a0bf528SMauro Carvalho Chehab 	default:
24739a0bf528SMauro Carvalho Chehab 	case QAM_256:
2474cd7a67a4SMauro Carvalho Chehab 		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
24759a0bf528SMauro Carvalho Chehab 		break;
24769a0bf528SMauro Carvalho Chehab 	}
24779a0bf528SMauro Carvalho Chehab 
2478cd7a67a4SMauro Carvalho Chehab 	if (qam_sl_err_power > 0) {
2479cd7a67a4SMauro Carvalho Chehab 		qam_sl_mer = log10times100(qam_sl_sig_power) -
2480cd7a67a4SMauro Carvalho Chehab 			log10times100((u32) qam_sl_err_power);
24819a0bf528SMauro Carvalho Chehab 	}
2482cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = qam_sl_mer;
24839a0bf528SMauro Carvalho Chehab 
24849a0bf528SMauro Carvalho Chehab 	return status;
24859a0bf528SMauro Carvalho Chehab }
24869a0bf528SMauro Carvalho Chehab 
2487cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state,
2488cd7a67a4SMauro Carvalho Chehab 				s32 *p_signal_to_noise)
24899a0bf528SMauro Carvalho Chehab {
24909a0bf528SMauro Carvalho Chehab 	int status;
2491cd7a67a4SMauro Carvalho Chehab 	u16 reg_data = 0;
2492cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_i = 0;
2493cd7a67a4SMauro Carvalho Chehab 	u32 eq_reg_td_sqr_err_q = 0;
2494cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_sqr_err_exp = 0;
2495cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_tps_pwr_ofs = 0;
2496cd7a67a4SMauro Carvalho Chehab 	u16 eq_reg_td_req_smb_cnt = 0;
2497cd7a67a4SMauro Carvalho Chehab 	u32 tps_cnt = 0;
2498cd7a67a4SMauro Carvalho Chehab 	u32 sqr_err_iq = 0;
24999a0bf528SMauro Carvalho Chehab 	u32 a = 0;
25009a0bf528SMauro Carvalho Chehab 	u32 b = 0;
25019a0bf528SMauro Carvalho Chehab 	u32 c = 0;
2502cd7a67a4SMauro Carvalho Chehab 	u32 i_mer = 0;
2503cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
25049a0bf528SMauro Carvalho Chehab 
25059a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25069a0bf528SMauro Carvalho Chehab 
2507ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2508ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_tps_pwr_ofs);
25099a0bf528SMauro Carvalho Chehab 	if (status < 0)
25109a0bf528SMauro Carvalho Chehab 		goto error;
2511ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2512ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_req_smb_cnt);
25139a0bf528SMauro Carvalho Chehab 	if (status < 0)
25149a0bf528SMauro Carvalho Chehab 		goto error;
2515ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2516ab5060cdSMauro Carvalho Chehab 			&eq_reg_td_sqr_err_exp);
25179a0bf528SMauro Carvalho Chehab 	if (status < 0)
25189a0bf528SMauro Carvalho Chehab 		goto error;
2519ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2520ab5060cdSMauro Carvalho Chehab 			&reg_data);
25219a0bf528SMauro Carvalho Chehab 	if (status < 0)
25229a0bf528SMauro Carvalho Chehab 		goto error;
25239a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_I operational range */
2524cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_i = (u32) reg_data;
2525cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2526cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2527cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_i += 0x00010000UL;
25289a0bf528SMauro Carvalho Chehab 	}
2529cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
25309a0bf528SMauro Carvalho Chehab 	if (status < 0)
25319a0bf528SMauro Carvalho Chehab 		goto error;
25329a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_Q operational range */
2533cd7a67a4SMauro Carvalho Chehab 	eq_reg_td_sqr_err_q = (u32) reg_data;
2534cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_sqr_err_exp > 11) &&
2535cd7a67a4SMauro Carvalho Chehab 		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
2536cd7a67a4SMauro Carvalho Chehab 		eq_reg_td_sqr_err_q += 0x00010000UL;
25379a0bf528SMauro Carvalho Chehab 
2538ab5060cdSMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2539ab5060cdSMauro Carvalho Chehab 			&transmission_params);
25409a0bf528SMauro Carvalho Chehab 	if (status < 0)
25419a0bf528SMauro Carvalho Chehab 		goto error;
25429a0bf528SMauro Carvalho Chehab 
25439a0bf528SMauro Carvalho Chehab 	/* Check input data for MER */
25449a0bf528SMauro Carvalho Chehab 
25459a0bf528SMauro Carvalho Chehab 	/* MER calculation (in 0.1 dB) without math.h */
2546cd7a67a4SMauro Carvalho Chehab 	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2547cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
2548cd7a67a4SMauro Carvalho Chehab 	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
25499a0bf528SMauro Carvalho Chehab 		/* No error at all, this must be the HW reset value
25509a0bf528SMauro Carvalho Chehab 			* Apparently no first measurement yet
25519a0bf528SMauro Carvalho Chehab 			* Set MER to 0.0 */
2552cd7a67a4SMauro Carvalho Chehab 		i_mer = 0;
25539a0bf528SMauro Carvalho Chehab 	} else {
2554cd7a67a4SMauro Carvalho Chehab 		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2555cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_sqr_err_exp;
2556cd7a67a4SMauro Carvalho Chehab 		if ((transmission_params &
25579a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
25589a0bf528SMauro Carvalho Chehab 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2559cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 17;
25609a0bf528SMauro Carvalho Chehab 		else
2561cd7a67a4SMauro Carvalho Chehab 			tps_cnt = 68;
25629a0bf528SMauro Carvalho Chehab 
25639a0bf528SMauro Carvalho Chehab 		/* IMER = 100 * log10 (x)
2564cd7a67a4SMauro Carvalho Chehab 			where x = (eq_reg_td_tps_pwr_ofs^2 *
2565cd7a67a4SMauro Carvalho Chehab 			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
25669a0bf528SMauro Carvalho Chehab 
25679a0bf528SMauro Carvalho Chehab 			=> IMER = a + b -c
2568cd7a67a4SMauro Carvalho Chehab 			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2569cd7a67a4SMauro Carvalho Chehab 			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2570cd7a67a4SMauro Carvalho Chehab 			c = 100 * log10 (sqr_err_iq)
25719a0bf528SMauro Carvalho Chehab 			*/
25729a0bf528SMauro Carvalho Chehab 
25739a0bf528SMauro Carvalho Chehab 		/* log(x) x = 9bits * 9bits->18 bits  */
2574cd7a67a4SMauro Carvalho Chehab 		a = log10times100(eq_reg_td_tps_pwr_ofs *
2575cd7a67a4SMauro Carvalho Chehab 					eq_reg_td_tps_pwr_ofs);
25769a0bf528SMauro Carvalho Chehab 		/* log(x) x = 16bits * 7bits->23 bits  */
2577cd7a67a4SMauro Carvalho Chehab 		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
25789a0bf528SMauro Carvalho Chehab 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
2579cd7a67a4SMauro Carvalho Chehab 		c = log10times100(sqr_err_iq);
25809a0bf528SMauro Carvalho Chehab 
2581cd7a67a4SMauro Carvalho Chehab 		i_mer = a + b - c;
25829a0bf528SMauro Carvalho Chehab 	}
2583cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = i_mer;
25849a0bf528SMauro Carvalho Chehab 
25859a0bf528SMauro Carvalho Chehab error:
25869a0bf528SMauro Carvalho Chehab 	if (status < 0)
25873a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
25889a0bf528SMauro Carvalho Chehab 	return status;
25899a0bf528SMauro Carvalho Chehab }
25909a0bf528SMauro Carvalho Chehab 
2591cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
25929a0bf528SMauro Carvalho Chehab {
25939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25949a0bf528SMauro Carvalho Chehab 
2595cd7a67a4SMauro Carvalho Chehab 	*p_signal_to_noise = 0;
2596cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
25979a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2598cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
25999a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
26009a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
2601cd7a67a4SMauro Carvalho Chehab 		return get_qam_signal_to_noise(state, p_signal_to_noise);
26029a0bf528SMauro Carvalho Chehab 	default:
26039a0bf528SMauro Carvalho Chehab 		break;
26049a0bf528SMauro Carvalho Chehab 	}
26059a0bf528SMauro Carvalho Chehab 	return 0;
26069a0bf528SMauro Carvalho Chehab }
26079a0bf528SMauro Carvalho Chehab 
26089a0bf528SMauro Carvalho Chehab #if 0
2609cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
26109a0bf528SMauro Carvalho Chehab {
26119a0bf528SMauro Carvalho Chehab 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
26129a0bf528SMauro Carvalho Chehab 	int status = 0;
26139a0bf528SMauro Carvalho Chehab 
26149a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26159a0bf528SMauro Carvalho Chehab 
26169a0bf528SMauro Carvalho Chehab 	static s32 QE_SN[] = {
26179a0bf528SMauro Carvalho Chehab 		51,		/* QPSK 1/2 */
26189a0bf528SMauro Carvalho Chehab 		69,		/* QPSK 2/3 */
26199a0bf528SMauro Carvalho Chehab 		79,		/* QPSK 3/4 */
26209a0bf528SMauro Carvalho Chehab 		89,		/* QPSK 5/6 */
26219a0bf528SMauro Carvalho Chehab 		97,		/* QPSK 7/8 */
26229a0bf528SMauro Carvalho Chehab 		108,		/* 16-QAM 1/2 */
26239a0bf528SMauro Carvalho Chehab 		131,		/* 16-QAM 2/3 */
26249a0bf528SMauro Carvalho Chehab 		146,		/* 16-QAM 3/4 */
26259a0bf528SMauro Carvalho Chehab 		156,		/* 16-QAM 5/6 */
26269a0bf528SMauro Carvalho Chehab 		160,		/* 16-QAM 7/8 */
26279a0bf528SMauro Carvalho Chehab 		165,		/* 64-QAM 1/2 */
26289a0bf528SMauro Carvalho Chehab 		187,		/* 64-QAM 2/3 */
26299a0bf528SMauro Carvalho Chehab 		202,		/* 64-QAM 3/4 */
26309a0bf528SMauro Carvalho Chehab 		216,		/* 64-QAM 5/6 */
26319a0bf528SMauro Carvalho Chehab 		225,		/* 64-QAM 7/8 */
26329a0bf528SMauro Carvalho Chehab 	};
26339a0bf528SMauro Carvalho Chehab 
2634cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26359a0bf528SMauro Carvalho Chehab 
26369a0bf528SMauro Carvalho Chehab 	do {
2637cd7a67a4SMauro Carvalho Chehab 		s32 signal_to_noise = 0;
2638cd7a67a4SMauro Carvalho Chehab 		u16 constellation = 0;
2639cd7a67a4SMauro Carvalho Chehab 		u16 code_rate = 0;
2640cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel;
2641cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality;
26429a0bf528SMauro Carvalho Chehab 
2643cd7a67a4SMauro Carvalho Chehab 		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
26449a0bf528SMauro Carvalho Chehab 		if (status < 0)
26459a0bf528SMauro Carvalho Chehab 			break;
2646ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2647ab5060cdSMauro Carvalho Chehab 				&constellation);
26489a0bf528SMauro Carvalho Chehab 		if (status < 0)
26499a0bf528SMauro Carvalho Chehab 			break;
2650cd7a67a4SMauro Carvalho Chehab 		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
26519a0bf528SMauro Carvalho Chehab 
2652ab5060cdSMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2653ab5060cdSMauro Carvalho Chehab 				&code_rate);
26549a0bf528SMauro Carvalho Chehab 		if (status < 0)
26559a0bf528SMauro Carvalho Chehab 			break;
2656cd7a67a4SMauro Carvalho Chehab 		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
26579a0bf528SMauro Carvalho Chehab 
2658cd7a67a4SMauro Carvalho Chehab 		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2659cd7a67a4SMauro Carvalho Chehab 		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
26609a0bf528SMauro Carvalho Chehab 			break;
2661cd7a67a4SMauro Carvalho Chehab 		signal_to_noise_rel = signal_to_noise -
2662cd7a67a4SMauro Carvalho Chehab 		    QE_SN[constellation * 5 + code_rate];
2663cd7a67a4SMauro Carvalho Chehab 		ber_quality = 100;
26649a0bf528SMauro Carvalho Chehab 
2665cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2666cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2667cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2668cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2669cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
26709a0bf528SMauro Carvalho Chehab 		else
2671cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
26729a0bf528SMauro Carvalho Chehab 	} while (0);
26739a0bf528SMauro Carvalho Chehab 	return 0;
26749a0bf528SMauro Carvalho Chehab };
26759a0bf528SMauro Carvalho Chehab 
2676cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
26779a0bf528SMauro Carvalho Chehab {
26789a0bf528SMauro Carvalho Chehab 	int status = 0;
2679cd7a67a4SMauro Carvalho Chehab 	*p_quality = 0;
26809a0bf528SMauro Carvalho Chehab 
26819a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26829a0bf528SMauro Carvalho Chehab 
26839a0bf528SMauro Carvalho Chehab 	do {
2684cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise = 0;
2685cd7a67a4SMauro Carvalho Chehab 		u32 ber_quality = 100;
2686cd7a67a4SMauro Carvalho Chehab 		u32 signal_to_noise_rel = 0;
26879a0bf528SMauro Carvalho Chehab 
2688cd7a67a4SMauro Carvalho Chehab 		status = get_qam_signal_to_noise(state, &signal_to_noise);
26899a0bf528SMauro Carvalho Chehab 		if (status < 0)
26909a0bf528SMauro Carvalho Chehab 			break;
26919a0bf528SMauro Carvalho Chehab 
26929a0bf528SMauro Carvalho Chehab 		switch (state->props.modulation) {
26939a0bf528SMauro Carvalho Chehab 		case QAM_16:
2694cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 200;
26959a0bf528SMauro Carvalho Chehab 			break;
26969a0bf528SMauro Carvalho Chehab 		case QAM_32:
2697cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 230;
26989a0bf528SMauro Carvalho Chehab 			break;	/* Not in NorDig */
26999a0bf528SMauro Carvalho Chehab 		case QAM_64:
2700cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 260;
27019a0bf528SMauro Carvalho Chehab 			break;
27029a0bf528SMauro Carvalho Chehab 		case QAM_128:
2703cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 290;
27049a0bf528SMauro Carvalho Chehab 			break;
27059a0bf528SMauro Carvalho Chehab 		default:
27069a0bf528SMauro Carvalho Chehab 		case QAM_256:
2707cd7a67a4SMauro Carvalho Chehab 			signal_to_noise_rel = signal_to_noise - 320;
27089a0bf528SMauro Carvalho Chehab 			break;
27099a0bf528SMauro Carvalho Chehab 		}
27109a0bf528SMauro Carvalho Chehab 
2711cd7a67a4SMauro Carvalho Chehab 		if (signal_to_noise_rel < -70)
2712cd7a67a4SMauro Carvalho Chehab 			*p_quality = 0;
2713cd7a67a4SMauro Carvalho Chehab 		else if (signal_to_noise_rel < 30)
2714cd7a67a4SMauro Carvalho Chehab 			*p_quality = ((signal_to_noise_rel + 70) *
2715cd7a67a4SMauro Carvalho Chehab 				     ber_quality) / 100;
27169a0bf528SMauro Carvalho Chehab 		else
2717cd7a67a4SMauro Carvalho Chehab 			*p_quality = ber_quality;
27189a0bf528SMauro Carvalho Chehab 	} while (0);
27199a0bf528SMauro Carvalho Chehab 
27209a0bf528SMauro Carvalho Chehab 	return status;
27219a0bf528SMauro Carvalho Chehab }
27229a0bf528SMauro Carvalho Chehab 
2723cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality)
27249a0bf528SMauro Carvalho Chehab {
27259a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27269a0bf528SMauro Carvalho Chehab 
2727cd7a67a4SMauro Carvalho Chehab 	switch (state->m_operation_mode) {
27289a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
2729cd7a67a4SMauro Carvalho Chehab 		return get_dvbt_quality(state, p_quality);
27309a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
2731cd7a67a4SMauro Carvalho Chehab 		return get_dvbc_quality(state, p_quality);
27329a0bf528SMauro Carvalho Chehab 	default:
27339a0bf528SMauro Carvalho Chehab 		break;
27349a0bf528SMauro Carvalho Chehab 	}
27359a0bf528SMauro Carvalho Chehab 
27369a0bf528SMauro Carvalho Chehab 	return 0;
27379a0bf528SMauro Carvalho Chehab }
27389a0bf528SMauro Carvalho Chehab #endif
27399a0bf528SMauro Carvalho Chehab 
27409a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
27419a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
27429a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A   0x420060
27439a0bf528SMauro Carvalho Chehab 
27449a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
27459a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
27469a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
27479a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
27489a0bf528SMauro Carvalho Chehab 
27499a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
27509a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
27519a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
27529a0bf528SMauro Carvalho Chehab 
2753cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
27549a0bf528SMauro Carvalho Chehab {
27559a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27569a0bf528SMauro Carvalho Chehab 
27579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27589a0bf528SMauro Carvalho Chehab 
2759cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
27609a0bf528SMauro Carvalho Chehab 		return 0;
2761cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_POWERED_DOWN)
27629a0bf528SMauro Carvalho Chehab 		goto error;
27639a0bf528SMauro Carvalho Chehab 
27649a0bf528SMauro Carvalho Chehab 	if (state->no_i2c_bridge)
27659a0bf528SMauro Carvalho Chehab 		return 0;
27669a0bf528SMauro Carvalho Chehab 
2767ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2768ab5060cdSMauro Carvalho Chehab 			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
27699a0bf528SMauro Carvalho Chehab 	if (status < 0)
27709a0bf528SMauro Carvalho Chehab 		goto error;
2771cd7a67a4SMauro Carvalho Chehab 	if (b_enable_bridge) {
2772ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2773ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
27749a0bf528SMauro Carvalho Chehab 		if (status < 0)
27759a0bf528SMauro Carvalho Chehab 			goto error;
27769a0bf528SMauro Carvalho Chehab 	} else {
2777ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2778ab5060cdSMauro Carvalho Chehab 				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
27799a0bf528SMauro Carvalho Chehab 		if (status < 0)
27809a0bf528SMauro Carvalho Chehab 			goto error;
27819a0bf528SMauro Carvalho Chehab 	}
27829a0bf528SMauro Carvalho Chehab 
2783b1cf2019SHans Verkuil 	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
27849a0bf528SMauro Carvalho Chehab 
27859a0bf528SMauro Carvalho Chehab error:
27869a0bf528SMauro Carvalho Chehab 	if (status < 0)
27873a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
27889a0bf528SMauro Carvalho Chehab 	return status;
27899a0bf528SMauro Carvalho Chehab }
27909a0bf528SMauro Carvalho Chehab 
2791cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state,
2792cd7a67a4SMauro Carvalho Chehab 		     struct s_cfg_pre_saw *p_pre_saw_cfg)
27939a0bf528SMauro Carvalho Chehab {
27949a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
27959a0bf528SMauro Carvalho Chehab 
27969a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27979a0bf528SMauro Carvalho Chehab 
2798cd7a67a4SMauro Carvalho Chehab 	if ((p_pre_saw_cfg == NULL)
2799cd7a67a4SMauro Carvalho Chehab 	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
28009a0bf528SMauro Carvalho Chehab 		goto error;
28019a0bf528SMauro Carvalho Chehab 
2802cd7a67a4SMauro Carvalho Chehab 	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
28039a0bf528SMauro Carvalho Chehab error:
28049a0bf528SMauro Carvalho Chehab 	if (status < 0)
28053a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28069a0bf528SMauro Carvalho Chehab 	return status;
28079a0bf528SMauro Carvalho Chehab }
28089a0bf528SMauro Carvalho Chehab 
2809cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2810cd7a67a4SMauro Carvalho Chehab 		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
28119a0bf528SMauro Carvalho Chehab {
2812cd7a67a4SMauro Carvalho Chehab 	u16 bl_status = 0;
2813cd7a67a4SMauro Carvalho Chehab 	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2814cd7a67a4SMauro Carvalho Chehab 	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
28159a0bf528SMauro Carvalho Chehab 	int status;
28169a0bf528SMauro Carvalho Chehab 	unsigned long end;
28179a0bf528SMauro Carvalho Chehab 
28189a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28199a0bf528SMauro Carvalho Chehab 
28209a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
28219a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
28229a0bf528SMauro Carvalho Chehab 	if (status < 0)
28239a0bf528SMauro Carvalho Chehab 		goto error;
28249a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
28259a0bf528SMauro Carvalho Chehab 	if (status < 0)
28269a0bf528SMauro Carvalho Chehab 		goto error;
28279a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
28289a0bf528SMauro Carvalho Chehab 	if (status < 0)
28299a0bf528SMauro Carvalho Chehab 		goto error;
2830cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
28319a0bf528SMauro Carvalho Chehab 	if (status < 0)
28329a0bf528SMauro Carvalho Chehab 		goto error;
2833cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
28349a0bf528SMauro Carvalho Chehab 	if (status < 0)
28359a0bf528SMauro Carvalho Chehab 		goto error;
28369a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
28379a0bf528SMauro Carvalho Chehab 	if (status < 0)
28389a0bf528SMauro Carvalho Chehab 		goto error;
28399a0bf528SMauro Carvalho Chehab 
2840cd7a67a4SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(time_out);
28419a0bf528SMauro Carvalho Chehab 	do {
2842cd7a67a4SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &bl_status);
28439a0bf528SMauro Carvalho Chehab 		if (status < 0)
28449a0bf528SMauro Carvalho Chehab 			goto error;
2845cd7a67a4SMauro Carvalho Chehab 	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
2846cd7a67a4SMauro Carvalho Chehab 	if (bl_status == 0x1) {
28473a4398f5SMauro Carvalho Chehab 		pr_err("SIO not ready\n");
28489a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
28499a0bf528SMauro Carvalho Chehab 		goto error2;
28509a0bf528SMauro Carvalho Chehab 	}
28519a0bf528SMauro Carvalho Chehab error:
28529a0bf528SMauro Carvalho Chehab 	if (status < 0)
28533a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28549a0bf528SMauro Carvalho Chehab error2:
28559a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
28569a0bf528SMauro Carvalho Chehab 	return status;
28579a0bf528SMauro Carvalho Chehab 
28589a0bf528SMauro Carvalho Chehab }
28599a0bf528SMauro Carvalho Chehab 
2860cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count)
28619a0bf528SMauro Carvalho Chehab {
28629a0bf528SMauro Carvalho Chehab 	u16 data = 0;
28639a0bf528SMauro Carvalho Chehab 	int status;
28649a0bf528SMauro Carvalho Chehab 
28659a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28669a0bf528SMauro Carvalho Chehab 
2867cd7a67a4SMauro Carvalho Chehab 	/* start measurement */
28689a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
28699a0bf528SMauro Carvalho Chehab 	if (status < 0)
28709a0bf528SMauro Carvalho Chehab 		goto error;
28719a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 1);
28729a0bf528SMauro Carvalho Chehab 	if (status < 0)
28739a0bf528SMauro Carvalho Chehab 		goto error;
28749a0bf528SMauro Carvalho Chehab 
28759a0bf528SMauro Carvalho Chehab 	*count = 0;
28769a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE0__A, &data);
28779a0bf528SMauro Carvalho Chehab 	if (status < 0)
28789a0bf528SMauro Carvalho Chehab 		goto error;
28799a0bf528SMauro Carvalho Chehab 	if (data == 127)
28809a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28819a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE1__A, &data);
28829a0bf528SMauro Carvalho Chehab 	if (status < 0)
28839a0bf528SMauro Carvalho Chehab 		goto error;
28849a0bf528SMauro Carvalho Chehab 	if (data == 127)
28859a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28869a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE2__A, &data);
28879a0bf528SMauro Carvalho Chehab 	if (status < 0)
28889a0bf528SMauro Carvalho Chehab 		goto error;
28899a0bf528SMauro Carvalho Chehab 	if (data == 127)
28909a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
28919a0bf528SMauro Carvalho Chehab 
28929a0bf528SMauro Carvalho Chehab error:
28939a0bf528SMauro Carvalho Chehab 	if (status < 0)
28943a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
28959a0bf528SMauro Carvalho Chehab 	return status;
28969a0bf528SMauro Carvalho Chehab }
28979a0bf528SMauro Carvalho Chehab 
2898cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state)
28999a0bf528SMauro Carvalho Chehab {
29009a0bf528SMauro Carvalho Chehab 	u16 count = 0;
29019a0bf528SMauro Carvalho Chehab 	int status;
29029a0bf528SMauro Carvalho Chehab 
29039a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29049a0bf528SMauro Carvalho Chehab 
2905cd7a67a4SMauro Carvalho Chehab 	status = adc_sync_measurement(state, &count);
29069a0bf528SMauro Carvalho Chehab 	if (status < 0)
29079a0bf528SMauro Carvalho Chehab 		goto error;
29089a0bf528SMauro Carvalho Chehab 
29099a0bf528SMauro Carvalho Chehab 	if (count == 1) {
291039c1cb2bSJonathan McCrohan 		/* Try sampling on a different edge */
2911cd7a67a4SMauro Carvalho Chehab 		u16 clk_neg = 0;
29129a0bf528SMauro Carvalho Chehab 
2913cd7a67a4SMauro Carvalho Chehab 		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
29149a0bf528SMauro Carvalho Chehab 		if (status < 0)
29159a0bf528SMauro Carvalho Chehab 			goto error;
2916cd7a67a4SMauro Carvalho Chehab 		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
29179a0bf528SMauro Carvalho Chehab 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2918cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2919cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
29209a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
29219a0bf528SMauro Carvalho Chehab 		} else {
2922cd7a67a4SMauro Carvalho Chehab 			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2923cd7a67a4SMauro Carvalho Chehab 			clk_neg |=
29249a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
29259a0bf528SMauro Carvalho Chehab 		}
2926cd7a67a4SMauro Carvalho Chehab 		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
29279a0bf528SMauro Carvalho Chehab 		if (status < 0)
29289a0bf528SMauro Carvalho Chehab 			goto error;
2929cd7a67a4SMauro Carvalho Chehab 		status = adc_sync_measurement(state, &count);
29309a0bf528SMauro Carvalho Chehab 		if (status < 0)
29319a0bf528SMauro Carvalho Chehab 			goto error;
29329a0bf528SMauro Carvalho Chehab 	}
29339a0bf528SMauro Carvalho Chehab 
29349a0bf528SMauro Carvalho Chehab 	if (count < 2)
29359a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
29369a0bf528SMauro Carvalho Chehab error:
29379a0bf528SMauro Carvalho Chehab 	if (status < 0)
29383a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
29399a0bf528SMauro Carvalho Chehab 	return status;
29409a0bf528SMauro Carvalho Chehab }
29419a0bf528SMauro Carvalho Chehab 
2942cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state,
2943cd7a67a4SMauro Carvalho Chehab 			       u16 intermediate_freqk_hz,
2944cd7a67a4SMauro Carvalho Chehab 			       s32 tuner_freq_offset, bool is_dtv)
29459a0bf528SMauro Carvalho Chehab {
2946cd7a67a4SMauro Carvalho Chehab 	bool select_pos_image = false;
2947cd7a67a4SMauro Carvalho Chehab 	u32 rf_freq_residual = tuner_freq_offset;
2948cd7a67a4SMauro Carvalho Chehab 	u32 fm_frequency_shift = 0;
2949cd7a67a4SMauro Carvalho Chehab 	bool tuner_mirror = !state->m_b_mirror_freq_spect;
2950cd7a67a4SMauro Carvalho Chehab 	u32 adc_freq;
2951cd7a67a4SMauro Carvalho Chehab 	bool adc_flip;
29529a0bf528SMauro Carvalho Chehab 	int status;
2953cd7a67a4SMauro Carvalho Chehab 	u32 if_freq_actual;
2954cd7a67a4SMauro Carvalho Chehab 	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2955cd7a67a4SMauro Carvalho Chehab 	u32 frequency_shift;
2956cd7a67a4SMauro Carvalho Chehab 	bool image_to_select;
29579a0bf528SMauro Carvalho Chehab 
29589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29599a0bf528SMauro Carvalho Chehab 
29609a0bf528SMauro Carvalho Chehab 	/*
29619a0bf528SMauro Carvalho Chehab 	   Program frequency shifter
29629a0bf528SMauro Carvalho Chehab 	   No need to account for mirroring on RF
29639a0bf528SMauro Carvalho Chehab 	 */
2964cd7a67a4SMauro Carvalho Chehab 	if (is_dtv) {
2965cd7a67a4SMauro Carvalho Chehab 		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2966cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_QAM_ITU_C) ||
2967cd7a67a4SMauro Carvalho Chehab 		    (state->m_operation_mode == OM_DVBT))
2968cd7a67a4SMauro Carvalho Chehab 			select_pos_image = true;
29699a0bf528SMauro Carvalho Chehab 		else
2970cd7a67a4SMauro Carvalho Chehab 			select_pos_image = false;
29719a0bf528SMauro Carvalho Chehab 	}
2972cd7a67a4SMauro Carvalho Chehab 	if (tuner_mirror)
29739a0bf528SMauro Carvalho Chehab 		/* tuner doesn't mirror */
2974cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz +
2975cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual + fm_frequency_shift;
29769a0bf528SMauro Carvalho Chehab 	else
29779a0bf528SMauro Carvalho Chehab 		/* tuner mirrors */
2978cd7a67a4SMauro Carvalho Chehab 		if_freq_actual = intermediate_freqk_hz -
2979cd7a67a4SMauro Carvalho Chehab 		    rf_freq_residual - fm_frequency_shift;
2980cd7a67a4SMauro Carvalho Chehab 	if (if_freq_actual > sampling_frequency / 2) {
29819a0bf528SMauro Carvalho Chehab 		/* adc mirrors */
2982cd7a67a4SMauro Carvalho Chehab 		adc_freq = sampling_frequency - if_freq_actual;
2983cd7a67a4SMauro Carvalho Chehab 		adc_flip = true;
29849a0bf528SMauro Carvalho Chehab 	} else {
29859a0bf528SMauro Carvalho Chehab 		/* adc doesn't mirror */
2986cd7a67a4SMauro Carvalho Chehab 		adc_freq = if_freq_actual;
2987cd7a67a4SMauro Carvalho Chehab 		adc_flip = false;
29889a0bf528SMauro Carvalho Chehab 	}
29899a0bf528SMauro Carvalho Chehab 
2990cd7a67a4SMauro Carvalho Chehab 	frequency_shift = adc_freq;
2991cd7a67a4SMauro Carvalho Chehab 	image_to_select = state->m_rfmirror ^ tuner_mirror ^
2992cd7a67a4SMauro Carvalho Chehab 	    adc_flip ^ select_pos_image;
2993cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_fs_rate_ofs =
2994cd7a67a4SMauro Carvalho Chehab 	    Frac28a((frequency_shift), sampling_frequency);
29959a0bf528SMauro Carvalho Chehab 
2996cd7a67a4SMauro Carvalho Chehab 	if (image_to_select)
2997cd7a67a4SMauro Carvalho Chehab 		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
29989a0bf528SMauro Carvalho Chehab 
29999a0bf528SMauro Carvalho Chehab 	/* Program frequency shifter with tuner offset compensation */
3000cd7a67a4SMauro Carvalho Chehab 	/* frequency_shift += tuner_freq_offset; TODO */
30019a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
3002cd7a67a4SMauro Carvalho Chehab 			 state->m_iqm_fs_rate_ofs);
30039a0bf528SMauro Carvalho Chehab 	if (status < 0)
30043a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
30059a0bf528SMauro Carvalho Chehab 	return status;
30069a0bf528SMauro Carvalho Chehab }
30079a0bf528SMauro Carvalho Chehab 
3008cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv)
30099a0bf528SMauro Carvalho Chehab {
3010cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt = 0;
3011cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_min = 0;
3012cd7a67a4SMauro Carvalho Chehab 	u16 ingain_tgt_max = 0;
3013cd7a67a4SMauro Carvalho Chehab 	u16 clp_cyclen = 0;
3014cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_min = 0;
3015cd7a67a4SMauro Carvalho Chehab 	u16 clp_dir_to = 0;
3016cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_min = 0;
3017cd7a67a4SMauro Carvalho Chehab 	u16 sns_sum_max = 0;
3018cd7a67a4SMauro Carvalho Chehab 	u16 clp_sum_max = 0;
3019cd7a67a4SMauro Carvalho Chehab 	u16 sns_dir_to = 0;
3020cd7a67a4SMauro Carvalho Chehab 	u16 ki_innergain_min = 0;
3021cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt = 0;
3022cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_min = 0;
3023cd7a67a4SMauro Carvalho Chehab 	u16 if_iaccu_hi_tgt_max = 0;
30249a0bf528SMauro Carvalho Chehab 	u16 data = 0;
3025cd7a67a4SMauro Carvalho Chehab 	u16 fast_clp_ctrl_delay = 0;
3026cd7a67a4SMauro Carvalho Chehab 	u16 clp_ctrl_mode = 0;
30279a0bf528SMauro Carvalho Chehab 	int status = 0;
30289a0bf528SMauro Carvalho Chehab 
30299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
30309a0bf528SMauro Carvalho Chehab 
30319a0bf528SMauro Carvalho Chehab 	/* Common settings */
3032cd7a67a4SMauro Carvalho Chehab 	sns_sum_max = 1023;
3033cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_min = 2047;
3034cd7a67a4SMauro Carvalho Chehab 	clp_cyclen = 500;
3035cd7a67a4SMauro Carvalho Chehab 	clp_sum_max = 1023;
30369a0bf528SMauro Carvalho Chehab 
30379a0bf528SMauro Carvalho Chehab 	/* AGCInit() not available for DVBT; init done in microcode */
3038cd7a67a4SMauro Carvalho Chehab 	if (!is_qam(state)) {
30393a4398f5SMauro Carvalho Chehab 		pr_err("%s: mode %d is not DVB-C\n",
30403a4398f5SMauro Carvalho Chehab 		       __func__, state->m_operation_mode);
30419a0bf528SMauro Carvalho Chehab 		return -EINVAL;
30429a0bf528SMauro Carvalho Chehab 	}
30439a0bf528SMauro Carvalho Chehab 
30449a0bf528SMauro Carvalho Chehab 	/* FIXME: Analog TV AGC require different settings */
30459a0bf528SMauro Carvalho Chehab 
30469a0bf528SMauro Carvalho Chehab 	/* Standard specific settings */
3047cd7a67a4SMauro Carvalho Chehab 	clp_sum_min = 8;
3048cd7a67a4SMauro Carvalho Chehab 	clp_dir_to = (u16) -9;
3049cd7a67a4SMauro Carvalho Chehab 	clp_ctrl_mode = 0;
3050cd7a67a4SMauro Carvalho Chehab 	sns_sum_min = 8;
3051cd7a67a4SMauro Carvalho Chehab 	sns_dir_to = (u16) -9;
3052cd7a67a4SMauro Carvalho Chehab 	ki_innergain_min = (u16) -1030;
3053cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt_max = 0x2380;
3054cd7a67a4SMauro Carvalho Chehab 	if_iaccu_hi_tgt = 0x2380;
3055cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_min = 0x0511;
3056cd7a67a4SMauro Carvalho Chehab 	ingain_tgt = 0x0511;
3057cd7a67a4SMauro Carvalho Chehab 	ingain_tgt_max = 5119;
3058cd7a67a4SMauro Carvalho Chehab 	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
30599a0bf528SMauro Carvalho Chehab 
3060ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3061ab5060cdSMauro Carvalho Chehab 			 fast_clp_ctrl_delay);
30629a0bf528SMauro Carvalho Chehab 	if (status < 0)
30639a0bf528SMauro Carvalho Chehab 		goto error;
30649a0bf528SMauro Carvalho Chehab 
3065cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
30669a0bf528SMauro Carvalho Chehab 	if (status < 0)
30679a0bf528SMauro Carvalho Chehab 		goto error;
3068cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
30699a0bf528SMauro Carvalho Chehab 	if (status < 0)
30709a0bf528SMauro Carvalho Chehab 		goto error;
3071cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
30729a0bf528SMauro Carvalho Chehab 	if (status < 0)
30739a0bf528SMauro Carvalho Chehab 		goto error;
3074cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
30759a0bf528SMauro Carvalho Chehab 	if (status < 0)
30769a0bf528SMauro Carvalho Chehab 		goto error;
3077ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3078ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_min);
30799a0bf528SMauro Carvalho Chehab 	if (status < 0)
30809a0bf528SMauro Carvalho Chehab 		goto error;
3081ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3082ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt_max);
30839a0bf528SMauro Carvalho Chehab 	if (status < 0)
30849a0bf528SMauro Carvalho Chehab 		goto error;
30859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
30869a0bf528SMauro Carvalho Chehab 	if (status < 0)
30879a0bf528SMauro Carvalho Chehab 		goto error;
30889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
30899a0bf528SMauro Carvalho Chehab 	if (status < 0)
30909a0bf528SMauro Carvalho Chehab 		goto error;
30919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
30929a0bf528SMauro Carvalho Chehab 	if (status < 0)
30939a0bf528SMauro Carvalho Chehab 		goto error;
30949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
30959a0bf528SMauro Carvalho Chehab 	if (status < 0)
30969a0bf528SMauro Carvalho Chehab 		goto error;
3097cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
30989a0bf528SMauro Carvalho Chehab 	if (status < 0)
30999a0bf528SMauro Carvalho Chehab 		goto error;
3100cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
31019a0bf528SMauro Carvalho Chehab 	if (status < 0)
31029a0bf528SMauro Carvalho Chehab 		goto error;
31039a0bf528SMauro Carvalho Chehab 
3104ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3105ab5060cdSMauro Carvalho Chehab 			 ki_innergain_min);
31069a0bf528SMauro Carvalho Chehab 	if (status < 0)
31079a0bf528SMauro Carvalho Chehab 		goto error;
3108ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3109ab5060cdSMauro Carvalho Chehab 			 if_iaccu_hi_tgt);
31109a0bf528SMauro Carvalho Chehab 	if (status < 0)
31119a0bf528SMauro Carvalho Chehab 		goto error;
3112cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
31139a0bf528SMauro Carvalho Chehab 	if (status < 0)
31149a0bf528SMauro Carvalho Chehab 		goto error;
31159a0bf528SMauro Carvalho Chehab 
31169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
31179a0bf528SMauro Carvalho Chehab 	if (status < 0)
31189a0bf528SMauro Carvalho Chehab 		goto error;
31199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
31209a0bf528SMauro Carvalho Chehab 	if (status < 0)
31219a0bf528SMauro Carvalho Chehab 		goto error;
31229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
31239a0bf528SMauro Carvalho Chehab 	if (status < 0)
31249a0bf528SMauro Carvalho Chehab 		goto error;
31259a0bf528SMauro Carvalho Chehab 
31269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
31279a0bf528SMauro Carvalho Chehab 	if (status < 0)
31289a0bf528SMauro Carvalho Chehab 		goto error;
3129cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
31309a0bf528SMauro Carvalho Chehab 	if (status < 0)
31319a0bf528SMauro Carvalho Chehab 		goto error;
3132cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
31339a0bf528SMauro Carvalho Chehab 	if (status < 0)
31349a0bf528SMauro Carvalho Chehab 		goto error;
3135cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
31369a0bf528SMauro Carvalho Chehab 	if (status < 0)
31379a0bf528SMauro Carvalho Chehab 		goto error;
3138cd7a67a4SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
31399a0bf528SMauro Carvalho Chehab 	if (status < 0)
31409a0bf528SMauro Carvalho Chehab 		goto error;
31419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
31429a0bf528SMauro Carvalho Chehab 	if (status < 0)
31439a0bf528SMauro Carvalho Chehab 		goto error;
31449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
31459a0bf528SMauro Carvalho Chehab 	if (status < 0)
31469a0bf528SMauro Carvalho Chehab 		goto error;
31479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
31489a0bf528SMauro Carvalho Chehab 	if (status < 0)
31499a0bf528SMauro Carvalho Chehab 		goto error;
31509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
31519a0bf528SMauro Carvalho Chehab 	if (status < 0)
31529a0bf528SMauro Carvalho Chehab 		goto error;
31539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
31549a0bf528SMauro Carvalho Chehab 	if (status < 0)
31559a0bf528SMauro Carvalho Chehab 		goto error;
31569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
31579a0bf528SMauro Carvalho Chehab 	if (status < 0)
31589a0bf528SMauro Carvalho Chehab 		goto error;
31599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
31609a0bf528SMauro Carvalho Chehab 	if (status < 0)
31619a0bf528SMauro Carvalho Chehab 		goto error;
31629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
31639a0bf528SMauro Carvalho Chehab 	if (status < 0)
31649a0bf528SMauro Carvalho Chehab 		goto error;
31659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
31669a0bf528SMauro Carvalho Chehab 	if (status < 0)
31679a0bf528SMauro Carvalho Chehab 		goto error;
31689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
31699a0bf528SMauro Carvalho Chehab 	if (status < 0)
31709a0bf528SMauro Carvalho Chehab 		goto error;
31719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
31729a0bf528SMauro Carvalho Chehab 	if (status < 0)
31739a0bf528SMauro Carvalho Chehab 		goto error;
31749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
31759a0bf528SMauro Carvalho Chehab 	if (status < 0)
31769a0bf528SMauro Carvalho Chehab 		goto error;
31779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
31789a0bf528SMauro Carvalho Chehab 	if (status < 0)
31799a0bf528SMauro Carvalho Chehab 		goto error;
31809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
31819a0bf528SMauro Carvalho Chehab 	if (status < 0)
31829a0bf528SMauro Carvalho Chehab 		goto error;
31839a0bf528SMauro Carvalho Chehab 
31849a0bf528SMauro Carvalho Chehab 	/* Initialize inner-loop KI gain factors */
31859a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_AGC_KI__A, &data);
31869a0bf528SMauro Carvalho Chehab 	if (status < 0)
31879a0bf528SMauro Carvalho Chehab 		goto error;
31889a0bf528SMauro Carvalho Chehab 
31899a0bf528SMauro Carvalho Chehab 	data = 0x0657;
31909a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_RF__M;
31919a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
31929a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_IF__M;
31939a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
31949a0bf528SMauro Carvalho Chehab 
31959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI__A, data);
31969a0bf528SMauro Carvalho Chehab error:
31979a0bf528SMauro Carvalho Chehab 	if (status < 0)
31983a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
31999a0bf528SMauro Carvalho Chehab 	return status;
32009a0bf528SMauro Carvalho Chehab }
32019a0bf528SMauro Carvalho Chehab 
3202cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
32039a0bf528SMauro Carvalho Chehab {
32049a0bf528SMauro Carvalho Chehab 	int status;
32059a0bf528SMauro Carvalho Chehab 
32069a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3207cd7a67a4SMauro Carvalho Chehab 	if (packet_err == NULL)
32089a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
32099a0bf528SMauro Carvalho Chehab 	else
3210ab5060cdSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3211ab5060cdSMauro Carvalho Chehab 				packet_err);
32129a0bf528SMauro Carvalho Chehab 	if (status < 0)
32133a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
32149a0bf528SMauro Carvalho Chehab 	return status;
32159a0bf528SMauro Carvalho Chehab }
32169a0bf528SMauro Carvalho Chehab 
3217cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state,
32189a0bf528SMauro Carvalho Chehab 			 u16 cmd, u16 subcmd,
32199a0bf528SMauro Carvalho Chehab 			 u16 param0, u16 param1, u16 param2,
32209a0bf528SMauro Carvalho Chehab 			 u16 param3, u16 param4)
32219a0bf528SMauro Carvalho Chehab {
3222cd7a67a4SMauro Carvalho Chehab 	u16 cur_cmd = 0;
3223cd7a67a4SMauro Carvalho Chehab 	u16 err_code = 0;
3224cd7a67a4SMauro Carvalho Chehab 	u16 retry_cnt = 0;
3225cd7a67a4SMauro Carvalho Chehab 	u16 sc_exec = 0;
32269a0bf528SMauro Carvalho Chehab 	int status;
32279a0bf528SMauro Carvalho Chehab 
32289a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3229cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3230cd7a67a4SMauro Carvalho Chehab 	if (sc_exec != 1) {
32319a0bf528SMauro Carvalho Chehab 		/* SC is not running */
32329a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32339a0bf528SMauro Carvalho Chehab 	}
32349a0bf528SMauro Carvalho Chehab 	if (status < 0)
32359a0bf528SMauro Carvalho Chehab 		goto error;
32369a0bf528SMauro Carvalho Chehab 
32379a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready to receive command */
3238cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32399a0bf528SMauro Carvalho Chehab 	do {
3240b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3241cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3242cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3243cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3244cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32459a0bf528SMauro Carvalho Chehab 		goto error;
32469a0bf528SMauro Carvalho Chehab 
32479a0bf528SMauro Carvalho Chehab 	/* Write sub-command */
32489a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32499a0bf528SMauro Carvalho Chehab 		/* All commands using sub-cmd */
32509a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32519a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32529a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32539a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
32549a0bf528SMauro Carvalho Chehab 		if (status < 0)
32559a0bf528SMauro Carvalho Chehab 			goto error;
32569a0bf528SMauro Carvalho Chehab 		break;
32579a0bf528SMauro Carvalho Chehab 	default:
32589a0bf528SMauro Carvalho Chehab 		/* Do nothing */
32599a0bf528SMauro Carvalho Chehab 		break;
32609a0bf528SMauro Carvalho Chehab 	}
32619a0bf528SMauro Carvalho Chehab 
32629a0bf528SMauro Carvalho Chehab 	/* Write needed parameters and the command */
32632f60f13cSMauro Carvalho Chehab 	status = 0;
32649a0bf528SMauro Carvalho Chehab 	switch (cmd) {
32659a0bf528SMauro Carvalho Chehab 		/* All commands using 5 parameters */
32669a0bf528SMauro Carvalho Chehab 		/* All commands using 4 parameters */
32679a0bf528SMauro Carvalho Chehab 		/* All commands using 3 parameters */
32689a0bf528SMauro Carvalho Chehab 		/* All commands using 2 parameters */
32699a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
32709a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32719a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32722f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
32739a0bf528SMauro Carvalho Chehab 		/* All commands using 1 parameters */
327406eeefe8SMauro Carvalho Chehab 		/* fall through */
32759a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32769a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
32772f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
32789a0bf528SMauro Carvalho Chehab 		/* All commands using 0 parameters */
327906eeefe8SMauro Carvalho Chehab 		/* fall through */
32809a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32819a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
32829a0bf528SMauro Carvalho Chehab 		/* Write command */
32832f60f13cSMauro Carvalho Chehab 		status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
32849a0bf528SMauro Carvalho Chehab 		break;
32859a0bf528SMauro Carvalho Chehab 	default:
32869a0bf528SMauro Carvalho Chehab 		/* Unknown command */
32879a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
32889a0bf528SMauro Carvalho Chehab 	}
32899a0bf528SMauro Carvalho Chehab 	if (status < 0)
32909a0bf528SMauro Carvalho Chehab 		goto error;
32919a0bf528SMauro Carvalho Chehab 
32929a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready processing command */
3293cd7a67a4SMauro Carvalho Chehab 	retry_cnt = 0;
32949a0bf528SMauro Carvalho Chehab 	do {
3295b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
3296cd7a67a4SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3297cd7a67a4SMauro Carvalho Chehab 		retry_cnt++;
3298cd7a67a4SMauro Carvalho Chehab 	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3299cd7a67a4SMauro Carvalho Chehab 	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
33009a0bf528SMauro Carvalho Chehab 		goto error;
33019a0bf528SMauro Carvalho Chehab 
33029a0bf528SMauro Carvalho Chehab 	/* Check for illegal cmd */
3303cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3304cd7a67a4SMauro Carvalho Chehab 	if (err_code == 0xFFFF) {
33059a0bf528SMauro Carvalho Chehab 		/* illegal command */
33069a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33079a0bf528SMauro Carvalho Chehab 	}
33089a0bf528SMauro Carvalho Chehab 	if (status < 0)
33099a0bf528SMauro Carvalho Chehab 		goto error;
33109a0bf528SMauro Carvalho Chehab 
331139c1cb2bSJonathan McCrohan 	/* Retrieve results parameters from SC */
33129a0bf528SMauro Carvalho Chehab 	switch (cmd) {
33139a0bf528SMauro Carvalho Chehab 		/* All commands yielding 5 results */
33149a0bf528SMauro Carvalho Chehab 		/* All commands yielding 4 results */
33159a0bf528SMauro Carvalho Chehab 		/* All commands yielding 3 results */
33169a0bf528SMauro Carvalho Chehab 		/* All commands yielding 2 results */
33179a0bf528SMauro Carvalho Chehab 		/* All commands yielding 1 result */
33189a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
33199a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
33209a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
33219a0bf528SMauro Carvalho Chehab 		/* All commands yielding 0 results */
33229a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
33239a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_TIMER:
33249a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
33259a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
33269a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
33279a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
33289a0bf528SMauro Carvalho Chehab 		break;
33299a0bf528SMauro Carvalho Chehab 	default:
33309a0bf528SMauro Carvalho Chehab 		/* Unknown command */
33319a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33329a0bf528SMauro Carvalho Chehab 		break;
33339a0bf528SMauro Carvalho Chehab 	}			/* switch (cmd->cmd) */
33349a0bf528SMauro Carvalho Chehab error:
33359a0bf528SMauro Carvalho Chehab 	if (status < 0)
33363a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33379a0bf528SMauro Carvalho Chehab 	return status;
33389a0bf528SMauro Carvalho Chehab }
33399a0bf528SMauro Carvalho Chehab 
3340cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state)
33419a0bf528SMauro Carvalho Chehab {
3342cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRX_POWER_UP;
33439a0bf528SMauro Carvalho Chehab 	int status;
33449a0bf528SMauro Carvalho Chehab 
33459a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3346cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
33479a0bf528SMauro Carvalho Chehab 	if (status < 0)
33483a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33499a0bf528SMauro Carvalho Chehab 	return status;
33509a0bf528SMauro Carvalho Chehab }
33519a0bf528SMauro Carvalho Chehab 
3352cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
33539a0bf528SMauro Carvalho Chehab {
33549a0bf528SMauro Carvalho Chehab 	int status;
33559a0bf528SMauro Carvalho Chehab 
33569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33575a7f7b79SMauro Carvalho Chehab 	if (*enabled)
33589a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
33599a0bf528SMauro Carvalho Chehab 	else
33609a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
33619a0bf528SMauro Carvalho Chehab 	if (status < 0)
33623a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33639a0bf528SMauro Carvalho Chehab 	return status;
33649a0bf528SMauro Carvalho Chehab }
33659a0bf528SMauro Carvalho Chehab 
33669a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K     4000
3367cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
33689a0bf528SMauro Carvalho Chehab {
33699a0bf528SMauro Carvalho Chehab 
33709a0bf528SMauro Carvalho Chehab 	int status;
33719a0bf528SMauro Carvalho Chehab 
33729a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33735a7f7b79SMauro Carvalho Chehab 	if (*enabled) {
33749a0bf528SMauro Carvalho Chehab 		/* write mask to 1 */
33759a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
33769a0bf528SMauro Carvalho Chehab 				   DEFAULT_FR_THRES_8K);
33779a0bf528SMauro Carvalho Chehab 	} else {
33789a0bf528SMauro Carvalho Chehab 		/* write mask to 0 */
33799a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
33809a0bf528SMauro Carvalho Chehab 	}
33819a0bf528SMauro Carvalho Chehab 	if (status < 0)
33823a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
33839a0bf528SMauro Carvalho Chehab 
33849a0bf528SMauro Carvalho Chehab 	return status;
33859a0bf528SMauro Carvalho Chehab }
33869a0bf528SMauro Carvalho Chehab 
3387cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3388cd7a67a4SMauro Carvalho Chehab 				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
33899a0bf528SMauro Carvalho Chehab {
33909a0bf528SMauro Carvalho Chehab 	u16 data = 0;
33919a0bf528SMauro Carvalho Chehab 	int status;
33929a0bf528SMauro Carvalho Chehab 
33939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33949a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
33959a0bf528SMauro Carvalho Chehab 	if (status < 0)
33969a0bf528SMauro Carvalho Chehab 		goto error;
33979a0bf528SMauro Carvalho Chehab 
3398cd7a67a4SMauro Carvalho Chehab 	switch (echo_thres->fft_mode) {
33999a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_2K:
34009a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3401cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
34029a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
34039a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
34049a0bf528SMauro Carvalho Chehab 		break;
34059a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_8K:
34069a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3407cd7a67a4SMauro Carvalho Chehab 		data |= ((echo_thres->threshold <<
34089a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
34099a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
34109a0bf528SMauro Carvalho Chehab 		break;
34119a0bf528SMauro Carvalho Chehab 	default:
34129a0bf528SMauro Carvalho Chehab 		return -EINVAL;
34139a0bf528SMauro Carvalho Chehab 	}
34149a0bf528SMauro Carvalho Chehab 
34159a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
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 
3422cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3423cd7a67a4SMauro Carvalho Chehab 			       enum drxk_cfg_dvbt_sqi_speed *speed)
34249a0bf528SMauro Carvalho Chehab {
34259a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
34269a0bf528SMauro Carvalho Chehab 
34279a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34289a0bf528SMauro Carvalho Chehab 
34299a0bf528SMauro Carvalho Chehab 	switch (*speed) {
34309a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_FAST:
34319a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_MEDIUM:
34329a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_SLOW:
34339a0bf528SMauro Carvalho Chehab 		break;
34349a0bf528SMauro Carvalho Chehab 	default:
34359a0bf528SMauro Carvalho Chehab 		goto error;
34369a0bf528SMauro Carvalho Chehab 	}
34379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
34389a0bf528SMauro Carvalho Chehab 			   (u16) *speed);
34399a0bf528SMauro Carvalho Chehab error:
34409a0bf528SMauro Carvalho Chehab 	if (status < 0)
34413a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34429a0bf528SMauro Carvalho Chehab 	return status;
34439a0bf528SMauro Carvalho Chehab }
34449a0bf528SMauro Carvalho Chehab 
34459a0bf528SMauro Carvalho Chehab /*============================================================================*/
34469a0bf528SMauro Carvalho Chehab 
344734eb9751SMauro Carvalho Chehab /*
34489a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
34499a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34509a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34519a0bf528SMauro Carvalho Chehab *
34529a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
34539a0bf528SMauro Carvalho Chehab *
34549a0bf528SMauro Carvalho Chehab */
3455cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state)
34569a0bf528SMauro Carvalho Chehab {
34579a0bf528SMauro Carvalho Chehab 	int status;
34589a0bf528SMauro Carvalho Chehab 	bool setincenable = false;
34599a0bf528SMauro Carvalho Chehab 	bool setfrenable = true;
34609a0bf528SMauro Carvalho Chehab 
3461cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3462cd7a67a4SMauro Carvalho Chehab 	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
34639a0bf528SMauro Carvalho Chehab 
34649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3465cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
34669a0bf528SMauro Carvalho Chehab 	if (status < 0)
34679a0bf528SMauro Carvalho Chehab 		goto error;
3468cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
34699a0bf528SMauro Carvalho Chehab 	if (status < 0)
34709a0bf528SMauro Carvalho Chehab 		goto error;
3471cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
34729a0bf528SMauro Carvalho Chehab 	if (status < 0)
34739a0bf528SMauro Carvalho Chehab 		goto error;
3474cd7a67a4SMauro Carvalho Chehab 	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
34759a0bf528SMauro Carvalho Chehab 	if (status < 0)
34769a0bf528SMauro Carvalho Chehab 		goto error;
3477ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3478ab5060cdSMauro Carvalho Chehab 			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
34799a0bf528SMauro Carvalho Chehab error:
34809a0bf528SMauro Carvalho Chehab 	if (status < 0)
34813a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
34829a0bf528SMauro Carvalho Chehab 	return status;
34839a0bf528SMauro Carvalho Chehab }
34849a0bf528SMauro Carvalho Chehab 
34859a0bf528SMauro Carvalho Chehab /*============================================================================*/
34869a0bf528SMauro Carvalho Chehab 
348734eb9751SMauro Carvalho Chehab /*
34889a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
34899a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34909a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34919a0bf528SMauro Carvalho Chehab *
34929a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
34939a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
34949a0bf528SMauro Carvalho Chehab */
3495cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
3496cd7a67a4SMauro Carvalho Chehab 			   enum operation_mode o_mode)
34979a0bf528SMauro Carvalho Chehab {
3498cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
34999a0bf528SMauro Carvalho Chehab 	u16 data = 0;
35009a0bf528SMauro Carvalho Chehab 	int status;
35019a0bf528SMauro Carvalho Chehab 
35029a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
35039a0bf528SMauro Carvalho Chehab 
3504cd7a67a4SMauro Carvalho Chehab 	power_up_dvbt(state);
35059a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
3506cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_dvbt(state);
35079a0bf528SMauro Carvalho Chehab 	/* send OFDM reset command */
3508ab5060cdSMauro Carvalho Chehab 	status = scu_command(state,
3509ab5060cdSMauro Carvalho Chehab 			     SCU_RAM_COMMAND_STANDARD_OFDM
3510ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3511ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
35129a0bf528SMauro Carvalho Chehab 	if (status < 0)
35139a0bf528SMauro Carvalho Chehab 		goto error;
35149a0bf528SMauro Carvalho Chehab 
35159a0bf528SMauro Carvalho Chehab 	/* send OFDM setenv command */
3516ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3517ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3518ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
35199a0bf528SMauro Carvalho Chehab 	if (status < 0)
35209a0bf528SMauro Carvalho Chehab 		goto error;
35219a0bf528SMauro Carvalho Chehab 
35229a0bf528SMauro Carvalho Chehab 	/* reset datapath for OFDM, processors first */
35239a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
35249a0bf528SMauro Carvalho Chehab 	if (status < 0)
35259a0bf528SMauro Carvalho Chehab 		goto error;
35269a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
35279a0bf528SMauro Carvalho Chehab 	if (status < 0)
35289a0bf528SMauro Carvalho Chehab 		goto error;
35299a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
35309a0bf528SMauro Carvalho Chehab 	if (status < 0)
35319a0bf528SMauro Carvalho Chehab 		goto error;
35329a0bf528SMauro Carvalho Chehab 
35339a0bf528SMauro Carvalho Chehab 	/* IQM setup */
35349a0bf528SMauro Carvalho Chehab 	/* synchronize on ofdstate->m_festart */
35359a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 1);
35369a0bf528SMauro Carvalho Chehab 	if (status < 0)
35379a0bf528SMauro Carvalho Chehab 		goto error;
35389a0bf528SMauro Carvalho Chehab 	/* window size for clipping ADC detection */
35399a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
35409a0bf528SMauro Carvalho Chehab 	if (status < 0)
35419a0bf528SMauro Carvalho Chehab 		goto error;
35429a0bf528SMauro Carvalho Chehab 	/* window size for for sense pre-SAW detection */
35439a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
35449a0bf528SMauro Carvalho Chehab 	if (status < 0)
35459a0bf528SMauro Carvalho Chehab 		goto error;
35469a0bf528SMauro Carvalho Chehab 	/* sense threshold for sense pre-SAW detection */
35479a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
35489a0bf528SMauro Carvalho Chehab 	if (status < 0)
35499a0bf528SMauro Carvalho Chehab 		goto error;
3550cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
35519a0bf528SMauro Carvalho Chehab 	if (status < 0)
35529a0bf528SMauro Carvalho Chehab 		goto error;
35539a0bf528SMauro Carvalho Chehab 
35549a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AGC_RF__A, 0);
35559a0bf528SMauro Carvalho Chehab 	if (status < 0)
35569a0bf528SMauro Carvalho Chehab 		goto error;
35579a0bf528SMauro Carvalho Chehab 
35589a0bf528SMauro Carvalho Chehab 	/* Impulse noise cruncher setup */
35599a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_LCT__A, 0);	/* crunch in IQM_CF */
35609a0bf528SMauro Carvalho Chehab 	if (status < 0)
35619a0bf528SMauro Carvalho Chehab 		goto error;
35629a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);	/* detect in IQM_CF */
35639a0bf528SMauro Carvalho Chehab 	if (status < 0)
35649a0bf528SMauro Carvalho Chehab 		goto error;
35659a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 3);	/* peak detector window length */
35669a0bf528SMauro Carvalho Chehab 	if (status < 0)
35679a0bf528SMauro Carvalho Chehab 		goto error;
35689a0bf528SMauro Carvalho Chehab 
35699a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 16);
35709a0bf528SMauro Carvalho Chehab 	if (status < 0)
35719a0bf528SMauro Carvalho Chehab 		goto error;
35729a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
35739a0bf528SMauro Carvalho Chehab 	if (status < 0)
35749a0bf528SMauro Carvalho Chehab 		goto error;
35759a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
35769a0bf528SMauro Carvalho Chehab 	if (status < 0)
35779a0bf528SMauro Carvalho Chehab 		goto error;
35789a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE__A, 1600);
35799a0bf528SMauro Carvalho Chehab 	if (status < 0)
35809a0bf528SMauro Carvalho Chehab 		goto error;
35819a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, 0);
35829a0bf528SMauro Carvalho Chehab 	if (status < 0)
35839a0bf528SMauro Carvalho Chehab 		goto error;
35849a0bf528SMauro Carvalho Chehab 
35859a0bf528SMauro Carvalho Chehab 	/* virtual clipping threshold for clipping ADC detection */
35869a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
35879a0bf528SMauro Carvalho Chehab 	if (status < 0)
35889a0bf528SMauro Carvalho Chehab 		goto error;
35899a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 495);	/* crunching threshold */
35909a0bf528SMauro Carvalho Chehab 	if (status < 0)
35919a0bf528SMauro Carvalho Chehab 		goto error;
35929a0bf528SMauro Carvalho Chehab 
3593ab5060cdSMauro Carvalho Chehab 	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3594ab5060cdSMauro Carvalho Chehab 			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
35959a0bf528SMauro Carvalho Chehab 	if (status < 0)
35969a0bf528SMauro Carvalho Chehab 		goto error;
35979a0bf528SMauro Carvalho Chehab 
35989a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 2);	/* peak detector threshold */
35999a0bf528SMauro Carvalho Chehab 	if (status < 0)
36009a0bf528SMauro Carvalho Chehab 		goto error;
36019a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
36029a0bf528SMauro Carvalho Chehab 	if (status < 0)
36039a0bf528SMauro Carvalho Chehab 		goto error;
36049a0bf528SMauro Carvalho Chehab 	/* enable power measurement interrupt */
36059a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
36069a0bf528SMauro Carvalho Chehab 	if (status < 0)
36079a0bf528SMauro Carvalho Chehab 		goto error;
36089a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
36099a0bf528SMauro Carvalho Chehab 	if (status < 0)
36109a0bf528SMauro Carvalho Chehab 		goto error;
36119a0bf528SMauro Carvalho Chehab 
36129a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
3613cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
36149a0bf528SMauro Carvalho Chehab 	if (status < 0)
36159a0bf528SMauro Carvalho Chehab 		goto error;
3616cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
36179a0bf528SMauro Carvalho Chehab 	if (status < 0)
36189a0bf528SMauro Carvalho Chehab 		goto error;
36199a0bf528SMauro Carvalho Chehab 
36209a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
36219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
36229a0bf528SMauro Carvalho Chehab 	if (status < 0)
36239a0bf528SMauro Carvalho Chehab 		goto error;
36249a0bf528SMauro Carvalho Chehab 
3625cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
36269a0bf528SMauro Carvalho Chehab 	if (status < 0)
36279a0bf528SMauro Carvalho Chehab 		goto error;
3628cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
36299a0bf528SMauro Carvalho Chehab 	if (status < 0)
36309a0bf528SMauro Carvalho Chehab 		goto error;
36319a0bf528SMauro Carvalho Chehab 
36329a0bf528SMauro Carvalho Chehab 	/* Set Noise Estimation notch width and enable DC fix */
36339a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
36349a0bf528SMauro Carvalho Chehab 	if (status < 0)
36359a0bf528SMauro Carvalho Chehab 		goto error;
36369a0bf528SMauro Carvalho Chehab 	data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
36379a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
36389a0bf528SMauro Carvalho Chehab 	if (status < 0)
36399a0bf528SMauro Carvalho Chehab 		goto error;
36409a0bf528SMauro Carvalho Chehab 
36419a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
36429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
36439a0bf528SMauro Carvalho Chehab 	if (status < 0)
36449a0bf528SMauro Carvalho Chehab 		goto error;
36459a0bf528SMauro Carvalho Chehab 
3646cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code) {
3647cd7a67a4SMauro Carvalho Chehab 		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
3648ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3649ab5060cdSMauro Carvalho Chehab 				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
36509a0bf528SMauro Carvalho Chehab 		if (status < 0)
36519a0bf528SMauro Carvalho Chehab 			goto error;
36529a0bf528SMauro Carvalho Chehab 	}
36539a0bf528SMauro Carvalho Chehab 
36549a0bf528SMauro Carvalho Chehab 	/* OFDM_SC setup */
36559a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36569a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
36579a0bf528SMauro Carvalho Chehab 	if (status < 0)
36589a0bf528SMauro Carvalho Chehab 		goto error;
36599a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
36609a0bf528SMauro Carvalho Chehab 	if (status < 0)
36619a0bf528SMauro Carvalho Chehab 		goto error;
36629a0bf528SMauro Carvalho Chehab #endif
36639a0bf528SMauro Carvalho Chehab 
36649a0bf528SMauro Carvalho Chehab 	/* FEC setup */
36659a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_INPUT_CTL__A, 1);	/* OFDM input */
36669a0bf528SMauro Carvalho Chehab 	if (status < 0)
36679a0bf528SMauro Carvalho Chehab 		goto error;
36689a0bf528SMauro Carvalho Chehab 
36699a0bf528SMauro Carvalho Chehab 
36709a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36719a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
36729a0bf528SMauro Carvalho Chehab 	if (status < 0)
36739a0bf528SMauro Carvalho Chehab 		goto error;
36749a0bf528SMauro Carvalho Chehab #else
36759a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
36769a0bf528SMauro Carvalho Chehab 	if (status < 0)
36779a0bf528SMauro Carvalho Chehab 		goto error;
36789a0bf528SMauro Carvalho Chehab #endif
36799a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
36809a0bf528SMauro Carvalho Chehab 	if (status < 0)
36819a0bf528SMauro Carvalho Chehab 		goto error;
36829a0bf528SMauro Carvalho Chehab 
36839a0bf528SMauro Carvalho Chehab 	/* Setup MPEG bus */
3684cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, OM_DVBT);
36859a0bf528SMauro Carvalho Chehab 	if (status < 0)
36869a0bf528SMauro Carvalho Chehab 		goto error;
36879a0bf528SMauro Carvalho Chehab 	/* Set DVBT Presets */
3688cd7a67a4SMauro Carvalho Chehab 	status = dvbt_activate_presets(state);
36899a0bf528SMauro Carvalho Chehab 	if (status < 0)
36909a0bf528SMauro Carvalho Chehab 		goto error;
36919a0bf528SMauro Carvalho Chehab 
36929a0bf528SMauro Carvalho Chehab error:
36939a0bf528SMauro Carvalho Chehab 	if (status < 0)
36943a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
36959a0bf528SMauro Carvalho Chehab 	return status;
36969a0bf528SMauro Carvalho Chehab }
36979a0bf528SMauro Carvalho Chehab 
36989a0bf528SMauro Carvalho Chehab /*============================================================================*/
369934eb9751SMauro Carvalho Chehab /*
3700cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel.
37019a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37029a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37039a0bf528SMauro Carvalho Chehab */
3704cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state)
37059a0bf528SMauro Carvalho Chehab {
37069a0bf528SMauro Carvalho Chehab 	u16 param1;
37079a0bf528SMauro Carvalho Chehab 	int status;
3708cd7a67a4SMauro Carvalho Chehab 	/* drxk_ofdm_sc_cmd_t scCmd; */
37099a0bf528SMauro Carvalho Chehab 
37109a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
3711cd7a67a4SMauro Carvalho Chehab 	/* start correct processes to get in lock */
37129a0bf528SMauro Carvalho Chehab 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
37139a0bf528SMauro Carvalho Chehab 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3714ab5060cdSMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3715ab5060cdSMauro Carvalho Chehab 				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3716ab5060cdSMauro Carvalho Chehab 				 0, 0, 0);
37179a0bf528SMauro Carvalho Chehab 	if (status < 0)
37189a0bf528SMauro Carvalho Chehab 		goto error;
3719cd7a67a4SMauro Carvalho Chehab 	/* start FEC OC */
3720cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
37219a0bf528SMauro Carvalho Chehab 	if (status < 0)
37229a0bf528SMauro Carvalho Chehab 		goto error;
37239a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
37249a0bf528SMauro Carvalho Chehab 	if (status < 0)
37259a0bf528SMauro Carvalho Chehab 		goto error;
37269a0bf528SMauro Carvalho Chehab error:
37279a0bf528SMauro Carvalho Chehab 	if (status < 0)
37283a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
37299a0bf528SMauro Carvalho Chehab 	return status;
37309a0bf528SMauro Carvalho Chehab }
37319a0bf528SMauro Carvalho Chehab 
37329a0bf528SMauro Carvalho Chehab 
37339a0bf528SMauro Carvalho Chehab /*============================================================================*/
37349a0bf528SMauro Carvalho Chehab 
373534eb9751SMauro Carvalho Chehab /*
37369a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
37379a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37389a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37399a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
37409a0bf528SMauro Carvalho Chehab */
3741cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3742cd7a67a4SMauro Carvalho Chehab 		   s32 tuner_freq_offset)
37439a0bf528SMauro Carvalho Chehab {
3744cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result = 0;
3745cd7a67a4SMauro Carvalho Chehab 	u16 transmission_params = 0;
3746cd7a67a4SMauro Carvalho Chehab 	u16 operation_mode = 0;
3747cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate_ofs = 0;
37489a0bf528SMauro Carvalho Chehab 	u32 bandwidth = 0;
37499a0bf528SMauro Carvalho Chehab 	u16 param1;
37509a0bf528SMauro Carvalho Chehab 	int status;
37519a0bf528SMauro Carvalho Chehab 
3752ab5060cdSMauro Carvalho Chehab 	dprintk(1, "IF =%d, TFO = %d\n",
3753ab5060cdSMauro Carvalho Chehab 		intermediate_freqk_hz, tuner_freq_offset);
37549a0bf528SMauro Carvalho Chehab 
3755ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3756ab5060cdSMauro Carvalho Chehab 			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3757ab5060cdSMauro Carvalho Chehab 			    0, NULL, 1, &cmd_result);
37589a0bf528SMauro Carvalho Chehab 	if (status < 0)
37599a0bf528SMauro Carvalho Chehab 		goto error;
37609a0bf528SMauro Carvalho Chehab 
37619a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
37629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
37639a0bf528SMauro Carvalho Chehab 	if (status < 0)
37649a0bf528SMauro Carvalho Chehab 		goto error;
37659a0bf528SMauro Carvalho Chehab 
37669a0bf528SMauro Carvalho Chehab 	/* Stop processors */
37679a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
37689a0bf528SMauro Carvalho Chehab 	if (status < 0)
37699a0bf528SMauro Carvalho Chehab 		goto error;
37709a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
37719a0bf528SMauro Carvalho Chehab 	if (status < 0)
37729a0bf528SMauro Carvalho Chehab 		goto error;
37739a0bf528SMauro Carvalho Chehab 
37749a0bf528SMauro Carvalho Chehab 	/* Mandatory fix, always stop CP, required to set spl offset back to
37759a0bf528SMauro Carvalho Chehab 		hardware default (is set to 0 by ucode during pilot detection */
37769a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
37779a0bf528SMauro Carvalho Chehab 	if (status < 0)
37789a0bf528SMauro Carvalho Chehab 		goto error;
37799a0bf528SMauro Carvalho Chehab 
3780ab5060cdSMauro Carvalho Chehab 	/*== Write channel settings to device ================================*/
37819a0bf528SMauro Carvalho Chehab 
37829a0bf528SMauro Carvalho Chehab 	/* mode */
37839a0bf528SMauro Carvalho Chehab 	switch (state->props.transmission_mode) {
37849a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_AUTO:
37859a0bf528SMauro Carvalho Chehab 	default:
3786cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
378706eeefe8SMauro Carvalho Chehab 		/* try first guess DRX_FFTMODE_8K */
378806eeefe8SMauro Carvalho Chehab 		/* fall through */
37899a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_8K:
3790cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
37919a0bf528SMauro Carvalho Chehab 		break;
37929a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_2K:
3793cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
37949a0bf528SMauro Carvalho Chehab 		break;
37959a0bf528SMauro Carvalho Chehab 	}
37969a0bf528SMauro Carvalho Chehab 
37979a0bf528SMauro Carvalho Chehab 	/* guard */
37989a0bf528SMauro Carvalho Chehab 	switch (state->props.guard_interval) {
37999a0bf528SMauro Carvalho Chehab 	default:
38009a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_AUTO:
3801cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
380206eeefe8SMauro Carvalho Chehab 		/* try first guess DRX_GUARD_1DIV4 */
380306eeefe8SMauro Carvalho Chehab 		/* fall through */
38049a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_4:
3805cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
38069a0bf528SMauro Carvalho Chehab 		break;
38079a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_32:
3808cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
38099a0bf528SMauro Carvalho Chehab 		break;
38109a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_16:
3811cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
38129a0bf528SMauro Carvalho Chehab 		break;
38139a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_8:
3814cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
38159a0bf528SMauro Carvalho Chehab 		break;
38169a0bf528SMauro Carvalho Chehab 	}
38179a0bf528SMauro Carvalho Chehab 
38189a0bf528SMauro Carvalho Chehab 	/* hierarchy */
38199a0bf528SMauro Carvalho Chehab 	switch (state->props.hierarchy) {
38209a0bf528SMauro Carvalho Chehab 	case HIERARCHY_AUTO:
38219a0bf528SMauro Carvalho Chehab 	case HIERARCHY_NONE:
38229a0bf528SMauro Carvalho Chehab 	default:
3823cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
382406eeefe8SMauro Carvalho Chehab 		/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3825cd7a67a4SMauro Carvalho Chehab 		/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
382606eeefe8SMauro Carvalho Chehab 		/* fall through */
38279a0bf528SMauro Carvalho Chehab 	case HIERARCHY_1:
3828cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
38299a0bf528SMauro Carvalho Chehab 		break;
38309a0bf528SMauro Carvalho Chehab 	case HIERARCHY_2:
3831cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
38329a0bf528SMauro Carvalho Chehab 		break;
38339a0bf528SMauro Carvalho Chehab 	case HIERARCHY_4:
3834cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
38359a0bf528SMauro Carvalho Chehab 		break;
38369a0bf528SMauro Carvalho Chehab 	}
38379a0bf528SMauro Carvalho Chehab 
38389a0bf528SMauro Carvalho Chehab 
38399a0bf528SMauro Carvalho Chehab 	/* modulation */
38409a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
38419a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
38429a0bf528SMauro Carvalho Chehab 	default:
3843cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
384406eeefe8SMauro Carvalho Chehab 		/* try first guess DRX_CONSTELLATION_QAM64 */
384506eeefe8SMauro Carvalho Chehab 		/* fall through */
38469a0bf528SMauro Carvalho Chehab 	case QAM_64:
3847cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
38489a0bf528SMauro Carvalho Chehab 		break;
38499a0bf528SMauro Carvalho Chehab 	case QPSK:
3850cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
38519a0bf528SMauro Carvalho Chehab 		break;
38529a0bf528SMauro Carvalho Chehab 	case QAM_16:
3853cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
38549a0bf528SMauro Carvalho Chehab 		break;
38559a0bf528SMauro Carvalho Chehab 	}
38569a0bf528SMauro Carvalho Chehab #if 0
385739c1cb2bSJonathan McCrohan 	/* No hierarchical channels support in BDA */
38589a0bf528SMauro Carvalho Chehab 	/* Priority (only for hierarchical channels) */
38599a0bf528SMauro Carvalho Chehab 	switch (channel->priority) {
38609a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_LOW:
3861cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3862cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38639a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_LO);
38649a0bf528SMauro Carvalho Chehab 		break;
38659a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_HIGH:
3866cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3867cd7a67a4SMauro Carvalho Chehab 		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38689a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_HI));
38699a0bf528SMauro Carvalho Chehab 		break;
38709a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_UNKNOWN:	/* fall through */
38719a0bf528SMauro Carvalho Chehab 	default:
38729a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
38739a0bf528SMauro Carvalho Chehab 		goto error;
38749a0bf528SMauro Carvalho Chehab 	}
38759a0bf528SMauro Carvalho Chehab #else
38769a0bf528SMauro Carvalho Chehab 	/* Set Priorty high */
3877cd7a67a4SMauro Carvalho Chehab 	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
38789a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
38799a0bf528SMauro Carvalho Chehab 	if (status < 0)
38809a0bf528SMauro Carvalho Chehab 		goto error;
38819a0bf528SMauro Carvalho Chehab #endif
38829a0bf528SMauro Carvalho Chehab 
38839a0bf528SMauro Carvalho Chehab 	/* coderate */
38849a0bf528SMauro Carvalho Chehab 	switch (state->props.code_rate_HP) {
38859a0bf528SMauro Carvalho Chehab 	case FEC_AUTO:
38869a0bf528SMauro Carvalho Chehab 	default:
3887cd7a67a4SMauro Carvalho Chehab 		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
388806eeefe8SMauro Carvalho Chehab 		/* try first guess DRX_CODERATE_2DIV3 */
388906eeefe8SMauro Carvalho Chehab 		/* fall through */
38909a0bf528SMauro Carvalho Chehab 	case FEC_2_3:
3891cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
38929a0bf528SMauro Carvalho Chehab 		break;
38939a0bf528SMauro Carvalho Chehab 	case FEC_1_2:
3894cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
38959a0bf528SMauro Carvalho Chehab 		break;
38969a0bf528SMauro Carvalho Chehab 	case FEC_3_4:
3897cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
38989a0bf528SMauro Carvalho Chehab 		break;
38999a0bf528SMauro Carvalho Chehab 	case FEC_5_6:
3900cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
39019a0bf528SMauro Carvalho Chehab 		break;
39029a0bf528SMauro Carvalho Chehab 	case FEC_7_8:
3903cd7a67a4SMauro Carvalho Chehab 		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
39049a0bf528SMauro Carvalho Chehab 		break;
39059a0bf528SMauro Carvalho Chehab 	}
39069a0bf528SMauro Carvalho Chehab 
3907ab5060cdSMauro Carvalho Chehab 	/*
3908ab5060cdSMauro Carvalho Chehab 	 * SAW filter selection: normaly not necesarry, but if wanted
3909ab5060cdSMauro Carvalho Chehab 	 * the application can select a SAW filter via the driver by
3910ab5060cdSMauro Carvalho Chehab 	 * using UIOs
3911ab5060cdSMauro Carvalho Chehab 	 */
3912ab5060cdSMauro Carvalho Chehab 
39139a0bf528SMauro Carvalho Chehab 	/* First determine real bandwidth (Hz) */
39149a0bf528SMauro Carvalho Chehab 	/* Also set delay for impulse noise cruncher */
3915ab5060cdSMauro Carvalho Chehab 	/*
3916ab5060cdSMauro Carvalho Chehab 	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3917ab5060cdSMauro Carvalho Chehab 	 * changed by SC for fix for some 8K,1/8 guard but is restored by
3918ab5060cdSMauro Carvalho Chehab 	 * InitEC and ResetEC functions
3919ab5060cdSMauro Carvalho Chehab 	 */
39209a0bf528SMauro Carvalho Chehab 	switch (state->props.bandwidth_hz) {
39219a0bf528SMauro Carvalho Chehab 	case 0:
39229a0bf528SMauro Carvalho Chehab 		state->props.bandwidth_hz = 8000000;
392306eeefe8SMauro Carvalho Chehab 		/* fall through */
39249a0bf528SMauro Carvalho Chehab 	case 8000000:
39259a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3926ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3927ab5060cdSMauro Carvalho Chehab 				 3052);
39289a0bf528SMauro Carvalho Chehab 		if (status < 0)
39299a0bf528SMauro Carvalho Chehab 			goto error;
39309a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 8 MHz */
3931ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3932ab5060cdSMauro Carvalho Chehab 				 7);
39339a0bf528SMauro Carvalho Chehab 		if (status < 0)
39349a0bf528SMauro Carvalho Chehab 			goto error;
3935ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3936ab5060cdSMauro Carvalho Chehab 				 7);
39379a0bf528SMauro Carvalho Chehab 		if (status < 0)
39389a0bf528SMauro Carvalho Chehab 			goto error;
3939ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3940ab5060cdSMauro Carvalho Chehab 				 7);
39419a0bf528SMauro Carvalho Chehab 		if (status < 0)
39429a0bf528SMauro Carvalho Chehab 			goto error;
3943ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3944ab5060cdSMauro Carvalho Chehab 				 1);
39459a0bf528SMauro Carvalho Chehab 		if (status < 0)
39469a0bf528SMauro Carvalho Chehab 			goto error;
39479a0bf528SMauro Carvalho Chehab 		break;
39489a0bf528SMauro Carvalho Chehab 	case 7000000:
39499a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3950ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3951ab5060cdSMauro Carvalho Chehab 				 3491);
39529a0bf528SMauro Carvalho Chehab 		if (status < 0)
39539a0bf528SMauro Carvalho Chehab 			goto error;
39549a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 7 MHz */
3955ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3956ab5060cdSMauro Carvalho Chehab 				 8);
39579a0bf528SMauro Carvalho Chehab 		if (status < 0)
39589a0bf528SMauro Carvalho Chehab 			goto error;
3959ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3960ab5060cdSMauro Carvalho Chehab 				 8);
39619a0bf528SMauro Carvalho Chehab 		if (status < 0)
39629a0bf528SMauro Carvalho Chehab 			goto error;
3963ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3964ab5060cdSMauro Carvalho Chehab 				 4);
39659a0bf528SMauro Carvalho Chehab 		if (status < 0)
39669a0bf528SMauro Carvalho Chehab 			goto error;
3967ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3968ab5060cdSMauro Carvalho Chehab 				 1);
39699a0bf528SMauro Carvalho Chehab 		if (status < 0)
39709a0bf528SMauro Carvalho Chehab 			goto error;
39719a0bf528SMauro Carvalho Chehab 		break;
39729a0bf528SMauro Carvalho Chehab 	case 6000000:
39739a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3974ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3975ab5060cdSMauro Carvalho Chehab 				 4073);
39769a0bf528SMauro Carvalho Chehab 		if (status < 0)
39779a0bf528SMauro Carvalho Chehab 			goto error;
39789a0bf528SMauro Carvalho Chehab 		/* cochannel protection for NTSC 6 MHz */
3979ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3980ab5060cdSMauro Carvalho Chehab 				 19);
39819a0bf528SMauro Carvalho Chehab 		if (status < 0)
39829a0bf528SMauro Carvalho Chehab 			goto error;
3983ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3984ab5060cdSMauro Carvalho Chehab 				 19);
39859a0bf528SMauro Carvalho Chehab 		if (status < 0)
39869a0bf528SMauro Carvalho Chehab 			goto error;
3987ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3988ab5060cdSMauro Carvalho Chehab 				 14);
39899a0bf528SMauro Carvalho Chehab 		if (status < 0)
39909a0bf528SMauro Carvalho Chehab 			goto error;
3991ab5060cdSMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3992ab5060cdSMauro Carvalho Chehab 				 1);
39939a0bf528SMauro Carvalho Chehab 		if (status < 0)
39949a0bf528SMauro Carvalho Chehab 			goto error;
39959a0bf528SMauro Carvalho Chehab 		break;
39969a0bf528SMauro Carvalho Chehab 	default:
39979a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
39989a0bf528SMauro Carvalho Chehab 		goto error;
39999a0bf528SMauro Carvalho Chehab 	}
40009a0bf528SMauro Carvalho Chehab 
4001cd7a67a4SMauro Carvalho Chehab 	if (iqm_rc_rate_ofs == 0) {
40029a0bf528SMauro Carvalho Chehab 		/* Now compute IQM_RC_RATE_OFS
40039a0bf528SMauro Carvalho Chehab 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
40049a0bf528SMauro Carvalho Chehab 			=>
40059a0bf528SMauro Carvalho Chehab 			((SysFreq / BandWidth) * (2^21)) - (2^23)
40069a0bf528SMauro Carvalho Chehab 			*/
40079a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^28)  */
4008ab5060cdSMauro Carvalho Chehab 		/*
4009ab5060cdSMauro Carvalho Chehab 		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
4010ab5060cdSMauro Carvalho Chehab 		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
4011ab5060cdSMauro Carvalho Chehab 		 *	=> assert(109714272 > 48000000) = true
4012ab5060cdSMauro Carvalho Chehab 		 * so Frac 28 can be used
4013ab5060cdSMauro Carvalho Chehab 		 */
4014cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = Frac28a((u32)
4015cd7a67a4SMauro Carvalho Chehab 					((state->m_sys_clock_freq *
40169a0bf528SMauro Carvalho Chehab 						1000) / 3), bandwidth);
40179a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4018cd7a67a4SMauro Carvalho Chehab 		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
4019cd7a67a4SMauro Carvalho Chehab 			iqm_rc_rate_ofs += 0x80L;
4020cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
40219a0bf528SMauro Carvalho Chehab 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
4022cd7a67a4SMauro Carvalho Chehab 		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
40239a0bf528SMauro Carvalho Chehab 	}
40249a0bf528SMauro Carvalho Chehab 
4025cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate_ofs &=
40269a0bf528SMauro Carvalho Chehab 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
40279a0bf528SMauro Carvalho Chehab 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4028cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
40299a0bf528SMauro Carvalho Chehab 	if (status < 0)
40309a0bf528SMauro Carvalho Chehab 		goto error;
40319a0bf528SMauro Carvalho Chehab 
40329a0bf528SMauro Carvalho Chehab 	/* Bandwidth setting done */
40339a0bf528SMauro Carvalho Chehab 
40349a0bf528SMauro Carvalho Chehab #if 0
4035cd7a67a4SMauro Carvalho Chehab 	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
40369a0bf528SMauro Carvalho Chehab 	if (status < 0)
40379a0bf528SMauro Carvalho Chehab 		goto error;
40389a0bf528SMauro Carvalho Chehab #endif
4039ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
4040ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
40419a0bf528SMauro Carvalho Chehab 	if (status < 0)
40429a0bf528SMauro Carvalho Chehab 		goto error;
40439a0bf528SMauro Carvalho Chehab 
4044ab5060cdSMauro Carvalho Chehab 	/*== start SC, write channel settings to SC ==========================*/
40459a0bf528SMauro Carvalho Chehab 
40469a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
40479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
40489a0bf528SMauro Carvalho Chehab 	if (status < 0)
40499a0bf528SMauro Carvalho Chehab 		goto error;
40509a0bf528SMauro Carvalho Chehab 
40519a0bf528SMauro Carvalho Chehab 	/* Enable SC after setting all other parameters */
40529a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_STATE__A, 0);
40539a0bf528SMauro Carvalho Chehab 	if (status < 0)
40549a0bf528SMauro Carvalho Chehab 		goto error;
40559a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
40569a0bf528SMauro Carvalho Chehab 	if (status < 0)
40579a0bf528SMauro Carvalho Chehab 		goto error;
40589a0bf528SMauro Carvalho Chehab 
40599a0bf528SMauro Carvalho Chehab 
4060ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4061ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
4062ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
40639a0bf528SMauro Carvalho Chehab 	if (status < 0)
40649a0bf528SMauro Carvalho Chehab 		goto error;
40659a0bf528SMauro Carvalho Chehab 
40669a0bf528SMauro Carvalho Chehab 	/* Write SC parameter registers, set all AUTO flags in operation mode */
40679a0bf528SMauro Carvalho Chehab 	param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
40689a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
40699a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
40709a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
40719a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4072cd7a67a4SMauro Carvalho Chehab 	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4073cd7a67a4SMauro Carvalho Chehab 				0, transmission_params, param1, 0, 0, 0);
40749a0bf528SMauro Carvalho Chehab 	if (status < 0)
40759a0bf528SMauro Carvalho Chehab 		goto error;
40769a0bf528SMauro Carvalho Chehab 
4077cd7a67a4SMauro Carvalho Chehab 	if (!state->m_drxk_a3_rom_code)
4078cd7a67a4SMauro Carvalho Chehab 		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
40799a0bf528SMauro Carvalho Chehab error:
40809a0bf528SMauro Carvalho Chehab 	if (status < 0)
40813a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
40829a0bf528SMauro Carvalho Chehab 
40839a0bf528SMauro Carvalho Chehab 	return status;
40849a0bf528SMauro Carvalho Chehab }
40859a0bf528SMauro Carvalho Chehab 
40869a0bf528SMauro Carvalho Chehab 
40879a0bf528SMauro Carvalho Chehab /*============================================================================*/
40889a0bf528SMauro Carvalho Chehab 
408934eb9751SMauro Carvalho Chehab /*
409039c1cb2bSJonathan McCrohan * \brief Retrieve lock status .
40919a0bf528SMauro Carvalho Chehab * \param demod    Pointer to demodulator instance.
40929a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
40939a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
40949a0bf528SMauro Carvalho Chehab *
40959a0bf528SMauro Carvalho Chehab */
4096cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
40979a0bf528SMauro Carvalho Chehab {
40989a0bf528SMauro Carvalho Chehab 	int status;
40999a0bf528SMauro Carvalho Chehab 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
41009a0bf528SMauro Carvalho Chehab 				    OFDM_SC_RA_RAM_LOCK_FEC__M);
41019a0bf528SMauro Carvalho Chehab 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
41029a0bf528SMauro Carvalho Chehab 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
41039a0bf528SMauro Carvalho Chehab 
4104cd7a67a4SMauro Carvalho Chehab 	u16 sc_ra_ram_lock = 0;
4105cd7a67a4SMauro Carvalho Chehab 	u16 sc_comm_exec = 0;
41069a0bf528SMauro Carvalho Chehab 
41079a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41089a0bf528SMauro Carvalho Chehab 
4109cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
41109a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
41119a0bf528SMauro Carvalho Chehab 	/* Check if SC is running */
4112cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
41139a0bf528SMauro Carvalho Chehab 	if (status < 0)
41149a0bf528SMauro Carvalho Chehab 		goto end;
4115cd7a67a4SMauro Carvalho Chehab 	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
41169a0bf528SMauro Carvalho Chehab 		goto end;
41179a0bf528SMauro Carvalho Chehab 
4118cd7a67a4SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
41199a0bf528SMauro Carvalho Chehab 	if (status < 0)
41209a0bf528SMauro Carvalho Chehab 		goto end;
41219a0bf528SMauro Carvalho Chehab 
4122cd7a67a4SMauro Carvalho Chehab 	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4123cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
4124cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4125cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = FEC_LOCK;
4126cd7a67a4SMauro Carvalho Chehab 	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4127cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
4128cd7a67a4SMauro Carvalho Chehab 	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4129cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
41309a0bf528SMauro Carvalho Chehab end:
41319a0bf528SMauro Carvalho Chehab 	if (status < 0)
41323a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41339a0bf528SMauro Carvalho Chehab 
41349a0bf528SMauro Carvalho Chehab 	return status;
41359a0bf528SMauro Carvalho Chehab }
41369a0bf528SMauro Carvalho Chehab 
4137cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state)
41389a0bf528SMauro Carvalho Chehab {
4139cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
41409a0bf528SMauro Carvalho Chehab 	int status;
41419a0bf528SMauro Carvalho Chehab 
41429a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
4143cd7a67a4SMauro Carvalho Chehab 	status = ctrl_power_mode(state, &power_mode);
41449a0bf528SMauro Carvalho Chehab 	if (status < 0)
41453a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41469a0bf528SMauro Carvalho Chehab 
41479a0bf528SMauro Carvalho Chehab 	return status;
41489a0bf528SMauro Carvalho Chehab }
41499a0bf528SMauro Carvalho Chehab 
41509a0bf528SMauro Carvalho Chehab 
415134eb9751SMauro Carvalho Chehab /* Power Down QAM */
4152cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state)
41539a0bf528SMauro Carvalho Chehab {
41549a0bf528SMauro Carvalho Chehab 	u16 data = 0;
4155cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
41569a0bf528SMauro Carvalho Chehab 	int status = 0;
41579a0bf528SMauro Carvalho Chehab 
41589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41599a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
41609a0bf528SMauro Carvalho Chehab 	if (status < 0)
41619a0bf528SMauro Carvalho Chehab 		goto error;
41629a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
41639a0bf528SMauro Carvalho Chehab 		/*
41649a0bf528SMauro Carvalho Chehab 			STOP demodulator
41659a0bf528SMauro Carvalho Chehab 			QAM and HW blocks
41669a0bf528SMauro Carvalho Chehab 			*/
41679a0bf528SMauro Carvalho Chehab 		/* stop all comstate->m_exec */
41689a0bf528SMauro Carvalho Chehab 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
41699a0bf528SMauro Carvalho Chehab 		if (status < 0)
41709a0bf528SMauro Carvalho Chehab 			goto error;
4171ab5060cdSMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4172ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4173ab5060cdSMauro Carvalho Chehab 				     0, NULL, 1, &cmd_result);
41749a0bf528SMauro Carvalho Chehab 		if (status < 0)
41759a0bf528SMauro Carvalho Chehab 			goto error;
41769a0bf528SMauro Carvalho Chehab 	}
41779a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
4178cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, false);
41799a0bf528SMauro Carvalho Chehab 
41809a0bf528SMauro Carvalho Chehab error:
41819a0bf528SMauro Carvalho Chehab 	if (status < 0)
41823a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
41839a0bf528SMauro Carvalho Chehab 
41849a0bf528SMauro Carvalho Chehab 	return status;
41859a0bf528SMauro Carvalho Chehab }
41869a0bf528SMauro Carvalho Chehab 
41879a0bf528SMauro Carvalho Chehab /*============================================================================*/
41889a0bf528SMauro Carvalho Chehab 
418934eb9751SMauro Carvalho Chehab /*
41909a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
41919a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
41929a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
41939a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41949a0bf528SMauro Carvalho Chehab *
41959a0bf528SMauro Carvalho Chehab *  NOTE:
41969a0bf528SMauro Carvalho Chehab *  Take into account that for certain settings the errorcounters can overflow.
41979a0bf528SMauro Carvalho Chehab *  The implementation does not check this.
41989a0bf528SMauro Carvalho Chehab *
41999a0bf528SMauro Carvalho Chehab */
4200cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state,
4201cd7a67a4SMauro Carvalho Chehab 			     enum e_drxk_constellation modulation,
4202cd7a67a4SMauro Carvalho Chehab 			     u32 symbol_rate)
42039a0bf528SMauro Carvalho Chehab {
4204cd7a67a4SMauro Carvalho Chehab 	u32 fec_bits_desired = 0;	/* BER accounting period */
4205cd7a67a4SMauro Carvalho Chehab 	u32 fec_rs_period_total = 0;	/* Total period */
4206cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
4207cd7a67a4SMauro Carvalho Chehab 	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
42089a0bf528SMauro Carvalho Chehab 	int status = 0;
42099a0bf528SMauro Carvalho Chehab 
42109a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42119a0bf528SMauro Carvalho Chehab 
4212cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1;
4213cd7a67a4SMauro Carvalho Chehab 	/* fec_bits_desired = symbol_rate [kHz] *
42149a0bf528SMauro Carvalho Chehab 		FrameLenght [ms] *
42159a0bf528SMauro Carvalho Chehab 		(modulation + 1) *
42169a0bf528SMauro Carvalho Chehab 		SyncLoss (== 1) *
42179a0bf528SMauro Carvalho Chehab 		ViterbiLoss (==1)
42189a0bf528SMauro Carvalho Chehab 		*/
42199a0bf528SMauro Carvalho Chehab 	switch (modulation) {
42209a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM16:
4221cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 4 * symbol_rate;
42229a0bf528SMauro Carvalho Chehab 		break;
42239a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM32:
4224cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 5 * symbol_rate;
42259a0bf528SMauro Carvalho Chehab 		break;
42269a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM64:
4227cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 6 * symbol_rate;
42289a0bf528SMauro Carvalho Chehab 		break;
42299a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM128:
4230cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 7 * symbol_rate;
42319a0bf528SMauro Carvalho Chehab 		break;
42329a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM256:
4233cd7a67a4SMauro Carvalho Chehab 		fec_bits_desired = 8 * symbol_rate;
42349a0bf528SMauro Carvalho Chehab 		break;
42359a0bf528SMauro Carvalho Chehab 	default:
42369a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42379a0bf528SMauro Carvalho Chehab 	}
42389a0bf528SMauro Carvalho Chehab 	if (status < 0)
42399a0bf528SMauro Carvalho Chehab 		goto error;
42409a0bf528SMauro Carvalho Chehab 
4241cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
4242cd7a67a4SMauro Carvalho Chehab 	fec_bits_desired *= 500;	/* meas. period [ms] */
42439a0bf528SMauro Carvalho Chehab 
42449a0bf528SMauro Carvalho Chehab 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4245cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total = fec_bits_desired / 1632 */
4246cd7a67a4SMauro Carvalho Chehab 	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
42479a0bf528SMauro Carvalho Chehab 
4248cd7a67a4SMauro Carvalho Chehab 	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
4249cd7a67a4SMauro Carvalho Chehab 	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4250cd7a67a4SMauro Carvalho Chehab 	if (fec_rs_prescale == 0) {
42519a0bf528SMauro Carvalho Chehab 		/* Divide by zero (though impossible) */
42529a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42539a0bf528SMauro Carvalho Chehab 		if (status < 0)
42549a0bf528SMauro Carvalho Chehab 			goto error;
42559a0bf528SMauro Carvalho Chehab 	}
4256cd7a67a4SMauro Carvalho Chehab 	fec_rs_period =
4257cd7a67a4SMauro Carvalho Chehab 		((u16) fec_rs_period_total +
4258cd7a67a4SMauro Carvalho Chehab 		(fec_rs_prescale >> 1)) / fec_rs_prescale;
42599a0bf528SMauro Carvalho Chehab 
42609a0bf528SMauro Carvalho Chehab 	/* write corresponding registers */
4261cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
42629a0bf528SMauro Carvalho Chehab 	if (status < 0)
42639a0bf528SMauro Carvalho Chehab 		goto error;
4264ab5060cdSMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4265ab5060cdSMauro Carvalho Chehab 			 fec_rs_prescale);
42669a0bf528SMauro Carvalho Chehab 	if (status < 0)
42679a0bf528SMauro Carvalho Chehab 		goto error;
4268cd7a67a4SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
42699a0bf528SMauro Carvalho Chehab error:
42709a0bf528SMauro Carvalho Chehab 	if (status < 0)
42713a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
42729a0bf528SMauro Carvalho Chehab 	return status;
42739a0bf528SMauro Carvalho Chehab }
42749a0bf528SMauro Carvalho Chehab 
4275cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state)
42769a0bf528SMauro Carvalho Chehab {
42779a0bf528SMauro Carvalho Chehab 	int status = 0;
42789a0bf528SMauro Carvalho Chehab 
42799a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42809a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
42819a0bf528SMauro Carvalho Chehab 	/* Equalizer */
42829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
42839a0bf528SMauro Carvalho Chehab 	if (status < 0)
42849a0bf528SMauro Carvalho Chehab 		goto error;
42859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
42869a0bf528SMauro Carvalho Chehab 	if (status < 0)
42879a0bf528SMauro Carvalho Chehab 		goto error;
42889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
42899a0bf528SMauro Carvalho Chehab 	if (status < 0)
42909a0bf528SMauro Carvalho Chehab 		goto error;
42919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
42929a0bf528SMauro Carvalho Chehab 	if (status < 0)
42939a0bf528SMauro Carvalho Chehab 		goto error;
42949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
42959a0bf528SMauro Carvalho Chehab 	if (status < 0)
42969a0bf528SMauro Carvalho Chehab 		goto error;
42979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
42989a0bf528SMauro Carvalho Chehab 	if (status < 0)
42999a0bf528SMauro Carvalho Chehab 		goto error;
43009a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
43019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
43029a0bf528SMauro Carvalho Chehab 	if (status < 0)
43039a0bf528SMauro Carvalho Chehab 		goto error;
43049a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
43059a0bf528SMauro Carvalho Chehab 	if (status < 0)
43069a0bf528SMauro Carvalho Chehab 		goto error;
43079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
43089a0bf528SMauro Carvalho Chehab 	if (status < 0)
43099a0bf528SMauro Carvalho Chehab 		goto error;
43109a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
43119a0bf528SMauro Carvalho Chehab 	if (status < 0)
43129a0bf528SMauro Carvalho Chehab 		goto error;
43139a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
43149a0bf528SMauro Carvalho Chehab 	if (status < 0)
43159a0bf528SMauro Carvalho Chehab 		goto error;
43169a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
43179a0bf528SMauro Carvalho Chehab 	if (status < 0)
43189a0bf528SMauro Carvalho Chehab 		goto error;
43199a0bf528SMauro Carvalho Chehab 
43209a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
43219a0bf528SMauro Carvalho Chehab 	if (status < 0)
43229a0bf528SMauro Carvalho Chehab 		goto error;
43239a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
43249a0bf528SMauro Carvalho Chehab 	if (status < 0)
43259a0bf528SMauro Carvalho Chehab 		goto error;
43269a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
43279a0bf528SMauro Carvalho Chehab 	if (status < 0)
43289a0bf528SMauro Carvalho Chehab 		goto error;
43299a0bf528SMauro Carvalho Chehab 
43309a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4331ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4332ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM16);
43339a0bf528SMauro Carvalho Chehab 	if (status < 0)
43349a0bf528SMauro Carvalho Chehab 		goto error;
43359a0bf528SMauro Carvalho Chehab 
43369a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
43379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
43389a0bf528SMauro Carvalho Chehab 	if (status < 0)
43399a0bf528SMauro Carvalho Chehab 		goto error;
43409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
43419a0bf528SMauro Carvalho Chehab 	if (status < 0)
43429a0bf528SMauro Carvalho Chehab 		goto error;
43439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
43449a0bf528SMauro Carvalho Chehab 	if (status < 0)
43459a0bf528SMauro Carvalho Chehab 		goto error;
43469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
43479a0bf528SMauro Carvalho Chehab 	if (status < 0)
43489a0bf528SMauro Carvalho Chehab 		goto error;
43499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
43509a0bf528SMauro Carvalho Chehab 	if (status < 0)
43519a0bf528SMauro Carvalho Chehab 		goto error;
43529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
43539a0bf528SMauro Carvalho Chehab 	if (status < 0)
43549a0bf528SMauro Carvalho Chehab 		goto error;
43559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
43569a0bf528SMauro Carvalho Chehab 	if (status < 0)
43579a0bf528SMauro Carvalho Chehab 		goto error;
43589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43599a0bf528SMauro Carvalho Chehab 	if (status < 0)
43609a0bf528SMauro Carvalho Chehab 		goto error;
43619a0bf528SMauro Carvalho Chehab 
43629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43639a0bf528SMauro Carvalho Chehab 	if (status < 0)
43649a0bf528SMauro Carvalho Chehab 		goto error;
43659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43669a0bf528SMauro Carvalho Chehab 	if (status < 0)
43679a0bf528SMauro Carvalho Chehab 		goto error;
43689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
43699a0bf528SMauro Carvalho Chehab 	if (status < 0)
43709a0bf528SMauro Carvalho Chehab 		goto error;
43719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
43729a0bf528SMauro Carvalho Chehab 	if (status < 0)
43739a0bf528SMauro Carvalho Chehab 		goto error;
43749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
43759a0bf528SMauro Carvalho Chehab 	if (status < 0)
43769a0bf528SMauro Carvalho Chehab 		goto error;
43779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
43789a0bf528SMauro Carvalho Chehab 	if (status < 0)
43799a0bf528SMauro Carvalho Chehab 		goto error;
43809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
43819a0bf528SMauro Carvalho Chehab 	if (status < 0)
43829a0bf528SMauro Carvalho Chehab 		goto error;
43839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
43849a0bf528SMauro Carvalho Chehab 	if (status < 0)
43859a0bf528SMauro Carvalho Chehab 		goto error;
43869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
43879a0bf528SMauro Carvalho Chehab 	if (status < 0)
43889a0bf528SMauro Carvalho Chehab 		goto error;
43899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
43909a0bf528SMauro Carvalho Chehab 	if (status < 0)
43919a0bf528SMauro Carvalho Chehab 		goto error;
43929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
43939a0bf528SMauro Carvalho Chehab 	if (status < 0)
43949a0bf528SMauro Carvalho Chehab 		goto error;
43959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
43969a0bf528SMauro Carvalho Chehab 	if (status < 0)
43979a0bf528SMauro Carvalho Chehab 		goto error;
43989a0bf528SMauro Carvalho Chehab 
43999a0bf528SMauro Carvalho Chehab 
44009a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
44019a0bf528SMauro Carvalho Chehab 
44029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
44039a0bf528SMauro Carvalho Chehab 	if (status < 0)
44049a0bf528SMauro Carvalho Chehab 		goto error;
44059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
44069a0bf528SMauro Carvalho Chehab 	if (status < 0)
44079a0bf528SMauro Carvalho Chehab 		goto error;
44089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
44099a0bf528SMauro Carvalho Chehab 	if (status < 0)
44109a0bf528SMauro Carvalho Chehab 		goto error;
44119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
44129a0bf528SMauro Carvalho Chehab 	if (status < 0)
44139a0bf528SMauro Carvalho Chehab 		goto error;
44149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
44159a0bf528SMauro Carvalho Chehab 	if (status < 0)
44169a0bf528SMauro Carvalho Chehab 		goto error;
44179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
44189a0bf528SMauro Carvalho Chehab 	if (status < 0)
44199a0bf528SMauro Carvalho Chehab 		goto error;
44209a0bf528SMauro Carvalho Chehab 
44219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
44229a0bf528SMauro Carvalho Chehab 	if (status < 0)
44239a0bf528SMauro Carvalho Chehab 		goto error;
44249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
44259a0bf528SMauro Carvalho Chehab 	if (status < 0)
44269a0bf528SMauro Carvalho Chehab 		goto error;
44279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
44289a0bf528SMauro Carvalho Chehab 	if (status < 0)
44299a0bf528SMauro Carvalho Chehab 		goto error;
44309a0bf528SMauro Carvalho Chehab 
44319a0bf528SMauro Carvalho Chehab 
44329a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
44339a0bf528SMauro Carvalho Chehab 
44349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
44359a0bf528SMauro Carvalho Chehab 	if (status < 0)
44369a0bf528SMauro Carvalho Chehab 		goto error;
44379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
44389a0bf528SMauro Carvalho Chehab 	if (status < 0)
44399a0bf528SMauro Carvalho Chehab 		goto error;
44409a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
44419a0bf528SMauro Carvalho Chehab 	if (status < 0)
44429a0bf528SMauro Carvalho Chehab 		goto error;
44439a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
44449a0bf528SMauro Carvalho Chehab 	if (status < 0)
44459a0bf528SMauro Carvalho Chehab 		goto error;
44469a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
44479a0bf528SMauro Carvalho Chehab 	if (status < 0)
44489a0bf528SMauro Carvalho Chehab 		goto error;
44499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
44509a0bf528SMauro Carvalho Chehab 	if (status < 0)
44519a0bf528SMauro Carvalho Chehab 		goto error;
44529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
44539a0bf528SMauro Carvalho Chehab 	if (status < 0)
44549a0bf528SMauro Carvalho Chehab 		goto error;
44559a0bf528SMauro Carvalho Chehab 
44569a0bf528SMauro Carvalho Chehab error:
44579a0bf528SMauro Carvalho Chehab 	if (status < 0)
44583a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
44599a0bf528SMauro Carvalho Chehab 	return status;
44609a0bf528SMauro Carvalho Chehab }
44619a0bf528SMauro Carvalho Chehab 
44629a0bf528SMauro Carvalho Chehab /*============================================================================*/
44639a0bf528SMauro Carvalho Chehab 
446434eb9751SMauro Carvalho Chehab /*
44659a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44669a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
44679a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
44689a0bf528SMauro Carvalho Chehab */
4469cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state)
44709a0bf528SMauro Carvalho Chehab {
44719a0bf528SMauro Carvalho Chehab 	int status = 0;
44729a0bf528SMauro Carvalho Chehab 
44739a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
44749a0bf528SMauro Carvalho Chehab 
44759a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
44769a0bf528SMauro Carvalho Chehab 	/* Equalizer */
44779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
44789a0bf528SMauro Carvalho Chehab 	if (status < 0)
44799a0bf528SMauro Carvalho Chehab 		goto error;
44809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
44819a0bf528SMauro Carvalho Chehab 	if (status < 0)
44829a0bf528SMauro Carvalho Chehab 		goto error;
44839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
44849a0bf528SMauro Carvalho Chehab 	if (status < 0)
44859a0bf528SMauro Carvalho Chehab 		goto error;
44869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
44879a0bf528SMauro Carvalho Chehab 	if (status < 0)
44889a0bf528SMauro Carvalho Chehab 		goto error;
44899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
44909a0bf528SMauro Carvalho Chehab 	if (status < 0)
44919a0bf528SMauro Carvalho Chehab 		goto error;
44929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
44939a0bf528SMauro Carvalho Chehab 	if (status < 0)
44949a0bf528SMauro Carvalho Chehab 		goto error;
44959a0bf528SMauro Carvalho Chehab 
44969a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
44979a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
44989a0bf528SMauro Carvalho Chehab 	if (status < 0)
44999a0bf528SMauro Carvalho Chehab 		goto error;
45009a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
45019a0bf528SMauro Carvalho Chehab 	if (status < 0)
45029a0bf528SMauro Carvalho Chehab 		goto error;
45039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
45049a0bf528SMauro Carvalho Chehab 	if (status < 0)
45059a0bf528SMauro Carvalho Chehab 		goto error;
45069a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
45079a0bf528SMauro Carvalho Chehab 	if (status < 0)
45089a0bf528SMauro Carvalho Chehab 		goto error;
45099a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
45109a0bf528SMauro Carvalho Chehab 	if (status < 0)
45119a0bf528SMauro Carvalho Chehab 		goto error;
45129a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
45139a0bf528SMauro Carvalho Chehab 	if (status < 0)
45149a0bf528SMauro Carvalho Chehab 		goto error;
45159a0bf528SMauro Carvalho Chehab 
45169a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
45179a0bf528SMauro Carvalho Chehab 	if (status < 0)
45189a0bf528SMauro Carvalho Chehab 		goto error;
45199a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
45209a0bf528SMauro Carvalho Chehab 	if (status < 0)
45219a0bf528SMauro Carvalho Chehab 		goto error;
45229a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
45239a0bf528SMauro Carvalho Chehab 	if (status < 0)
45249a0bf528SMauro Carvalho Chehab 		goto error;
45259a0bf528SMauro Carvalho Chehab 
45269a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
45279a0bf528SMauro Carvalho Chehab 
4528ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4529ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM32);
45309a0bf528SMauro Carvalho Chehab 	if (status < 0)
45319a0bf528SMauro Carvalho Chehab 		goto error;
45329a0bf528SMauro Carvalho Chehab 
45339a0bf528SMauro Carvalho Chehab 
45349a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
45359a0bf528SMauro Carvalho Chehab 
45369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
45379a0bf528SMauro Carvalho Chehab 	if (status < 0)
45389a0bf528SMauro Carvalho Chehab 		goto error;
45399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
45409a0bf528SMauro Carvalho Chehab 	if (status < 0)
45419a0bf528SMauro Carvalho Chehab 		goto error;
45429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
45439a0bf528SMauro Carvalho Chehab 	if (status < 0)
45449a0bf528SMauro Carvalho Chehab 		goto error;
45459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
45469a0bf528SMauro Carvalho Chehab 	if (status < 0)
45479a0bf528SMauro Carvalho Chehab 		goto error;
45489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
45499a0bf528SMauro Carvalho Chehab 	if (status < 0)
45509a0bf528SMauro Carvalho Chehab 		goto error;
45519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
45529a0bf528SMauro Carvalho Chehab 	if (status < 0)
45539a0bf528SMauro Carvalho Chehab 		goto error;
45549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
45559a0bf528SMauro Carvalho Chehab 	if (status < 0)
45569a0bf528SMauro Carvalho Chehab 		goto error;
45579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
45589a0bf528SMauro Carvalho Chehab 	if (status < 0)
45599a0bf528SMauro Carvalho Chehab 		goto error;
45609a0bf528SMauro Carvalho Chehab 
45619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45629a0bf528SMauro Carvalho Chehab 	if (status < 0)
45639a0bf528SMauro Carvalho Chehab 		goto error;
45649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45659a0bf528SMauro Carvalho Chehab 	if (status < 0)
45669a0bf528SMauro Carvalho Chehab 		goto error;
45679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
45689a0bf528SMauro Carvalho Chehab 	if (status < 0)
45699a0bf528SMauro Carvalho Chehab 		goto error;
45709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
45719a0bf528SMauro Carvalho Chehab 	if (status < 0)
45729a0bf528SMauro Carvalho Chehab 		goto error;
45739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
45749a0bf528SMauro Carvalho Chehab 	if (status < 0)
45759a0bf528SMauro Carvalho Chehab 		goto error;
45769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
45779a0bf528SMauro Carvalho Chehab 	if (status < 0)
45789a0bf528SMauro Carvalho Chehab 		goto error;
45799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
45809a0bf528SMauro Carvalho Chehab 	if (status < 0)
45819a0bf528SMauro Carvalho Chehab 		goto error;
45829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
45839a0bf528SMauro Carvalho Chehab 	if (status < 0)
45849a0bf528SMauro Carvalho Chehab 		goto error;
45859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
45869a0bf528SMauro Carvalho Chehab 	if (status < 0)
45879a0bf528SMauro Carvalho Chehab 		goto error;
45889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
45899a0bf528SMauro Carvalho Chehab 	if (status < 0)
45909a0bf528SMauro Carvalho Chehab 		goto error;
45919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
45929a0bf528SMauro Carvalho Chehab 	if (status < 0)
45939a0bf528SMauro Carvalho Chehab 		goto error;
45949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
45959a0bf528SMauro Carvalho Chehab 	if (status < 0)
45969a0bf528SMauro Carvalho Chehab 		goto error;
45979a0bf528SMauro Carvalho Chehab 
45989a0bf528SMauro Carvalho Chehab 
45999a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
46009a0bf528SMauro Carvalho Chehab 
46019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
46029a0bf528SMauro Carvalho Chehab 	if (status < 0)
46039a0bf528SMauro Carvalho Chehab 		goto error;
46049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
46059a0bf528SMauro Carvalho Chehab 	if (status < 0)
46069a0bf528SMauro Carvalho Chehab 		goto error;
46079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
46089a0bf528SMauro Carvalho Chehab 	if (status < 0)
46099a0bf528SMauro Carvalho Chehab 		goto error;
46109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
46119a0bf528SMauro Carvalho Chehab 	if (status < 0)
46129a0bf528SMauro Carvalho Chehab 		goto error;
46139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
46149a0bf528SMauro Carvalho Chehab 	if (status < 0)
46159a0bf528SMauro Carvalho Chehab 		goto error;
46169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
46179a0bf528SMauro Carvalho Chehab 	if (status < 0)
46189a0bf528SMauro Carvalho Chehab 		goto error;
46199a0bf528SMauro Carvalho Chehab 
46209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
46219a0bf528SMauro Carvalho Chehab 	if (status < 0)
46229a0bf528SMauro Carvalho Chehab 		goto error;
46239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
46249a0bf528SMauro Carvalho Chehab 	if (status < 0)
46259a0bf528SMauro Carvalho Chehab 		goto error;
46269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
46279a0bf528SMauro Carvalho Chehab 	if (status < 0)
46289a0bf528SMauro Carvalho Chehab 		goto error;
46299a0bf528SMauro Carvalho Chehab 
46309a0bf528SMauro Carvalho Chehab 
46319a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
46329a0bf528SMauro Carvalho Chehab 
46339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
46349a0bf528SMauro Carvalho Chehab 	if (status < 0)
46359a0bf528SMauro Carvalho Chehab 		goto error;
46369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
46379a0bf528SMauro Carvalho Chehab 	if (status < 0)
46389a0bf528SMauro Carvalho Chehab 		goto error;
46399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
46409a0bf528SMauro Carvalho Chehab 	if (status < 0)
46419a0bf528SMauro Carvalho Chehab 		goto error;
46429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
46439a0bf528SMauro Carvalho Chehab 	if (status < 0)
46449a0bf528SMauro Carvalho Chehab 		goto error;
46459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
46469a0bf528SMauro Carvalho Chehab 	if (status < 0)
46479a0bf528SMauro Carvalho Chehab 		goto error;
46489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
46499a0bf528SMauro Carvalho Chehab 	if (status < 0)
46509a0bf528SMauro Carvalho Chehab 		goto error;
46519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
46529a0bf528SMauro Carvalho Chehab error:
46539a0bf528SMauro Carvalho Chehab 	if (status < 0)
46543a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
46559a0bf528SMauro Carvalho Chehab 	return status;
46569a0bf528SMauro Carvalho Chehab }
46579a0bf528SMauro Carvalho Chehab 
46589a0bf528SMauro Carvalho Chehab /*============================================================================*/
46599a0bf528SMauro Carvalho Chehab 
466034eb9751SMauro Carvalho Chehab /*
46619a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46629a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46639a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46649a0bf528SMauro Carvalho Chehab */
4665cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state)
46669a0bf528SMauro Carvalho Chehab {
46679a0bf528SMauro Carvalho Chehab 	int status = 0;
46689a0bf528SMauro Carvalho Chehab 
46699a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
46709a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
46719a0bf528SMauro Carvalho Chehab 	/* Equalizer */
46729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
46739a0bf528SMauro Carvalho Chehab 	if (status < 0)
46749a0bf528SMauro Carvalho Chehab 		goto error;
46759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
46769a0bf528SMauro Carvalho Chehab 	if (status < 0)
46779a0bf528SMauro Carvalho Chehab 		goto error;
46789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
46799a0bf528SMauro Carvalho Chehab 	if (status < 0)
46809a0bf528SMauro Carvalho Chehab 		goto error;
46819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
46829a0bf528SMauro Carvalho Chehab 	if (status < 0)
46839a0bf528SMauro Carvalho Chehab 		goto error;
46849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
46859a0bf528SMauro Carvalho Chehab 	if (status < 0)
46869a0bf528SMauro Carvalho Chehab 		goto error;
46879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
46889a0bf528SMauro Carvalho Chehab 	if (status < 0)
46899a0bf528SMauro Carvalho Chehab 		goto error;
46909a0bf528SMauro Carvalho Chehab 
46919a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
46929a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
46939a0bf528SMauro Carvalho Chehab 	if (status < 0)
46949a0bf528SMauro Carvalho Chehab 		goto error;
46959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
46969a0bf528SMauro Carvalho Chehab 	if (status < 0)
46979a0bf528SMauro Carvalho Chehab 		goto error;
46989a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
46999a0bf528SMauro Carvalho Chehab 	if (status < 0)
47009a0bf528SMauro Carvalho Chehab 		goto error;
47019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
47029a0bf528SMauro Carvalho Chehab 	if (status < 0)
47039a0bf528SMauro Carvalho Chehab 		goto error;
47049a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
47059a0bf528SMauro Carvalho Chehab 	if (status < 0)
47069a0bf528SMauro Carvalho Chehab 		goto error;
47079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
47089a0bf528SMauro Carvalho Chehab 	if (status < 0)
47099a0bf528SMauro Carvalho Chehab 		goto error;
47109a0bf528SMauro Carvalho Chehab 
47119a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
47129a0bf528SMauro Carvalho Chehab 	if (status < 0)
47139a0bf528SMauro Carvalho Chehab 		goto error;
47149a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
47159a0bf528SMauro Carvalho Chehab 	if (status < 0)
47169a0bf528SMauro Carvalho Chehab 		goto error;
47179a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
47189a0bf528SMauro Carvalho Chehab 	if (status < 0)
47199a0bf528SMauro Carvalho Chehab 		goto error;
47209a0bf528SMauro Carvalho Chehab 
47219a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
4722ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4723ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM64);
47249a0bf528SMauro Carvalho Chehab 	if (status < 0)
47259a0bf528SMauro Carvalho Chehab 		goto error;
47269a0bf528SMauro Carvalho Chehab 
47279a0bf528SMauro Carvalho Chehab 
47289a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
47299a0bf528SMauro Carvalho Chehab 
47309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
47319a0bf528SMauro Carvalho Chehab 	if (status < 0)
47329a0bf528SMauro Carvalho Chehab 		goto error;
47339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
47349a0bf528SMauro Carvalho Chehab 	if (status < 0)
47359a0bf528SMauro Carvalho Chehab 		goto error;
47369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
47379a0bf528SMauro Carvalho Chehab 	if (status < 0)
47389a0bf528SMauro Carvalho Chehab 		goto error;
47399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
47409a0bf528SMauro Carvalho Chehab 	if (status < 0)
47419a0bf528SMauro Carvalho Chehab 		goto error;
47429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
47439a0bf528SMauro Carvalho Chehab 	if (status < 0)
47449a0bf528SMauro Carvalho Chehab 		goto error;
47459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
47469a0bf528SMauro Carvalho Chehab 	if (status < 0)
47479a0bf528SMauro Carvalho Chehab 		goto error;
47489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
47499a0bf528SMauro Carvalho Chehab 	if (status < 0)
47509a0bf528SMauro Carvalho Chehab 		goto error;
47519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
47529a0bf528SMauro Carvalho Chehab 	if (status < 0)
47539a0bf528SMauro Carvalho Chehab 		goto error;
47549a0bf528SMauro Carvalho Chehab 
47559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
47569a0bf528SMauro Carvalho Chehab 	if (status < 0)
47579a0bf528SMauro Carvalho Chehab 		goto error;
47589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47599a0bf528SMauro Carvalho Chehab 	if (status < 0)
47609a0bf528SMauro Carvalho Chehab 		goto error;
47619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47629a0bf528SMauro Carvalho Chehab 	if (status < 0)
47639a0bf528SMauro Carvalho Chehab 		goto error;
47649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47659a0bf528SMauro Carvalho Chehab 	if (status < 0)
47669a0bf528SMauro Carvalho Chehab 		goto error;
47679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47689a0bf528SMauro Carvalho Chehab 	if (status < 0)
47699a0bf528SMauro Carvalho Chehab 		goto error;
47709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
47719a0bf528SMauro Carvalho Chehab 	if (status < 0)
47729a0bf528SMauro Carvalho Chehab 		goto error;
47739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
47749a0bf528SMauro Carvalho Chehab 	if (status < 0)
47759a0bf528SMauro Carvalho Chehab 		goto error;
47769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
47779a0bf528SMauro Carvalho Chehab 	if (status < 0)
47789a0bf528SMauro Carvalho Chehab 		goto error;
47799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
47809a0bf528SMauro Carvalho Chehab 	if (status < 0)
47819a0bf528SMauro Carvalho Chehab 		goto error;
47829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
47839a0bf528SMauro Carvalho Chehab 	if (status < 0)
47849a0bf528SMauro Carvalho Chehab 		goto error;
47859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
47869a0bf528SMauro Carvalho Chehab 	if (status < 0)
47879a0bf528SMauro Carvalho Chehab 		goto error;
47889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
47899a0bf528SMauro Carvalho Chehab 	if (status < 0)
47909a0bf528SMauro Carvalho Chehab 		goto error;
47919a0bf528SMauro Carvalho Chehab 
47929a0bf528SMauro Carvalho Chehab 
47939a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
47949a0bf528SMauro Carvalho Chehab 
47959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
47969a0bf528SMauro Carvalho Chehab 	if (status < 0)
47979a0bf528SMauro Carvalho Chehab 		goto error;
47989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
47999a0bf528SMauro Carvalho Chehab 	if (status < 0)
48009a0bf528SMauro Carvalho Chehab 		goto error;
48019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
48029a0bf528SMauro Carvalho Chehab 	if (status < 0)
48039a0bf528SMauro Carvalho Chehab 		goto error;
48049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
48059a0bf528SMauro Carvalho Chehab 	if (status < 0)
48069a0bf528SMauro Carvalho Chehab 		goto error;
48079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
48089a0bf528SMauro Carvalho Chehab 	if (status < 0)
48099a0bf528SMauro Carvalho Chehab 		goto error;
48109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
48119a0bf528SMauro Carvalho Chehab 	if (status < 0)
48129a0bf528SMauro Carvalho Chehab 		goto error;
48139a0bf528SMauro Carvalho Chehab 
48149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
48159a0bf528SMauro Carvalho Chehab 	if (status < 0)
48169a0bf528SMauro Carvalho Chehab 		goto error;
48179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
48189a0bf528SMauro Carvalho Chehab 	if (status < 0)
48199a0bf528SMauro Carvalho Chehab 		goto error;
48209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
48219a0bf528SMauro Carvalho Chehab 	if (status < 0)
48229a0bf528SMauro Carvalho Chehab 		goto error;
48239a0bf528SMauro Carvalho Chehab 
48249a0bf528SMauro Carvalho Chehab 
48259a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
48269a0bf528SMauro Carvalho Chehab 
48279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
48289a0bf528SMauro Carvalho Chehab 	if (status < 0)
48299a0bf528SMauro Carvalho Chehab 		goto error;
48309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
48319a0bf528SMauro Carvalho Chehab 	if (status < 0)
48329a0bf528SMauro Carvalho Chehab 		goto error;
48339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
48349a0bf528SMauro Carvalho Chehab 	if (status < 0)
48359a0bf528SMauro Carvalho Chehab 		goto error;
48369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
48379a0bf528SMauro Carvalho Chehab 	if (status < 0)
48389a0bf528SMauro Carvalho Chehab 		goto error;
48399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
48409a0bf528SMauro Carvalho Chehab 	if (status < 0)
48419a0bf528SMauro Carvalho Chehab 		goto error;
48429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
48439a0bf528SMauro Carvalho Chehab 	if (status < 0)
48449a0bf528SMauro Carvalho Chehab 		goto error;
48459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
48469a0bf528SMauro Carvalho Chehab error:
48479a0bf528SMauro Carvalho Chehab 	if (status < 0)
48483a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
48499a0bf528SMauro Carvalho Chehab 
48509a0bf528SMauro Carvalho Chehab 	return status;
48519a0bf528SMauro Carvalho Chehab }
48529a0bf528SMauro Carvalho Chehab 
48539a0bf528SMauro Carvalho Chehab /*============================================================================*/
48549a0bf528SMauro Carvalho Chehab 
485534eb9751SMauro Carvalho Chehab /*
48569a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
48579a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
48589a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48599a0bf528SMauro Carvalho Chehab */
4860cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state)
48619a0bf528SMauro Carvalho Chehab {
48629a0bf528SMauro Carvalho Chehab 	int status = 0;
48639a0bf528SMauro Carvalho Chehab 
48649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
48659a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
48669a0bf528SMauro Carvalho Chehab 	/* Equalizer */
48679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48689a0bf528SMauro Carvalho Chehab 	if (status < 0)
48699a0bf528SMauro Carvalho Chehab 		goto error;
48709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
48719a0bf528SMauro Carvalho Chehab 	if (status < 0)
48729a0bf528SMauro Carvalho Chehab 		goto error;
48739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
48749a0bf528SMauro Carvalho Chehab 	if (status < 0)
48759a0bf528SMauro Carvalho Chehab 		goto error;
48769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
48779a0bf528SMauro Carvalho Chehab 	if (status < 0)
48789a0bf528SMauro Carvalho Chehab 		goto error;
48799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
48809a0bf528SMauro Carvalho Chehab 	if (status < 0)
48819a0bf528SMauro Carvalho Chehab 		goto error;
48829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
48839a0bf528SMauro Carvalho Chehab 	if (status < 0)
48849a0bf528SMauro Carvalho Chehab 		goto error;
48859a0bf528SMauro Carvalho Chehab 
48869a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
48879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
48889a0bf528SMauro Carvalho Chehab 	if (status < 0)
48899a0bf528SMauro Carvalho Chehab 		goto error;
48909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
48919a0bf528SMauro Carvalho Chehab 	if (status < 0)
48929a0bf528SMauro Carvalho Chehab 		goto error;
48939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
48949a0bf528SMauro Carvalho Chehab 	if (status < 0)
48959a0bf528SMauro Carvalho Chehab 		goto error;
48969a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
48979a0bf528SMauro Carvalho Chehab 	if (status < 0)
48989a0bf528SMauro Carvalho Chehab 		goto error;
48999a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
49009a0bf528SMauro Carvalho Chehab 	if (status < 0)
49019a0bf528SMauro Carvalho Chehab 		goto error;
49029a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
49039a0bf528SMauro Carvalho Chehab 	if (status < 0)
49049a0bf528SMauro Carvalho Chehab 		goto error;
49059a0bf528SMauro Carvalho Chehab 
49069a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
49079a0bf528SMauro Carvalho Chehab 	if (status < 0)
49089a0bf528SMauro Carvalho Chehab 		goto error;
49099a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
49109a0bf528SMauro Carvalho Chehab 	if (status < 0)
49119a0bf528SMauro Carvalho Chehab 		goto error;
49129a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
49139a0bf528SMauro Carvalho Chehab 	if (status < 0)
49149a0bf528SMauro Carvalho Chehab 		goto error;
49159a0bf528SMauro Carvalho Chehab 
49169a0bf528SMauro Carvalho Chehab 
49179a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
49189a0bf528SMauro Carvalho Chehab 
4919ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4920ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM128);
49219a0bf528SMauro Carvalho Chehab 	if (status < 0)
49229a0bf528SMauro Carvalho Chehab 		goto error;
49239a0bf528SMauro Carvalho Chehab 
49249a0bf528SMauro Carvalho Chehab 
49259a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
49269a0bf528SMauro Carvalho Chehab 
49279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
49289a0bf528SMauro Carvalho Chehab 	if (status < 0)
49299a0bf528SMauro Carvalho Chehab 		goto error;
49309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
49319a0bf528SMauro Carvalho Chehab 	if (status < 0)
49329a0bf528SMauro Carvalho Chehab 		goto error;
49339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
49349a0bf528SMauro Carvalho Chehab 	if (status < 0)
49359a0bf528SMauro Carvalho Chehab 		goto error;
49369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
49379a0bf528SMauro Carvalho Chehab 	if (status < 0)
49389a0bf528SMauro Carvalho Chehab 		goto error;
49399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
49409a0bf528SMauro Carvalho Chehab 	if (status < 0)
49419a0bf528SMauro Carvalho Chehab 		goto error;
49429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
49439a0bf528SMauro Carvalho Chehab 	if (status < 0)
49449a0bf528SMauro Carvalho Chehab 		goto error;
49459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
49469a0bf528SMauro Carvalho Chehab 	if (status < 0)
49479a0bf528SMauro Carvalho Chehab 		goto error;
49489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
49499a0bf528SMauro Carvalho Chehab 	if (status < 0)
49509a0bf528SMauro Carvalho Chehab 		goto error;
49519a0bf528SMauro Carvalho Chehab 
49529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
49539a0bf528SMauro Carvalho Chehab 	if (status < 0)
49549a0bf528SMauro Carvalho Chehab 		goto error;
49559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
49569a0bf528SMauro Carvalho Chehab 	if (status < 0)
49579a0bf528SMauro Carvalho Chehab 		goto error;
49589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49599a0bf528SMauro Carvalho Chehab 	if (status < 0)
49609a0bf528SMauro Carvalho Chehab 		goto error;
49619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49629a0bf528SMauro Carvalho Chehab 	if (status < 0)
49639a0bf528SMauro Carvalho Chehab 		goto error;
49649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49659a0bf528SMauro Carvalho Chehab 	if (status < 0)
49669a0bf528SMauro Carvalho Chehab 		goto error;
49679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49689a0bf528SMauro Carvalho Chehab 	if (status < 0)
49699a0bf528SMauro Carvalho Chehab 		goto error;
49709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
49719a0bf528SMauro Carvalho Chehab 	if (status < 0)
49729a0bf528SMauro Carvalho Chehab 		goto error;
49739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
49749a0bf528SMauro Carvalho Chehab 	if (status < 0)
49759a0bf528SMauro Carvalho Chehab 		goto error;
49769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
49779a0bf528SMauro Carvalho Chehab 	if (status < 0)
49789a0bf528SMauro Carvalho Chehab 		goto error;
49799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
49809a0bf528SMauro Carvalho Chehab 	if (status < 0)
49819a0bf528SMauro Carvalho Chehab 		goto error;
49829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
49839a0bf528SMauro Carvalho Chehab 	if (status < 0)
49849a0bf528SMauro Carvalho Chehab 		goto error;
49859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
49869a0bf528SMauro Carvalho Chehab 	if (status < 0)
49879a0bf528SMauro Carvalho Chehab 		goto error;
49889a0bf528SMauro Carvalho Chehab 
49899a0bf528SMauro Carvalho Chehab 
49909a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
49919a0bf528SMauro Carvalho Chehab 
49929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
49939a0bf528SMauro Carvalho Chehab 	if (status < 0)
49949a0bf528SMauro Carvalho Chehab 		goto error;
49959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
49969a0bf528SMauro Carvalho Chehab 	if (status < 0)
49979a0bf528SMauro Carvalho Chehab 		goto error;
49989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
49999a0bf528SMauro Carvalho Chehab 	if (status < 0)
50009a0bf528SMauro Carvalho Chehab 		goto error;
50019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
50029a0bf528SMauro Carvalho Chehab 	if (status < 0)
50039a0bf528SMauro Carvalho Chehab 		goto error;
50049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
50059a0bf528SMauro Carvalho Chehab 	if (status < 0)
50069a0bf528SMauro Carvalho Chehab 		goto error;
50079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
50089a0bf528SMauro Carvalho Chehab 	if (status < 0)
50099a0bf528SMauro Carvalho Chehab 		goto error;
50109a0bf528SMauro Carvalho Chehab 
50119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
50129a0bf528SMauro Carvalho Chehab 	if (status < 0)
50139a0bf528SMauro Carvalho Chehab 		goto error;
50149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
50159a0bf528SMauro Carvalho Chehab 	if (status < 0)
50169a0bf528SMauro Carvalho Chehab 		goto error;
50179a0bf528SMauro Carvalho Chehab 
50189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
50199a0bf528SMauro Carvalho Chehab 	if (status < 0)
50209a0bf528SMauro Carvalho Chehab 		goto error;
50219a0bf528SMauro Carvalho Chehab 
50229a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
50239a0bf528SMauro Carvalho Chehab 
50249a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
50259a0bf528SMauro Carvalho Chehab 	if (status < 0)
50269a0bf528SMauro Carvalho Chehab 		goto error;
50279a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
50289a0bf528SMauro Carvalho Chehab 	if (status < 0)
50299a0bf528SMauro Carvalho Chehab 		goto error;
50309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
50319a0bf528SMauro Carvalho Chehab 	if (status < 0)
50329a0bf528SMauro Carvalho Chehab 		goto error;
50339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
50349a0bf528SMauro Carvalho Chehab 	if (status < 0)
50359a0bf528SMauro Carvalho Chehab 		goto error;
50369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
50379a0bf528SMauro Carvalho Chehab 	if (status < 0)
50389a0bf528SMauro Carvalho Chehab 		goto error;
50399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
50409a0bf528SMauro Carvalho Chehab 	if (status < 0)
50419a0bf528SMauro Carvalho Chehab 		goto error;
50429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
50439a0bf528SMauro Carvalho Chehab error:
50449a0bf528SMauro Carvalho Chehab 	if (status < 0)
50453a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
50469a0bf528SMauro Carvalho Chehab 
50479a0bf528SMauro Carvalho Chehab 	return status;
50489a0bf528SMauro Carvalho Chehab }
50499a0bf528SMauro Carvalho Chehab 
50509a0bf528SMauro Carvalho Chehab /*============================================================================*/
50519a0bf528SMauro Carvalho Chehab 
505234eb9751SMauro Carvalho Chehab /*
50539a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
50549a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
50559a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
50569a0bf528SMauro Carvalho Chehab */
5057cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state)
50589a0bf528SMauro Carvalho Chehab {
50599a0bf528SMauro Carvalho Chehab 	int status = 0;
50609a0bf528SMauro Carvalho Chehab 
50619a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
50629a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
50639a0bf528SMauro Carvalho Chehab 	/* Equalizer */
50649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50659a0bf528SMauro Carvalho Chehab 	if (status < 0)
50669a0bf528SMauro Carvalho Chehab 		goto error;
50679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50689a0bf528SMauro Carvalho Chehab 	if (status < 0)
50699a0bf528SMauro Carvalho Chehab 		goto error;
50709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
50719a0bf528SMauro Carvalho Chehab 	if (status < 0)
50729a0bf528SMauro Carvalho Chehab 		goto error;
50739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
50749a0bf528SMauro Carvalho Chehab 	if (status < 0)
50759a0bf528SMauro Carvalho Chehab 		goto error;
50769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
50779a0bf528SMauro Carvalho Chehab 	if (status < 0)
50789a0bf528SMauro Carvalho Chehab 		goto error;
50799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
50809a0bf528SMauro Carvalho Chehab 	if (status < 0)
50819a0bf528SMauro Carvalho Chehab 		goto error;
50829a0bf528SMauro Carvalho Chehab 
50839a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
50849a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
50859a0bf528SMauro Carvalho Chehab 	if (status < 0)
50869a0bf528SMauro Carvalho Chehab 		goto error;
50879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
50889a0bf528SMauro Carvalho Chehab 	if (status < 0)
50899a0bf528SMauro Carvalho Chehab 		goto error;
50909a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
50919a0bf528SMauro Carvalho Chehab 	if (status < 0)
50929a0bf528SMauro Carvalho Chehab 		goto error;
50939a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
50949a0bf528SMauro Carvalho Chehab 	if (status < 0)
50959a0bf528SMauro Carvalho Chehab 		goto error;
50969a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
50979a0bf528SMauro Carvalho Chehab 	if (status < 0)
50989a0bf528SMauro Carvalho Chehab 		goto error;
50999a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
51009a0bf528SMauro Carvalho Chehab 	if (status < 0)
51019a0bf528SMauro Carvalho Chehab 		goto error;
51029a0bf528SMauro Carvalho Chehab 
51039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
51049a0bf528SMauro Carvalho Chehab 	if (status < 0)
51059a0bf528SMauro Carvalho Chehab 		goto error;
51069a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
51079a0bf528SMauro Carvalho Chehab 	if (status < 0)
51089a0bf528SMauro Carvalho Chehab 		goto error;
51099a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
51109a0bf528SMauro Carvalho Chehab 	if (status < 0)
51119a0bf528SMauro Carvalho Chehab 		goto error;
51129a0bf528SMauro Carvalho Chehab 
51139a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
51149a0bf528SMauro Carvalho Chehab 
5115ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5116ab5060cdSMauro Carvalho Chehab 			 DRXK_QAM_SL_SIG_POWER_QAM256);
51179a0bf528SMauro Carvalho Chehab 	if (status < 0)
51189a0bf528SMauro Carvalho Chehab 		goto error;
51199a0bf528SMauro Carvalho Chehab 
51209a0bf528SMauro Carvalho Chehab 
51219a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
51229a0bf528SMauro Carvalho Chehab 
51239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
51249a0bf528SMauro Carvalho Chehab 	if (status < 0)
51259a0bf528SMauro Carvalho Chehab 		goto error;
51269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
51279a0bf528SMauro Carvalho Chehab 	if (status < 0)
51289a0bf528SMauro Carvalho Chehab 		goto error;
51299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
51309a0bf528SMauro Carvalho Chehab 	if (status < 0)
51319a0bf528SMauro Carvalho Chehab 		goto error;
51329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
51339a0bf528SMauro Carvalho Chehab 	if (status < 0)
51349a0bf528SMauro Carvalho Chehab 		goto error;
51359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
51369a0bf528SMauro Carvalho Chehab 	if (status < 0)
51379a0bf528SMauro Carvalho Chehab 		goto error;
51389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
51399a0bf528SMauro Carvalho Chehab 	if (status < 0)
51409a0bf528SMauro Carvalho Chehab 		goto error;
51419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
51429a0bf528SMauro Carvalho Chehab 	if (status < 0)
51439a0bf528SMauro Carvalho Chehab 		goto error;
51449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
51459a0bf528SMauro Carvalho Chehab 	if (status < 0)
51469a0bf528SMauro Carvalho Chehab 		goto error;
51479a0bf528SMauro Carvalho Chehab 
51489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
51499a0bf528SMauro Carvalho Chehab 	if (status < 0)
51509a0bf528SMauro Carvalho Chehab 		goto error;
51519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
51529a0bf528SMauro Carvalho Chehab 	if (status < 0)
51539a0bf528SMauro Carvalho Chehab 		goto error;
51549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
51559a0bf528SMauro Carvalho Chehab 	if (status < 0)
51569a0bf528SMauro Carvalho Chehab 		goto error;
51579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
51589a0bf528SMauro Carvalho Chehab 	if (status < 0)
51599a0bf528SMauro Carvalho Chehab 		goto error;
51609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51619a0bf528SMauro Carvalho Chehab 	if (status < 0)
51629a0bf528SMauro Carvalho Chehab 		goto error;
51639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51649a0bf528SMauro Carvalho Chehab 	if (status < 0)
51659a0bf528SMauro Carvalho Chehab 		goto error;
51669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51679a0bf528SMauro Carvalho Chehab 	if (status < 0)
51689a0bf528SMauro Carvalho Chehab 		goto error;
51699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51709a0bf528SMauro Carvalho Chehab 	if (status < 0)
51719a0bf528SMauro Carvalho Chehab 		goto error;
51729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
51739a0bf528SMauro Carvalho Chehab 	if (status < 0)
51749a0bf528SMauro Carvalho Chehab 		goto error;
51759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
51769a0bf528SMauro Carvalho Chehab 	if (status < 0)
51779a0bf528SMauro Carvalho Chehab 		goto error;
51789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
51799a0bf528SMauro Carvalho Chehab 	if (status < 0)
51809a0bf528SMauro Carvalho Chehab 		goto error;
51819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
51829a0bf528SMauro Carvalho Chehab 	if (status < 0)
51839a0bf528SMauro Carvalho Chehab 		goto error;
51849a0bf528SMauro Carvalho Chehab 
51859a0bf528SMauro Carvalho Chehab 
51869a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
51879a0bf528SMauro Carvalho Chehab 
51889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
51899a0bf528SMauro Carvalho Chehab 	if (status < 0)
51909a0bf528SMauro Carvalho Chehab 		goto error;
51919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
51929a0bf528SMauro Carvalho Chehab 	if (status < 0)
51939a0bf528SMauro Carvalho Chehab 		goto error;
51949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
51959a0bf528SMauro Carvalho Chehab 	if (status < 0)
51969a0bf528SMauro Carvalho Chehab 		goto error;
51979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
51989a0bf528SMauro Carvalho Chehab 	if (status < 0)
51999a0bf528SMauro Carvalho Chehab 		goto error;
52009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
52019a0bf528SMauro Carvalho Chehab 	if (status < 0)
52029a0bf528SMauro Carvalho Chehab 		goto error;
52039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
52049a0bf528SMauro Carvalho Chehab 	if (status < 0)
52059a0bf528SMauro Carvalho Chehab 		goto error;
52069a0bf528SMauro Carvalho Chehab 
52079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
52089a0bf528SMauro Carvalho Chehab 	if (status < 0)
52099a0bf528SMauro Carvalho Chehab 		goto error;
52109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
52119a0bf528SMauro Carvalho Chehab 	if (status < 0)
52129a0bf528SMauro Carvalho Chehab 		goto error;
52139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
52149a0bf528SMauro Carvalho Chehab 	if (status < 0)
52159a0bf528SMauro Carvalho Chehab 		goto error;
52169a0bf528SMauro Carvalho Chehab 
52179a0bf528SMauro Carvalho Chehab 
52189a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
52199a0bf528SMauro Carvalho Chehab 
52209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
52219a0bf528SMauro Carvalho Chehab 	if (status < 0)
52229a0bf528SMauro Carvalho Chehab 		goto error;
52239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
52249a0bf528SMauro Carvalho Chehab 	if (status < 0)
52259a0bf528SMauro Carvalho Chehab 		goto error;
52269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
52279a0bf528SMauro Carvalho Chehab 	if (status < 0)
52289a0bf528SMauro Carvalho Chehab 		goto error;
52299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
52309a0bf528SMauro Carvalho Chehab 	if (status < 0)
52319a0bf528SMauro Carvalho Chehab 		goto error;
52329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
52339a0bf528SMauro Carvalho Chehab 	if (status < 0)
52349a0bf528SMauro Carvalho Chehab 		goto error;
52359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
52369a0bf528SMauro Carvalho Chehab 	if (status < 0)
52379a0bf528SMauro Carvalho Chehab 		goto error;
52389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
52399a0bf528SMauro Carvalho Chehab error:
52409a0bf528SMauro Carvalho Chehab 	if (status < 0)
52413a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52429a0bf528SMauro Carvalho Chehab 	return status;
52439a0bf528SMauro Carvalho Chehab }
52449a0bf528SMauro Carvalho Chehab 
52459a0bf528SMauro Carvalho Chehab 
52469a0bf528SMauro Carvalho Chehab /*============================================================================*/
524734eb9751SMauro Carvalho Chehab /*
52489a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
52499a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52509a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52519a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52529a0bf528SMauro Carvalho Chehab */
5253cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state)
52549a0bf528SMauro Carvalho Chehab {
52559a0bf528SMauro Carvalho Chehab 	int status;
5256cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
52579a0bf528SMauro Carvalho Chehab 
52589a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52599a0bf528SMauro Carvalho Chehab 	/* Stop QAM comstate->m_exec */
52609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52619a0bf528SMauro Carvalho Chehab 	if (status < 0)
52629a0bf528SMauro Carvalho Chehab 		goto error;
52639a0bf528SMauro Carvalho Chehab 
5264ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5265ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5266ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
52679a0bf528SMauro Carvalho Chehab error:
52689a0bf528SMauro Carvalho Chehab 	if (status < 0)
52693a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
52709a0bf528SMauro Carvalho Chehab 	return status;
52719a0bf528SMauro Carvalho Chehab }
52729a0bf528SMauro Carvalho Chehab 
52739a0bf528SMauro Carvalho Chehab /*============================================================================*/
52749a0bf528SMauro Carvalho Chehab 
527534eb9751SMauro Carvalho Chehab /*
52769a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
52779a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52789a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52799a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52809a0bf528SMauro Carvalho Chehab */
5281cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state)
52829a0bf528SMauro Carvalho Chehab {
5283cd7a67a4SMauro Carvalho Chehab 	u32 adc_frequency = 0;
5284cd7a67a4SMauro Carvalho Chehab 	u32 symb_freq = 0;
5285cd7a67a4SMauro Carvalho Chehab 	u32 iqm_rc_rate = 0;
52869a0bf528SMauro Carvalho Chehab 	u16 ratesel = 0;
5287cd7a67a4SMauro Carvalho Chehab 	u32 lc_symb_rate = 0;
52889a0bf528SMauro Carvalho Chehab 	int status;
52899a0bf528SMauro Carvalho Chehab 
52909a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52919a0bf528SMauro Carvalho Chehab 	/* Select & calculate correct IQM rate */
5292cd7a67a4SMauro Carvalho Chehab 	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
52939a0bf528SMauro Carvalho Chehab 	ratesel = 0;
52949a0bf528SMauro Carvalho Chehab 	if (state->props.symbol_rate <= 1188750)
52959a0bf528SMauro Carvalho Chehab 		ratesel = 3;
52969a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 2377500)
52979a0bf528SMauro Carvalho Chehab 		ratesel = 2;
52989a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 4755000)
52999a0bf528SMauro Carvalho Chehab 		ratesel = 1;
53009a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FD_RATESEL__A, ratesel);
53019a0bf528SMauro Carvalho Chehab 	if (status < 0)
53029a0bf528SMauro Carvalho Chehab 		goto error;
53039a0bf528SMauro Carvalho Chehab 
53049a0bf528SMauro Carvalho Chehab 	/*
53059a0bf528SMauro Carvalho Chehab 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
53069a0bf528SMauro Carvalho Chehab 		*/
5307cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate * (1 << ratesel);
5308cd7a67a4SMauro Carvalho Chehab 	if (symb_freq == 0) {
53099a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53109a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53119a0bf528SMauro Carvalho Chehab 		goto error;
53129a0bf528SMauro Carvalho Chehab 	}
5313cd7a67a4SMauro Carvalho Chehab 	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5314cd7a67a4SMauro Carvalho Chehab 		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
53159a0bf528SMauro Carvalho Chehab 		(1 << 23);
5316cd7a67a4SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
53179a0bf528SMauro Carvalho Chehab 	if (status < 0)
53189a0bf528SMauro Carvalho Chehab 		goto error;
5319cd7a67a4SMauro Carvalho Chehab 	state->m_iqm_rc_rate = iqm_rc_rate;
53209a0bf528SMauro Carvalho Chehab 	/*
5321cd7a67a4SMauro Carvalho Chehab 		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
53229a0bf528SMauro Carvalho Chehab 		*/
5323cd7a67a4SMauro Carvalho Chehab 	symb_freq = state->props.symbol_rate;
5324cd7a67a4SMauro Carvalho Chehab 	if (adc_frequency == 0) {
53259a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53269a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53279a0bf528SMauro Carvalho Chehab 		goto error;
53289a0bf528SMauro Carvalho Chehab 	}
5329cd7a67a4SMauro Carvalho Chehab 	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5330cd7a67a4SMauro Carvalho Chehab 		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
53319a0bf528SMauro Carvalho Chehab 		16);
5332cd7a67a4SMauro Carvalho Chehab 	if (lc_symb_rate > 511)
5333cd7a67a4SMauro Carvalho Chehab 		lc_symb_rate = 511;
5334cd7a67a4SMauro Carvalho Chehab 	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
53359a0bf528SMauro Carvalho Chehab 
53369a0bf528SMauro Carvalho Chehab error:
53379a0bf528SMauro Carvalho Chehab 	if (status < 0)
53383a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53399a0bf528SMauro Carvalho Chehab 	return status;
53409a0bf528SMauro Carvalho Chehab }
53419a0bf528SMauro Carvalho Chehab 
53429a0bf528SMauro Carvalho Chehab /*============================================================================*/
53439a0bf528SMauro Carvalho Chehab 
534434eb9751SMauro Carvalho Chehab /*
53459a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
53469a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
53479a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
53489a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
53499a0bf528SMauro Carvalho Chehab */
53509a0bf528SMauro Carvalho Chehab 
5351cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
53529a0bf528SMauro Carvalho Chehab {
53539a0bf528SMauro Carvalho Chehab 	int status;
5354cd7a67a4SMauro Carvalho Chehab 	u16 result[2] = { 0, 0 };
53559a0bf528SMauro Carvalho Chehab 
53569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5357cd7a67a4SMauro Carvalho Chehab 	*p_lock_status = NOT_LOCKED;
53589a0bf528SMauro Carvalho Chehab 	status = scu_command(state,
53599a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_STANDARD_QAM |
53609a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5361cd7a67a4SMauro Carvalho Chehab 			result);
53629a0bf528SMauro Carvalho Chehab 	if (status < 0)
53633a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
53649a0bf528SMauro Carvalho Chehab 
5365cd7a67a4SMauro Carvalho Chehab 	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53669a0bf528SMauro Carvalho Chehab 		/* 0x0000 NOT LOCKED */
5367cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53689a0bf528SMauro Carvalho Chehab 		/* 0x4000 DEMOD LOCKED */
5369cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = DEMOD_LOCK;
5370cd7a67a4SMauro Carvalho Chehab 	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53719a0bf528SMauro Carvalho Chehab 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
5372cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = MPEG_LOCK;
53739a0bf528SMauro Carvalho Chehab 	} else {
53749a0bf528SMauro Carvalho Chehab 		/* 0xC000 NEVER LOCKED */
53759a0bf528SMauro Carvalho Chehab 		/* (system will never be able to lock to the signal) */
5376ab5060cdSMauro Carvalho Chehab 		/*
5377ab5060cdSMauro Carvalho Chehab 		 * TODO: check this, intermediate & standard specific lock
5378ab5060cdSMauro Carvalho Chehab 		 * states are not taken into account here
5379ab5060cdSMauro Carvalho Chehab 		 */
5380cd7a67a4SMauro Carvalho Chehab 		*p_lock_status = NEVER_LOCK;
53819a0bf528SMauro Carvalho Chehab 	}
53829a0bf528SMauro Carvalho Chehab 	return status;
53839a0bf528SMauro Carvalho Chehab }
53849a0bf528SMauro Carvalho Chehab 
53859a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M         0x03
53869a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL     0x00
53879a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED          0x01
53889a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON    0x02
53899a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M      0x10
53909a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL  0x10
53919a0bf528SMauro Carvalho Chehab 
5392cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state,
5393cd7a67a4SMauro Carvalho Chehab 				 int number_of_parameters)
53949a0bf528SMauro Carvalho Chehab {
53959a0bf528SMauro Carvalho Chehab 	int status;
5396cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5397cd7a67a4SMauro Carvalho Chehab 	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
53989a0bf528SMauro Carvalho Chehab 
5399cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[0] = state->m_constellation;	/* modulation     */
5400cd7a67a4SMauro Carvalho Chehab 	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
54019a0bf528SMauro Carvalho Chehab 
5402cd7a67a4SMauro Carvalho Chehab 	if (number_of_parameters == 2) {
5403cd7a67a4SMauro Carvalho Chehab 		u16 set_env_parameters[1] = { 0 };
54049a0bf528SMauro Carvalho Chehab 
5405cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5406cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_C;
54079a0bf528SMauro Carvalho Chehab 		else
5408cd7a67a4SMauro Carvalho Chehab 			set_env_parameters[0] = QAM_TOP_ANNEX_A;
54099a0bf528SMauro Carvalho Chehab 
54109a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5411ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5412ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5413cd7a67a4SMauro Carvalho Chehab 				     1, set_env_parameters, 1, &cmd_result);
54149a0bf528SMauro Carvalho Chehab 		if (status < 0)
54159a0bf528SMauro Carvalho Chehab 			goto error;
54169a0bf528SMauro Carvalho Chehab 
54179a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5418ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5419ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5420cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5421cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
5422cd7a67a4SMauro Carvalho Chehab 	} else if (number_of_parameters == 4) {
5423cd7a67a4SMauro Carvalho Chehab 		if (state->m_operation_mode == OM_QAM_ITU_C)
5424cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_C;
54259a0bf528SMauro Carvalho Chehab 		else
5426cd7a67a4SMauro Carvalho Chehab 			set_param_parameters[2] = QAM_TOP_ANNEX_A;
54279a0bf528SMauro Carvalho Chehab 
5428cd7a67a4SMauro Carvalho Chehab 		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
54299a0bf528SMauro Carvalho Chehab 		/* Env parameters */
54309a0bf528SMauro Carvalho Chehab 		/* check for LOCKRANGE Extented */
5431cd7a67a4SMauro Carvalho Chehab 		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
54329a0bf528SMauro Carvalho Chehab 
54339a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
5434ab5060cdSMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM
5435ab5060cdSMauro Carvalho Chehab 				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5436cd7a67a4SMauro Carvalho Chehab 				     number_of_parameters, set_param_parameters,
5437cd7a67a4SMauro Carvalho Chehab 				     1, &cmd_result);
54389a0bf528SMauro Carvalho Chehab 	} else {
54393a4398f5SMauro Carvalho Chehab 		pr_warn("Unknown QAM demodulator parameter count %d\n",
54403a4398f5SMauro Carvalho Chehab 			number_of_parameters);
544194af1b63SMauro Carvalho Chehab 		status = -EINVAL;
54429a0bf528SMauro Carvalho Chehab 	}
54439a0bf528SMauro Carvalho Chehab 
54449a0bf528SMauro Carvalho Chehab error:
54459a0bf528SMauro Carvalho Chehab 	if (status < 0)
54463a4398f5SMauro Carvalho Chehab 		pr_warn("Warning %d on %s\n", status, __func__);
54479a0bf528SMauro Carvalho Chehab 	return status;
54489a0bf528SMauro Carvalho Chehab }
54499a0bf528SMauro Carvalho Chehab 
5450cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5451cd7a67a4SMauro Carvalho Chehab 		  s32 tuner_freq_offset)
54529a0bf528SMauro Carvalho Chehab {
54539a0bf528SMauro Carvalho Chehab 	int status;
5454cd7a67a4SMauro Carvalho Chehab 	u16 cmd_result;
5455cd7a67a4SMauro Carvalho Chehab 	int qam_demod_param_count = state->qam_demod_parameter_count;
54569a0bf528SMauro Carvalho Chehab 
54579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
54589a0bf528SMauro Carvalho Chehab 	/*
54599a0bf528SMauro Carvalho Chehab 	 * STEP 1: reset demodulator
54609a0bf528SMauro Carvalho Chehab 	 *	resets FEC DI and FEC RS
54619a0bf528SMauro Carvalho Chehab 	 *	resets QAM block
54629a0bf528SMauro Carvalho Chehab 	 *	resets SCU variables
54639a0bf528SMauro Carvalho Chehab 	 */
54649a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54659a0bf528SMauro Carvalho Chehab 	if (status < 0)
54669a0bf528SMauro Carvalho Chehab 		goto error;
54679a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54689a0bf528SMauro Carvalho Chehab 	if (status < 0)
54699a0bf528SMauro Carvalho Chehab 		goto error;
5470cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
54719a0bf528SMauro Carvalho Chehab 	if (status < 0)
54729a0bf528SMauro Carvalho Chehab 		goto error;
54739a0bf528SMauro Carvalho Chehab 
54749a0bf528SMauro Carvalho Chehab 	/*
54759a0bf528SMauro Carvalho Chehab 	 * STEP 2: configure demodulator
54769a0bf528SMauro Carvalho Chehab 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
54779a0bf528SMauro Carvalho Chehab 	 *       SCU variables
54789a0bf528SMauro Carvalho Chehab 	 */
5479cd7a67a4SMauro Carvalho Chehab 	status = qam_set_symbolrate(state);
54809a0bf528SMauro Carvalho Chehab 	if (status < 0)
54819a0bf528SMauro Carvalho Chehab 		goto error;
54829a0bf528SMauro Carvalho Chehab 
54839a0bf528SMauro Carvalho Chehab 	/* Set params */
54849a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
54859a0bf528SMauro Carvalho Chehab 	case QAM_256:
5486cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM256;
54879a0bf528SMauro Carvalho Chehab 		break;
54889a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
54899a0bf528SMauro Carvalho Chehab 	case QAM_64:
5490cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM64;
54919a0bf528SMauro Carvalho Chehab 		break;
54929a0bf528SMauro Carvalho Chehab 	case QAM_16:
5493cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM16;
54949a0bf528SMauro Carvalho Chehab 		break;
54959a0bf528SMauro Carvalho Chehab 	case QAM_32:
5496cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM32;
54979a0bf528SMauro Carvalho Chehab 		break;
54989a0bf528SMauro Carvalho Chehab 	case QAM_128:
5499cd7a67a4SMauro Carvalho Chehab 		state->m_constellation = DRX_CONSTELLATION_QAM128;
55009a0bf528SMauro Carvalho Chehab 		break;
55019a0bf528SMauro Carvalho Chehab 	default:
55029a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
55039a0bf528SMauro Carvalho Chehab 		break;
55049a0bf528SMauro Carvalho Chehab 	}
55059a0bf528SMauro Carvalho Chehab 	if (status < 0)
55069a0bf528SMauro Carvalho Chehab 		goto error;
55079a0bf528SMauro Carvalho Chehab 
55089a0bf528SMauro Carvalho Chehab 	/* Use the 4-parameter if it's requested or we're probing for
55099a0bf528SMauro Carvalho Chehab 	 * the correct command. */
55109a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 4
55119a0bf528SMauro Carvalho Chehab 		|| !state->qam_demod_parameter_count) {
5512cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 4;
5513cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
55149a0bf528SMauro Carvalho Chehab 	}
55159a0bf528SMauro Carvalho Chehab 
55169a0bf528SMauro Carvalho Chehab 	/* Use the 2-parameter command if it was requested or if we're
55179a0bf528SMauro Carvalho Chehab 	 * probing for the correct command and the 4-parameter command
55189a0bf528SMauro Carvalho Chehab 	 * failed. */
55199a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 2
55209a0bf528SMauro Carvalho Chehab 		|| (!state->qam_demod_parameter_count && status < 0)) {
5521cd7a67a4SMauro Carvalho Chehab 		qam_demod_param_count = 2;
5522cd7a67a4SMauro Carvalho Chehab 		status = qam_demodulator_command(state, qam_demod_param_count);
55239a0bf528SMauro Carvalho Chehab 	}
55249a0bf528SMauro Carvalho Chehab 
55259a0bf528SMauro Carvalho Chehab 	if (status < 0) {
55260fb220f2SMauro Carvalho Chehab 		dprintk(1, "Could not set demodulator parameters.\n");
55270fb220f2SMauro Carvalho Chehab 		dprintk(1,
55280fb220f2SMauro Carvalho Chehab 			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
55299a0bf528SMauro Carvalho Chehab 			state->qam_demod_parameter_count,
55309a0bf528SMauro Carvalho Chehab 			state->microcode_name);
55319a0bf528SMauro Carvalho Chehab 		goto error;
55329a0bf528SMauro Carvalho Chehab 	} else if (!state->qam_demod_parameter_count) {
55330fb220f2SMauro Carvalho Chehab 		dprintk(1,
55340fb220f2SMauro Carvalho Chehab 			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
5535cd7a67a4SMauro Carvalho Chehab 			qam_demod_param_count);
55369a0bf528SMauro Carvalho Chehab 
55379a0bf528SMauro Carvalho Chehab 		/*
55389a0bf528SMauro Carvalho Chehab 		 * One of our commands was successful. We don't need to
55399a0bf528SMauro Carvalho Chehab 		 * auto-probe anymore, now that we got the correct command.
55409a0bf528SMauro Carvalho Chehab 		 */
5541cd7a67a4SMauro Carvalho Chehab 		state->qam_demod_parameter_count = qam_demod_param_count;
55429a0bf528SMauro Carvalho Chehab 	}
55439a0bf528SMauro Carvalho Chehab 
55449a0bf528SMauro Carvalho Chehab 	/*
55459a0bf528SMauro Carvalho Chehab 	 * STEP 3: enable the system in a mode where the ADC provides valid
55469a0bf528SMauro Carvalho Chehab 	 * signal setup modulation independent registers
55479a0bf528SMauro Carvalho Chehab 	 */
55489a0bf528SMauro Carvalho Chehab #if 0
5549cd7a67a4SMauro Carvalho Chehab 	status = set_frequency(channel, tuner_freq_offset));
55509a0bf528SMauro Carvalho Chehab 	if (status < 0)
55519a0bf528SMauro Carvalho Chehab 		goto error;
55529a0bf528SMauro Carvalho Chehab #endif
5553ab5060cdSMauro Carvalho Chehab 	status = set_frequency_shifter(state, intermediate_freqk_hz,
5554ab5060cdSMauro Carvalho Chehab 				       tuner_freq_offset, true);
55559a0bf528SMauro Carvalho Chehab 	if (status < 0)
55569a0bf528SMauro Carvalho Chehab 		goto error;
55579a0bf528SMauro Carvalho Chehab 
55589a0bf528SMauro Carvalho Chehab 	/* Setup BER measurement */
5559ab5060cdSMauro Carvalho Chehab 	status = set_qam_measurement(state, state->m_constellation,
5560ab5060cdSMauro Carvalho Chehab 				     state->props.symbol_rate);
55619a0bf528SMauro Carvalho Chehab 	if (status < 0)
55629a0bf528SMauro Carvalho Chehab 		goto error;
55639a0bf528SMauro Carvalho Chehab 
55649a0bf528SMauro Carvalho Chehab 	/* Reset default values */
55659a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55669a0bf528SMauro Carvalho Chehab 	if (status < 0)
55679a0bf528SMauro Carvalho Chehab 		goto error;
55689a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55699a0bf528SMauro Carvalho Chehab 	if (status < 0)
55709a0bf528SMauro Carvalho Chehab 		goto error;
55719a0bf528SMauro Carvalho Chehab 
55729a0bf528SMauro Carvalho Chehab 	/* Reset default LC values */
55739a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55749a0bf528SMauro Carvalho Chehab 	if (status < 0)
55759a0bf528SMauro Carvalho Chehab 		goto error;
55769a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55779a0bf528SMauro Carvalho Chehab 	if (status < 0)
55789a0bf528SMauro Carvalho Chehab 		goto error;
55799a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
55809a0bf528SMauro Carvalho Chehab 	if (status < 0)
55819a0bf528SMauro Carvalho Chehab 		goto error;
55829a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_MODE__A, 7);
55839a0bf528SMauro Carvalho Chehab 	if (status < 0)
55849a0bf528SMauro Carvalho Chehab 		goto error;
55859a0bf528SMauro Carvalho Chehab 
55869a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
55879a0bf528SMauro Carvalho Chehab 	if (status < 0)
55889a0bf528SMauro Carvalho Chehab 		goto error;
55899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
55909a0bf528SMauro Carvalho Chehab 	if (status < 0)
55919a0bf528SMauro Carvalho Chehab 		goto error;
55929a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
55939a0bf528SMauro Carvalho Chehab 	if (status < 0)
55949a0bf528SMauro Carvalho Chehab 		goto error;
55959a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
55969a0bf528SMauro Carvalho Chehab 	if (status < 0)
55979a0bf528SMauro Carvalho Chehab 		goto error;
55989a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
55999a0bf528SMauro Carvalho Chehab 	if (status < 0)
56009a0bf528SMauro Carvalho Chehab 		goto error;
56019a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
56029a0bf528SMauro Carvalho Chehab 	if (status < 0)
56039a0bf528SMauro Carvalho Chehab 		goto error;
56049a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
56059a0bf528SMauro Carvalho Chehab 	if (status < 0)
56069a0bf528SMauro Carvalho Chehab 		goto error;
56079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
56089a0bf528SMauro Carvalho Chehab 	if (status < 0)
56099a0bf528SMauro Carvalho Chehab 		goto error;
56109a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
56119a0bf528SMauro Carvalho Chehab 	if (status < 0)
56129a0bf528SMauro Carvalho Chehab 		goto error;
56139a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
56149a0bf528SMauro Carvalho Chehab 	if (status < 0)
56159a0bf528SMauro Carvalho Chehab 		goto error;
56169a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
56179a0bf528SMauro Carvalho Chehab 	if (status < 0)
56189a0bf528SMauro Carvalho Chehab 		goto error;
56199a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
56209a0bf528SMauro Carvalho Chehab 	if (status < 0)
56219a0bf528SMauro Carvalho Chehab 		goto error;
56229a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
56239a0bf528SMauro Carvalho Chehab 	if (status < 0)
56249a0bf528SMauro Carvalho Chehab 		goto error;
56259a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
56269a0bf528SMauro Carvalho Chehab 	if (status < 0)
56279a0bf528SMauro Carvalho Chehab 		goto error;
56289a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
56299a0bf528SMauro Carvalho Chehab 	if (status < 0)
56309a0bf528SMauro Carvalho Chehab 		goto error;
56319a0bf528SMauro Carvalho Chehab 
56329a0bf528SMauro Carvalho Chehab 	/* Mirroring, QAM-block starting point not inverted */
5633ab5060cdSMauro Carvalho Chehab 	status = write16(state, QAM_SY_SP_INV__A,
5634ab5060cdSMauro Carvalho Chehab 			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
56359a0bf528SMauro Carvalho Chehab 	if (status < 0)
56369a0bf528SMauro Carvalho Chehab 		goto error;
56379a0bf528SMauro Carvalho Chehab 
56389a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
56399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
56409a0bf528SMauro Carvalho Chehab 	if (status < 0)
56419a0bf528SMauro Carvalho Chehab 		goto error;
56429a0bf528SMauro Carvalho Chehab 
56439a0bf528SMauro Carvalho Chehab 	/* STEP 4: modulation specific setup */
56449a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
56459a0bf528SMauro Carvalho Chehab 	case QAM_16:
5646cd7a67a4SMauro Carvalho Chehab 		status = set_qam16(state);
56479a0bf528SMauro Carvalho Chehab 		break;
56489a0bf528SMauro Carvalho Chehab 	case QAM_32:
5649cd7a67a4SMauro Carvalho Chehab 		status = set_qam32(state);
56509a0bf528SMauro Carvalho Chehab 		break;
56519a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
56529a0bf528SMauro Carvalho Chehab 	case QAM_64:
5653cd7a67a4SMauro Carvalho Chehab 		status = set_qam64(state);
56549a0bf528SMauro Carvalho Chehab 		break;
56559a0bf528SMauro Carvalho Chehab 	case QAM_128:
5656cd7a67a4SMauro Carvalho Chehab 		status = set_qam128(state);
56579a0bf528SMauro Carvalho Chehab 		break;
56589a0bf528SMauro Carvalho Chehab 	case QAM_256:
5659cd7a67a4SMauro Carvalho Chehab 		status = set_qam256(state);
56609a0bf528SMauro Carvalho Chehab 		break;
56619a0bf528SMauro Carvalho Chehab 	default:
56629a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
56639a0bf528SMauro Carvalho Chehab 		break;
56649a0bf528SMauro Carvalho Chehab 	}
56659a0bf528SMauro Carvalho Chehab 	if (status < 0)
56669a0bf528SMauro Carvalho Chehab 		goto error;
56679a0bf528SMauro Carvalho Chehab 
56689a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
56699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56709a0bf528SMauro Carvalho Chehab 	if (status < 0)
56719a0bf528SMauro Carvalho Chehab 		goto error;
56729a0bf528SMauro Carvalho Chehab 
56739a0bf528SMauro Carvalho Chehab 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
56749a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.modulation = channel->modulation; */
56759a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
5676cd7a67a4SMauro Carvalho Chehab 	status = mpegts_dto_setup(state, state->m_operation_mode);
56779a0bf528SMauro Carvalho Chehab 	if (status < 0)
56789a0bf528SMauro Carvalho Chehab 		goto error;
56799a0bf528SMauro Carvalho Chehab 
5680cd7a67a4SMauro Carvalho Chehab 	/* start processes */
5681cd7a67a4SMauro Carvalho Chehab 	status = mpegts_start(state);
56829a0bf528SMauro Carvalho Chehab 	if (status < 0)
56839a0bf528SMauro Carvalho Chehab 		goto error;
56849a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
56859a0bf528SMauro Carvalho Chehab 	if (status < 0)
56869a0bf528SMauro Carvalho Chehab 		goto error;
56879a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
56889a0bf528SMauro Carvalho Chehab 	if (status < 0)
56899a0bf528SMauro Carvalho Chehab 		goto error;
56909a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
56919a0bf528SMauro Carvalho Chehab 	if (status < 0)
56929a0bf528SMauro Carvalho Chehab 		goto error;
56939a0bf528SMauro Carvalho Chehab 
56949a0bf528SMauro Carvalho Chehab 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5695ab5060cdSMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5696ab5060cdSMauro Carvalho Chehab 			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
5697ab5060cdSMauro Carvalho Chehab 			     0, NULL, 1, &cmd_result);
56989a0bf528SMauro Carvalho Chehab 	if (status < 0)
56999a0bf528SMauro Carvalho Chehab 		goto error;
57009a0bf528SMauro Carvalho Chehab 
57019a0bf528SMauro Carvalho Chehab 	/* update global DRXK data container */
57029a0bf528SMauro Carvalho Chehab /*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
57039a0bf528SMauro Carvalho Chehab 
57049a0bf528SMauro Carvalho Chehab error:
57059a0bf528SMauro Carvalho Chehab 	if (status < 0)
57063a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
57079a0bf528SMauro Carvalho Chehab 	return status;
57089a0bf528SMauro Carvalho Chehab }
57099a0bf528SMauro Carvalho Chehab 
5710cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
5711cd7a67a4SMauro Carvalho Chehab 			  enum operation_mode o_mode)
57129a0bf528SMauro Carvalho Chehab {
57139a0bf528SMauro Carvalho Chehab 	int status;
57149a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
57159a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
57169a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
57179a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
57189a0bf528SMauro Carvalho Chehab #endif
57199a0bf528SMauro Carvalho Chehab 
57209a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
57219a0bf528SMauro Carvalho Chehab 
57229a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
5723cd7a67a4SMauro Carvalho Chehab 	switch_antenna_to_qam(state);
57249a0bf528SMauro Carvalho Chehab 
57259a0bf528SMauro Carvalho Chehab 	/* Ensure correct power-up mode */
5726cd7a67a4SMauro Carvalho Chehab 	status = power_up_qam(state);
57279a0bf528SMauro Carvalho Chehab 	if (status < 0)
57289a0bf528SMauro Carvalho Chehab 		goto error;
57299a0bf528SMauro Carvalho Chehab 	/* Reset QAM block */
5730cd7a67a4SMauro Carvalho Chehab 	status = qam_reset_qam(state);
57319a0bf528SMauro Carvalho Chehab 	if (status < 0)
57329a0bf528SMauro Carvalho Chehab 		goto error;
57339a0bf528SMauro Carvalho Chehab 
57349a0bf528SMauro Carvalho Chehab 	/* Setup IQM */
57359a0bf528SMauro Carvalho Chehab 
57369a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
57379a0bf528SMauro Carvalho Chehab 	if (status < 0)
57389a0bf528SMauro Carvalho Chehab 		goto error;
57399a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
57409a0bf528SMauro Carvalho Chehab 	if (status < 0)
57419a0bf528SMauro Carvalho Chehab 		goto error;
57429a0bf528SMauro Carvalho Chehab 
57439a0bf528SMauro Carvalho Chehab 	/* Upload IQM Channel Filter settings by
57449a0bf528SMauro Carvalho Chehab 		boot loader from ROM table */
5745cd7a67a4SMauro Carvalho Chehab 	switch (o_mode) {
57469a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
5747ab5060cdSMauro Carvalho Chehab 		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5748ab5060cdSMauro Carvalho Chehab 				      DRXK_BLCC_NR_ELEMENTS_TAPS,
5749ab5060cdSMauro Carvalho Chehab 			DRXK_BLC_TIMEOUT);
57509a0bf528SMauro Carvalho Chehab 		break;
57519a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
5752ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5753ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5754ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5755ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57569a0bf528SMauro Carvalho Chehab 		if (status < 0)
57579a0bf528SMauro Carvalho Chehab 			goto error;
5758ab5060cdSMauro Carvalho Chehab 		status = bl_direct_cmd(state,
5759ab5060cdSMauro Carvalho Chehab 				       IQM_CF_TAP_IM0__A,
5760ab5060cdSMauro Carvalho Chehab 				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5761ab5060cdSMauro Carvalho Chehab 				       DRXK_BLDC_NR_ELEMENTS_TAPS,
5762ab5060cdSMauro Carvalho Chehab 				       DRXK_BLC_TIMEOUT);
57639a0bf528SMauro Carvalho Chehab 		break;
57649a0bf528SMauro Carvalho Chehab 	default:
57659a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
57669a0bf528SMauro Carvalho Chehab 	}
57679a0bf528SMauro Carvalho Chehab 	if (status < 0)
57689a0bf528SMauro Carvalho Chehab 		goto error;
57699a0bf528SMauro Carvalho Chehab 
5770ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
57719a0bf528SMauro Carvalho Chehab 	if (status < 0)
57729a0bf528SMauro Carvalho Chehab 		goto error;
57739a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57749a0bf528SMauro Carvalho Chehab 	if (status < 0)
57759a0bf528SMauro Carvalho Chehab 		goto error;
5776ab5060cdSMauro Carvalho Chehab 	status = write16(state, IQM_CF_MIDTAP__A,
5777ab5060cdSMauro Carvalho Chehab 		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57789a0bf528SMauro Carvalho Chehab 	if (status < 0)
57799a0bf528SMauro Carvalho Chehab 		goto error;
57809a0bf528SMauro Carvalho Chehab 
57819a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 21);
57829a0bf528SMauro Carvalho Chehab 	if (status < 0)
57839a0bf528SMauro Carvalho Chehab 		goto error;
57849a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
57859a0bf528SMauro Carvalho Chehab 	if (status < 0)
57869a0bf528SMauro Carvalho Chehab 		goto error;
57879a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
57889a0bf528SMauro Carvalho Chehab 	if (status < 0)
57899a0bf528SMauro Carvalho Chehab 		goto error;
57909a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
57919a0bf528SMauro Carvalho Chehab 	if (status < 0)
57929a0bf528SMauro Carvalho Chehab 		goto error;
57939a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
57949a0bf528SMauro Carvalho Chehab 	if (status < 0)
57959a0bf528SMauro Carvalho Chehab 		goto error;
57969a0bf528SMauro Carvalho Chehab 
57979a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FS_ADJ_SEL__A, 1);
57989a0bf528SMauro Carvalho Chehab 	if (status < 0)
57999a0bf528SMauro Carvalho Chehab 		goto error;
58009a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_ADJ_SEL__A, 1);
58019a0bf528SMauro Carvalho Chehab 	if (status < 0)
58029a0bf528SMauro Carvalho Chehab 		goto error;
58039a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_ADJ_SEL__A, 1);
58049a0bf528SMauro Carvalho Chehab 	if (status < 0)
58059a0bf528SMauro Carvalho Chehab 		goto error;
58069a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 0);
58079a0bf528SMauro Carvalho Chehab 	if (status < 0)
58089a0bf528SMauro Carvalho Chehab 		goto error;
58099a0bf528SMauro Carvalho Chehab 
58109a0bf528SMauro Carvalho Chehab 	/* IQM Impulse Noise Processing Unit */
58119a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_CLP_VAL__A, 500);
58129a0bf528SMauro Carvalho Chehab 	if (status < 0)
58139a0bf528SMauro Carvalho Chehab 		goto error;
58149a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 1000);
58159a0bf528SMauro Carvalho Chehab 	if (status < 0)
58169a0bf528SMauro Carvalho Chehab 		goto error;
58179a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_BYPASSDET__A, 1);
58189a0bf528SMauro Carvalho Chehab 	if (status < 0)
58199a0bf528SMauro Carvalho Chehab 		goto error;
58209a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);
58219a0bf528SMauro Carvalho Chehab 	if (status < 0)
58229a0bf528SMauro Carvalho Chehab 		goto error;
58239a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 1);
58249a0bf528SMauro Carvalho Chehab 	if (status < 0)
58259a0bf528SMauro Carvalho Chehab 		goto error;
58269a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 1);
58279a0bf528SMauro Carvalho Chehab 	if (status < 0)
58289a0bf528SMauro Carvalho Chehab 		goto error;
58299a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_BYPASS__A, 1);
58309a0bf528SMauro Carvalho Chehab 	if (status < 0)
58319a0bf528SMauro Carvalho Chehab 		goto error;
58329a0bf528SMauro Carvalho Chehab 
58339a0bf528SMauro Carvalho Chehab 	/* turn on IQMAF. Must be done before setAgc**() */
5834cd7a67a4SMauro Carvalho Chehab 	status = set_iqm_af(state, true);
58359a0bf528SMauro Carvalho Chehab 	if (status < 0)
58369a0bf528SMauro Carvalho Chehab 		goto error;
58379a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
58389a0bf528SMauro Carvalho Chehab 	if (status < 0)
58399a0bf528SMauro Carvalho Chehab 		goto error;
58409a0bf528SMauro Carvalho Chehab 
58419a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
5842cd7a67a4SMauro Carvalho Chehab 	status = adc_synchronization(state);
58439a0bf528SMauro Carvalho Chehab 	if (status < 0)
58449a0bf528SMauro Carvalho Chehab 		goto error;
58459a0bf528SMauro Carvalho Chehab 
58469a0bf528SMauro Carvalho Chehab 	/* Set the FSM step period */
58479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
58489a0bf528SMauro Carvalho Chehab 	if (status < 0)
58499a0bf528SMauro Carvalho Chehab 		goto error;
58509a0bf528SMauro Carvalho Chehab 
58519a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
58529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
58539a0bf528SMauro Carvalho Chehab 	if (status < 0)
58549a0bf528SMauro Carvalho Chehab 		goto error;
58559a0bf528SMauro Carvalho Chehab 
58569a0bf528SMauro Carvalho Chehab 	/* No more resets of the IQM, current standard correctly set =>
58579a0bf528SMauro Carvalho Chehab 		now AGCs can be configured. */
58589a0bf528SMauro Carvalho Chehab 
5859cd7a67a4SMauro Carvalho Chehab 	status = init_agc(state, true);
58609a0bf528SMauro Carvalho Chehab 	if (status < 0)
58619a0bf528SMauro Carvalho Chehab 		goto error;
5862cd7a67a4SMauro Carvalho Chehab 	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
58639a0bf528SMauro Carvalho Chehab 	if (status < 0)
58649a0bf528SMauro Carvalho Chehab 		goto error;
58659a0bf528SMauro Carvalho Chehab 
58669a0bf528SMauro Carvalho Chehab 	/* Configure AGC's */
5867cd7a67a4SMauro Carvalho Chehab 	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
58689a0bf528SMauro Carvalho Chehab 	if (status < 0)
58699a0bf528SMauro Carvalho Chehab 		goto error;
5870cd7a67a4SMauro Carvalho Chehab 	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
58719a0bf528SMauro Carvalho Chehab 	if (status < 0)
58729a0bf528SMauro Carvalho Chehab 		goto error;
58739a0bf528SMauro Carvalho Chehab 
58749a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
58759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58769a0bf528SMauro Carvalho Chehab error:
58779a0bf528SMauro Carvalho Chehab 	if (status < 0)
58783a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
58799a0bf528SMauro Carvalho Chehab 	return status;
58809a0bf528SMauro Carvalho Chehab }
58819a0bf528SMauro Carvalho Chehab 
5882cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state)
58839a0bf528SMauro Carvalho Chehab {
58849a0bf528SMauro Carvalho Chehab 	int status;
58859a0bf528SMauro Carvalho Chehab 	u16 value = 0;
58869a0bf528SMauro Carvalho Chehab 
58879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
58889a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
5889ab5060cdSMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A,
5890ab5060cdSMauro Carvalho Chehab 			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58919a0bf528SMauro Carvalho Chehab 	if (status < 0)
58929a0bf528SMauro Carvalho Chehab 		goto error;
58939a0bf528SMauro Carvalho Chehab 
58949a0bf528SMauro Carvalho Chehab 	/*  Write magic word to enable pdr reg write               */
58959a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
58969a0bf528SMauro Carvalho Chehab 	if (status < 0)
58979a0bf528SMauro Carvalho Chehab 		goto error;
58989a0bf528SMauro Carvalho Chehab 
5899cd7a67a4SMauro Carvalho Chehab 	if (state->m_has_sawsw) {
5900cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0001) { /* UIO-1 */
59019a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5902ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5903ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59049a0bf528SMauro Carvalho Chehab 			if (status < 0)
59059a0bf528SMauro Carvalho Chehab 				goto error;
59069a0bf528SMauro Carvalho Chehab 
59079a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59089a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59099a0bf528SMauro Carvalho Chehab 			if (status < 0)
59109a0bf528SMauro Carvalho Chehab 				goto error;
5911cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0001) == 0)
59129a0bf528SMauro Carvalho Chehab 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
59139a0bf528SMauro Carvalho Chehab 			else
59149a0bf528SMauro Carvalho Chehab 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
59159a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59169a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59179a0bf528SMauro Carvalho Chehab 			if (status < 0)
59189a0bf528SMauro Carvalho Chehab 				goto error;
59199a0bf528SMauro Carvalho Chehab 		}
5920cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0002) { /* UIO-2 */
59219a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5922ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5923ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59249a0bf528SMauro Carvalho Chehab 			if (status < 0)
59259a0bf528SMauro Carvalho Chehab 				goto error;
59269a0bf528SMauro Carvalho Chehab 
59279a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59289a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59299a0bf528SMauro Carvalho Chehab 			if (status < 0)
59309a0bf528SMauro Carvalho Chehab 				goto error;
5931cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0002) == 0)
59329a0bf528SMauro Carvalho Chehab 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
59339a0bf528SMauro Carvalho Chehab 			else
59349a0bf528SMauro Carvalho Chehab 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
59359a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59369a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59379a0bf528SMauro Carvalho Chehab 			if (status < 0)
59389a0bf528SMauro Carvalho Chehab 				goto error;
59399a0bf528SMauro Carvalho Chehab 		}
5940cd7a67a4SMauro Carvalho Chehab 		if (state->uio_mask & 0x0004) { /* UIO-3 */
59419a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
5942ab5060cdSMauro Carvalho Chehab 			status = write16(state, SIO_PDR_GPIO_CFG__A,
5943ab5060cdSMauro Carvalho Chehab 					 state->m_gpio_cfg);
59449a0bf528SMauro Carvalho Chehab 			if (status < 0)
59459a0bf528SMauro Carvalho Chehab 				goto error;
59469a0bf528SMauro Carvalho Chehab 
59479a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59489a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59499a0bf528SMauro Carvalho Chehab 			if (status < 0)
59509a0bf528SMauro Carvalho Chehab 				goto error;
5951cd7a67a4SMauro Carvalho Chehab 			if ((state->m_gpio & 0x0004) == 0)
59529a0bf528SMauro Carvalho Chehab 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
59539a0bf528SMauro Carvalho Chehab 			else
59549a0bf528SMauro Carvalho Chehab 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
59559a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59569a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59579a0bf528SMauro Carvalho Chehab 			if (status < 0)
59589a0bf528SMauro Carvalho Chehab 				goto error;
59599a0bf528SMauro Carvalho Chehab 		}
59609a0bf528SMauro Carvalho Chehab 	}
59619a0bf528SMauro Carvalho Chehab 	/*  Write magic word to disable pdr reg write               */
59629a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59639a0bf528SMauro Carvalho Chehab error:
59649a0bf528SMauro Carvalho Chehab 	if (status < 0)
59653a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59669a0bf528SMauro Carvalho Chehab 	return status;
59679a0bf528SMauro Carvalho Chehab }
59689a0bf528SMauro Carvalho Chehab 
5969cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state)
59709a0bf528SMauro Carvalho Chehab {
59719a0bf528SMauro Carvalho Chehab 	int status = 0;
59729a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59739a0bf528SMauro Carvalho Chehab 
59749a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59759a0bf528SMauro Carvalho Chehab 
59769a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59779a0bf528SMauro Carvalho Chehab 		return 0;
59789a0bf528SMauro Carvalho Chehab 
5979cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
59809a0bf528SMauro Carvalho Chehab 
59819a0bf528SMauro Carvalho Chehab 	if (state->antenna_dvbt ^ gpio_state) {
59829a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-T mode. Switch */
59839a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
5984cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
59859a0bf528SMauro Carvalho Chehab 		else
5986cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
5987cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
59889a0bf528SMauro Carvalho Chehab 	}
59899a0bf528SMauro Carvalho Chehab 	if (status < 0)
59903a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
59919a0bf528SMauro Carvalho Chehab 	return status;
59929a0bf528SMauro Carvalho Chehab }
59939a0bf528SMauro Carvalho Chehab 
5994cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state)
59959a0bf528SMauro Carvalho Chehab {
59969a0bf528SMauro Carvalho Chehab 	int status = 0;
59979a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59989a0bf528SMauro Carvalho Chehab 
59999a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60009a0bf528SMauro Carvalho Chehab 
60019a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
60029a0bf528SMauro Carvalho Chehab 		return 0;
60039a0bf528SMauro Carvalho Chehab 
6004cd7a67a4SMauro Carvalho Chehab 	gpio_state = state->m_gpio & state->antenna_gpio;
60059a0bf528SMauro Carvalho Chehab 
60069a0bf528SMauro Carvalho Chehab 	if (!(state->antenna_dvbt ^ gpio_state)) {
60079a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-C mode. Switch */
60089a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
6009cd7a67a4SMauro Carvalho Chehab 			state->m_gpio |= state->antenna_gpio;
60109a0bf528SMauro Carvalho Chehab 		else
6011cd7a67a4SMauro Carvalho Chehab 			state->m_gpio &= ~state->antenna_gpio;
6012cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
60139a0bf528SMauro Carvalho Chehab 	}
60149a0bf528SMauro Carvalho Chehab 	if (status < 0)
60153a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
60169a0bf528SMauro Carvalho Chehab 	return status;
60179a0bf528SMauro Carvalho Chehab }
60189a0bf528SMauro Carvalho Chehab 
60199a0bf528SMauro Carvalho Chehab 
6020cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state)
60219a0bf528SMauro Carvalho Chehab {
60229a0bf528SMauro Carvalho Chehab 	/* Power down to requested mode */
60239a0bf528SMauro Carvalho Chehab 	/* Backup some register settings */
60249a0bf528SMauro Carvalho Chehab 	/* Set pins with possible pull-ups connected to them in input mode */
60259a0bf528SMauro Carvalho Chehab 	/* Analog power down */
60269a0bf528SMauro Carvalho Chehab 	/* ADC power down */
60279a0bf528SMauro Carvalho Chehab 	/* Power down device */
60289a0bf528SMauro Carvalho Chehab 	int status;
60299a0bf528SMauro Carvalho Chehab 
60309a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6031cd7a67a4SMauro Carvalho Chehab 	if (state->m_b_p_down_open_bridge) {
60329a0bf528SMauro Carvalho Chehab 		/* Open I2C bridge before power down of DRXK */
60339a0bf528SMauro Carvalho Chehab 		status = ConfigureI2CBridge(state, true);
60349a0bf528SMauro Carvalho Chehab 		if (status < 0)
60359a0bf528SMauro Carvalho Chehab 			goto error;
60369a0bf528SMauro Carvalho Chehab 	}
60379a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
6038cd7a67a4SMauro Carvalho Chehab 	status = dvbt_enable_ofdm_token_ring(state, false);
60399a0bf528SMauro Carvalho Chehab 	if (status < 0)
60409a0bf528SMauro Carvalho Chehab 		goto error;
60419a0bf528SMauro Carvalho Chehab 
6042ab5060cdSMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A,
6043ab5060cdSMauro Carvalho Chehab 			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
60449a0bf528SMauro Carvalho Chehab 	if (status < 0)
60459a0bf528SMauro Carvalho Chehab 		goto error;
60469a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60479a0bf528SMauro Carvalho Chehab 	if (status < 0)
60489a0bf528SMauro Carvalho Chehab 		goto error;
6049cd7a67a4SMauro Carvalho Chehab 	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
6050cd7a67a4SMauro Carvalho Chehab 	status = hi_cfg_command(state);
60519a0bf528SMauro Carvalho Chehab error:
60529a0bf528SMauro Carvalho Chehab 	if (status < 0)
60533a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
60549a0bf528SMauro Carvalho Chehab 
60559a0bf528SMauro Carvalho Chehab 	return status;
60569a0bf528SMauro Carvalho Chehab }
60579a0bf528SMauro Carvalho Chehab 
60589a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60599a0bf528SMauro Carvalho Chehab {
60609a0bf528SMauro Carvalho Chehab 	int status = 0, n = 0;
6061cd7a67a4SMauro Carvalho Chehab 	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6062cd7a67a4SMauro Carvalho Chehab 	u16 driver_version;
60639a0bf528SMauro Carvalho Chehab 
60649a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6065cd7a67a4SMauro Carvalho Chehab 	if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
60669a0bf528SMauro Carvalho Chehab 		drxk_i2c_lock(state);
6067cd7a67a4SMauro Carvalho Chehab 		status = power_up_device(state);
60689a0bf528SMauro Carvalho Chehab 		if (status < 0)
60699a0bf528SMauro Carvalho Chehab 			goto error;
6070cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
60719a0bf528SMauro Carvalho Chehab 		if (status < 0)
60729a0bf528SMauro Carvalho Chehab 			goto error;
60739a0bf528SMauro Carvalho Chehab 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
6074ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_CC_SOFT_RST__A,
6075ab5060cdSMauro Carvalho Chehab 				 SIO_CC_SOFT_RST_OFDM__M
6076ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_SYS__M
6077ab5060cdSMauro Carvalho Chehab 				 | SIO_CC_SOFT_RST_OSC__M);
60789a0bf528SMauro Carvalho Chehab 		if (status < 0)
60799a0bf528SMauro Carvalho Chehab 			goto error;
60809a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60819a0bf528SMauro Carvalho Chehab 		if (status < 0)
60829a0bf528SMauro Carvalho Chehab 			goto error;
6083ab5060cdSMauro Carvalho Chehab 		/*
6084ab5060cdSMauro Carvalho Chehab 		 * TODO is this needed? If yes, how much delay in
6085ab5060cdSMauro Carvalho Chehab 		 * worst case scenario
6086ab5060cdSMauro Carvalho Chehab 		 */
6087b72852baSMauro Carvalho Chehab 		usleep_range(1000, 2000);
6088cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_a3_patch_code = true;
6089cd7a67a4SMauro Carvalho Chehab 		status = get_device_capabilities(state);
60909a0bf528SMauro Carvalho Chehab 		if (status < 0)
60919a0bf528SMauro Carvalho Chehab 			goto error;
60929a0bf528SMauro Carvalho Chehab 
60939a0bf528SMauro Carvalho Chehab 		/* Bridge delay, uses oscilator clock */
60949a0bf528SMauro Carvalho Chehab 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60959a0bf528SMauro Carvalho Chehab 		/* SDA brdige delay */
6096cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay =
6097cd7a67a4SMauro Carvalho Chehab 			(u16) ((state->m_osc_clock_freq / 1000) *
60989a0bf528SMauro Carvalho Chehab 				HI_I2C_BRIDGE_DELAY) / 1000;
60999a0bf528SMauro Carvalho Chehab 		/* Clipping */
6100cd7a67a4SMauro Carvalho Chehab 		if (state->m_hi_cfg_bridge_delay >
61019a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6102cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay =
61039a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
61049a0bf528SMauro Carvalho Chehab 		}
61059a0bf528SMauro Carvalho Chehab 		/* SCL bridge delay, same as SDA for now */
6106cd7a67a4SMauro Carvalho Chehab 		state->m_hi_cfg_bridge_delay +=
6107cd7a67a4SMauro Carvalho Chehab 			state->m_hi_cfg_bridge_delay <<
61089a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
61099a0bf528SMauro Carvalho Chehab 
6110cd7a67a4SMauro Carvalho Chehab 		status = init_hi(state);
61119a0bf528SMauro Carvalho Chehab 		if (status < 0)
61129a0bf528SMauro Carvalho Chehab 			goto error;
61139a0bf528SMauro Carvalho Chehab 		/* disable various processes */
61149a0bf528SMauro Carvalho Chehab #if NOA1ROM
61159a0bf528SMauro Carvalho Chehab 		if (!(state->m_DRXK_A1_ROM_CODE)
61169a0bf528SMauro Carvalho Chehab 			&& !(state->m_DRXK_A2_ROM_CODE))
61179a0bf528SMauro Carvalho Chehab #endif
61189a0bf528SMauro Carvalho Chehab 		{
6119ab5060cdSMauro Carvalho Chehab 			status = write16(state, SCU_RAM_GPIO__A,
6120ab5060cdSMauro Carvalho Chehab 					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
61219a0bf528SMauro Carvalho Chehab 			if (status < 0)
61229a0bf528SMauro Carvalho Chehab 				goto error;
61239a0bf528SMauro Carvalho Chehab 		}
61249a0bf528SMauro Carvalho Chehab 
61259a0bf528SMauro Carvalho Chehab 		/* disable MPEG port */
6126cd7a67a4SMauro Carvalho Chehab 		status = mpegts_disable(state);
61279a0bf528SMauro Carvalho Chehab 		if (status < 0)
61289a0bf528SMauro Carvalho Chehab 			goto error;
61299a0bf528SMauro Carvalho Chehab 
61309a0bf528SMauro Carvalho Chehab 		/* Stop AUD and SCU */
61319a0bf528SMauro Carvalho Chehab 		status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
61329a0bf528SMauro Carvalho Chehab 		if (status < 0)
61339a0bf528SMauro Carvalho Chehab 			goto error;
61349a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
61359a0bf528SMauro Carvalho Chehab 		if (status < 0)
61369a0bf528SMauro Carvalho Chehab 			goto error;
61379a0bf528SMauro Carvalho Chehab 
61389a0bf528SMauro Carvalho Chehab 		/* enable token-ring bus through OFDM block for possible ucode upload */
6139ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6140ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
61419a0bf528SMauro Carvalho Chehab 		if (status < 0)
61429a0bf528SMauro Carvalho Chehab 			goto error;
61439a0bf528SMauro Carvalho Chehab 
61449a0bf528SMauro Carvalho Chehab 		/* include boot loader section */
6145ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_BL_COMM_EXEC__A,
6146ab5060cdSMauro Carvalho Chehab 				 SIO_BL_COMM_EXEC_ACTIVE);
61479a0bf528SMauro Carvalho Chehab 		if (status < 0)
61489a0bf528SMauro Carvalho Chehab 			goto error;
6149cd7a67a4SMauro Carvalho Chehab 		status = bl_chain_cmd(state, 0, 6, 100);
61509a0bf528SMauro Carvalho Chehab 		if (status < 0)
61519a0bf528SMauro Carvalho Chehab 			goto error;
61529a0bf528SMauro Carvalho Chehab 
61539a0bf528SMauro Carvalho Chehab 		if (state->fw) {
6154cd7a67a4SMauro Carvalho Chehab 			status = download_microcode(state, state->fw->data,
61559a0bf528SMauro Carvalho Chehab 						   state->fw->size);
61569a0bf528SMauro Carvalho Chehab 			if (status < 0)
61579a0bf528SMauro Carvalho Chehab 				goto error;
61589a0bf528SMauro Carvalho Chehab 		}
61599a0bf528SMauro Carvalho Chehab 
61609a0bf528SMauro Carvalho Chehab 		/* disable token-ring bus through OFDM block for possible ucode upload */
6161ab5060cdSMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6162ab5060cdSMauro Carvalho Chehab 				 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
61639a0bf528SMauro Carvalho Chehab 		if (status < 0)
61649a0bf528SMauro Carvalho Chehab 			goto error;
61659a0bf528SMauro Carvalho Chehab 
61669a0bf528SMauro Carvalho Chehab 		/* Run SCU for a little while to initialize microcode version numbers */
61679a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61689a0bf528SMauro Carvalho Chehab 		if (status < 0)
61699a0bf528SMauro Carvalho Chehab 			goto error;
6170cd7a67a4SMauro Carvalho Chehab 		status = drxx_open(state);
61719a0bf528SMauro Carvalho Chehab 		if (status < 0)
61729a0bf528SMauro Carvalho Chehab 			goto error;
61739a0bf528SMauro Carvalho Chehab 		/* added for test */
61749a0bf528SMauro Carvalho Chehab 		msleep(30);
61759a0bf528SMauro Carvalho Chehab 
6176cd7a67a4SMauro Carvalho Chehab 		power_mode = DRXK_POWER_DOWN_OFDM;
6177cd7a67a4SMauro Carvalho Chehab 		status = ctrl_power_mode(state, &power_mode);
61789a0bf528SMauro Carvalho Chehab 		if (status < 0)
61799a0bf528SMauro Carvalho Chehab 			goto error;
61809a0bf528SMauro Carvalho Chehab 
61819a0bf528SMauro Carvalho Chehab 		/* Stamp driver version number in SCU data RAM in BCD code
618239c1cb2bSJonathan McCrohan 			Done to enable field application engineers to retrieve drxdriver version
61839a0bf528SMauro Carvalho Chehab 			via I2C from SCU RAM.
61849a0bf528SMauro Carvalho Chehab 			Not using SCU command interface for SCU register access since no
61859a0bf528SMauro Carvalho Chehab 			microcode may be present.
61869a0bf528SMauro Carvalho Chehab 			*/
6187cd7a67a4SMauro Carvalho Chehab 		driver_version =
61889a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61899a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61909a0bf528SMauro Carvalho Chehab 			((DRXK_VERSION_MAJOR % 10) << 4) +
61919a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_MINOR % 10);
6192ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6193ab5060cdSMauro Carvalho Chehab 				 driver_version);
61949a0bf528SMauro Carvalho Chehab 		if (status < 0)
61959a0bf528SMauro Carvalho Chehab 			goto error;
6196cd7a67a4SMauro Carvalho Chehab 		driver_version =
61979a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61989a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61999a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
62009a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_PATCH % 10);
6201ab5060cdSMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6202ab5060cdSMauro Carvalho Chehab 				 driver_version);
62039a0bf528SMauro Carvalho Chehab 		if (status < 0)
62049a0bf528SMauro Carvalho Chehab 			goto error;
62059a0bf528SMauro Carvalho Chehab 
62063a4398f5SMauro Carvalho Chehab 		pr_info("DRXK driver version %d.%d.%d\n",
62079a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
62089a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_PATCH);
62099a0bf528SMauro Carvalho Chehab 
6210ab5060cdSMauro Carvalho Chehab 		/*
6211ab5060cdSMauro Carvalho Chehab 		 * Dirty fix of default values for ROM/PATCH microcode
6212ab5060cdSMauro Carvalho Chehab 		 * Dirty because this fix makes it impossible to setup
6213ab5060cdSMauro Carvalho Chehab 		 * suitable values before calling DRX_Open. This solution
6214ab5060cdSMauro Carvalho Chehab 		 * requires changes to RF AGC speed to be done via the CTRL
6215ab5060cdSMauro Carvalho Chehab 		 * function after calling DRX_Open
6216ab5060cdSMauro Carvalho Chehab 		 */
62179a0bf528SMauro Carvalho Chehab 
6218cd7a67a4SMauro Carvalho Chehab 		/* m_dvbt_rf_agc_cfg.speed = 3; */
62199a0bf528SMauro Carvalho Chehab 
62209a0bf528SMauro Carvalho Chehab 		/* Reset driver debug flags to 0 */
62219a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
62229a0bf528SMauro Carvalho Chehab 		if (status < 0)
62239a0bf528SMauro Carvalho Chehab 			goto error;
62249a0bf528SMauro Carvalho Chehab 		/* driver 0.9.0 */
62259a0bf528SMauro Carvalho Chehab 		/* Setup FEC OC:
62269a0bf528SMauro Carvalho Chehab 			NOTE: No more full FEC resets allowed afterwards!! */
62279a0bf528SMauro Carvalho Chehab 		status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
62289a0bf528SMauro Carvalho Chehab 		if (status < 0)
62299a0bf528SMauro Carvalho Chehab 			goto error;
62309a0bf528SMauro Carvalho Chehab 		/* MPEGTS functions are still the same */
6231cd7a67a4SMauro Carvalho Chehab 		status = mpegts_dto_init(state);
62329a0bf528SMauro Carvalho Chehab 		if (status < 0)
62339a0bf528SMauro Carvalho Chehab 			goto error;
6234cd7a67a4SMauro Carvalho Chehab 		status = mpegts_stop(state);
62359a0bf528SMauro Carvalho Chehab 		if (status < 0)
62369a0bf528SMauro Carvalho Chehab 			goto error;
6237cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_polarity(state);
62389a0bf528SMauro Carvalho Chehab 		if (status < 0)
62399a0bf528SMauro Carvalho Chehab 			goto error;
6240cd7a67a4SMauro Carvalho Chehab 		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
62419a0bf528SMauro Carvalho Chehab 		if (status < 0)
62429a0bf528SMauro Carvalho Chehab 			goto error;
62439a0bf528SMauro Carvalho Chehab 		/* added: configure GPIO */
6244cd7a67a4SMauro Carvalho Chehab 		status = write_gpio(state);
62459a0bf528SMauro Carvalho Chehab 		if (status < 0)
62469a0bf528SMauro Carvalho Chehab 			goto error;
62479a0bf528SMauro Carvalho Chehab 
6248cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_STOPPED;
62499a0bf528SMauro Carvalho Chehab 
6250cd7a67a4SMauro Carvalho Chehab 		if (state->m_b_power_down) {
6251cd7a67a4SMauro Carvalho Chehab 			status = power_down_device(state);
62529a0bf528SMauro Carvalho Chehab 			if (status < 0)
62539a0bf528SMauro Carvalho Chehab 				goto error;
6254cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_POWERED_DOWN;
62559a0bf528SMauro Carvalho Chehab 		} else
6256cd7a67a4SMauro Carvalho Chehab 			state->m_drxk_state = DRXK_STOPPED;
62579a0bf528SMauro Carvalho Chehab 
62589a0bf528SMauro Carvalho Chehab 		/* Initialize the supported delivery systems */
62599a0bf528SMauro Carvalho Chehab 		n = 0;
6260cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbc) {
62619a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62629a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62639a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-C",
62649a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62659a0bf528SMauro Carvalho Chehab 		}
6266cd7a67a4SMauro Carvalho Chehab 		if (state->m_has_dvbt) {
62679a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBT;
62689a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-T",
62699a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62709a0bf528SMauro Carvalho Chehab 		}
62719a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62729a0bf528SMauro Carvalho Chehab 	}
62739a0bf528SMauro Carvalho Chehab error:
62749a0bf528SMauro Carvalho Chehab 	if (status < 0) {
6275cd7a67a4SMauro Carvalho Chehab 		state->m_drxk_state = DRXK_NO_DEV;
62769a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62773a4398f5SMauro Carvalho Chehab 		pr_err("Error %d on %s\n", status, __func__);
62789a0bf528SMauro Carvalho Chehab 	}
62799a0bf528SMauro Carvalho Chehab 
62809a0bf528SMauro Carvalho Chehab 	return status;
62819a0bf528SMauro Carvalho Chehab }
62829a0bf528SMauro Carvalho Chehab 
62839a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62849a0bf528SMauro Carvalho Chehab 			     void *context)
62859a0bf528SMauro Carvalho Chehab {
62869a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = context;
62879a0bf528SMauro Carvalho Chehab 
62889a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62899a0bf528SMauro Carvalho Chehab 	if (!fw) {
62903a4398f5SMauro Carvalho Chehab 		pr_err("Could not load firmware file %s.\n",
62919a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62923a4398f5SMauro Carvalho Chehab 		pr_info("Copy %s to your hotplug directory!\n",
62939a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62949a0bf528SMauro Carvalho Chehab 		state->microcode_name = NULL;
62959a0bf528SMauro Carvalho Chehab 
62969a0bf528SMauro Carvalho Chehab 		/*
62979a0bf528SMauro Carvalho Chehab 		 * As firmware is now load asynchronous, it is not possible
62989a0bf528SMauro Carvalho Chehab 		 * anymore to fail at frontend attach. We might silently
62999a0bf528SMauro Carvalho Chehab 		 * return here, and hope that the driver won't crash.
63009a0bf528SMauro Carvalho Chehab 		 * We might also change all DVB callbacks to return -ENODEV
63019a0bf528SMauro Carvalho Chehab 		 * if the device is not initialized.
63029a0bf528SMauro Carvalho Chehab 		 * As the DRX-K devices have their own internal firmware,
63039a0bf528SMauro Carvalho Chehab 		 * let's just hope that it will match a firmware revision
63049a0bf528SMauro Carvalho Chehab 		 * compatible with this driver and proceed.
63059a0bf528SMauro Carvalho Chehab 		 */
63069a0bf528SMauro Carvalho Chehab 	}
63079a0bf528SMauro Carvalho Chehab 	state->fw = fw;
63089a0bf528SMauro Carvalho Chehab 
63099a0bf528SMauro Carvalho Chehab 	init_drxk(state);
63109a0bf528SMauro Carvalho Chehab }
63119a0bf528SMauro Carvalho Chehab 
63129a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
63139a0bf528SMauro Carvalho Chehab {
63149a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63159a0bf528SMauro Carvalho Chehab 
63169a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63179a0bf528SMauro Carvalho Chehab 	release_firmware(state->fw);
63189a0bf528SMauro Carvalho Chehab 
63199a0bf528SMauro Carvalho Chehab 	kfree(state);
63209a0bf528SMauro Carvalho Chehab }
63219a0bf528SMauro Carvalho Chehab 
63229a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
63239a0bf528SMauro Carvalho Chehab {
63249a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63259a0bf528SMauro Carvalho Chehab 
63269a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63279a0bf528SMauro Carvalho Chehab 
6328cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63299a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6330cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63319a0bf528SMauro Carvalho Chehab 		return 0;
63329a0bf528SMauro Carvalho Chehab 
6333cd7a67a4SMauro Carvalho Chehab 	shut_down(state);
63349a0bf528SMauro Carvalho Chehab 	return 0;
63359a0bf528SMauro Carvalho Chehab }
63369a0bf528SMauro Carvalho Chehab 
63379a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
63389a0bf528SMauro Carvalho Chehab {
63399a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63409a0bf528SMauro Carvalho Chehab 
63419a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
63429a0bf528SMauro Carvalho Chehab 
6343cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63449a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63459a0bf528SMauro Carvalho Chehab 
63469a0bf528SMauro Carvalho Chehab 	return ConfigureI2CBridge(state, enable ? true : false);
63479a0bf528SMauro Carvalho Chehab }
63489a0bf528SMauro Carvalho Chehab 
63499a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
63509a0bf528SMauro Carvalho Chehab {
63519a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
63529a0bf528SMauro Carvalho Chehab 	u32 delsys  = p->delivery_system, old_delsys;
63539a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63549a0bf528SMauro Carvalho Chehab 	u32 IF;
63559a0bf528SMauro Carvalho Chehab 
63569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63579a0bf528SMauro Carvalho Chehab 
6358cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
63599a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63609a0bf528SMauro Carvalho Chehab 
6361cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
63629a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
63639a0bf528SMauro Carvalho Chehab 
63649a0bf528SMauro Carvalho Chehab 	if (!fe->ops.tuner_ops.get_if_frequency) {
63653a4398f5SMauro Carvalho Chehab 		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63669a0bf528SMauro Carvalho Chehab 		return -EINVAL;
63679a0bf528SMauro Carvalho Chehab 	}
63689a0bf528SMauro Carvalho Chehab 
63699a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63709a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 1);
63719a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
63729a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
63739a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63749a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 0);
63759a0bf528SMauro Carvalho Chehab 
63769a0bf528SMauro Carvalho Chehab 	old_delsys = state->props.delivery_system;
63779a0bf528SMauro Carvalho Chehab 	state->props = *p;
63789a0bf528SMauro Carvalho Chehab 
63799a0bf528SMauro Carvalho Chehab 	if (old_delsys != delsys) {
6380cd7a67a4SMauro Carvalho Chehab 		shut_down(state);
63819a0bf528SMauro Carvalho Chehab 		switch (delsys) {
63829a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_A:
63839a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_C:
6384cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbc)
63859a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6386ab5060cdSMauro Carvalho Chehab 			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6387ab5060cdSMauro Carvalho Chehab 						true : false;
63889a0bf528SMauro Carvalho Chehab 			if (state->m_itut_annex_c)
6389cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_C);
63909a0bf528SMauro Carvalho Chehab 			else
6391cd7a67a4SMauro Carvalho Chehab 				setoperation_mode(state, OM_QAM_ITU_A);
63929a0bf528SMauro Carvalho Chehab 			break;
63939a0bf528SMauro Carvalho Chehab 		case SYS_DVBT:
6394cd7a67a4SMauro Carvalho Chehab 			if (!state->m_has_dvbt)
63959a0bf528SMauro Carvalho Chehab 				return -EINVAL;
6396cd7a67a4SMauro Carvalho Chehab 			setoperation_mode(state, OM_DVBT);
63979a0bf528SMauro Carvalho Chehab 			break;
63989a0bf528SMauro Carvalho Chehab 		default:
63999a0bf528SMauro Carvalho Chehab 			return -EINVAL;
64009a0bf528SMauro Carvalho Chehab 		}
64019a0bf528SMauro Carvalho Chehab 	}
64029a0bf528SMauro Carvalho Chehab 
64039a0bf528SMauro Carvalho Chehab 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
6404cd7a67a4SMauro Carvalho Chehab 	start(state, 0, IF);
64059a0bf528SMauro Carvalho Chehab 
640639c1cb2bSJonathan McCrohan 	/* After set_frontend, stats aren't available */
64078f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
64088f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64098f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64108f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64118f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64128f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64138f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64148f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
64158f3741e0SMauro Carvalho Chehab 
64169a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
64179a0bf528SMauro Carvalho Chehab 
64189a0bf528SMauro Carvalho Chehab 	return 0;
64199a0bf528SMauro Carvalho Chehab }
64209a0bf528SMauro Carvalho Chehab 
642159a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength)
642259a7a23cSMauro Carvalho Chehab {
642359a7a23cSMauro Carvalho Chehab 	int status;
6424cd7a67a4SMauro Carvalho Chehab 	struct s_cfg_agc   rf_agc, if_agc;
6425cd7a67a4SMauro Carvalho Chehab 	u32          total_gain  = 0;
642659a7a23cSMauro Carvalho Chehab 	u32          atten      = 0;
6427cd7a67a4SMauro Carvalho Chehab 	u32          agc_range   = 0;
642859a7a23cSMauro Carvalho Chehab 	u16            scu_lvl  = 0;
642959a7a23cSMauro Carvalho Chehab 	u16            scu_coc  = 0;
643059a7a23cSMauro Carvalho Chehab 	/* FIXME: those are part of the tuner presets */
6431cd7a67a4SMauro Carvalho Chehab 	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
6432cd7a67a4SMauro Carvalho Chehab 	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
643359a7a23cSMauro Carvalho Chehab 
643459a7a23cSMauro Carvalho Chehab 	*strength = 0;
643559a7a23cSMauro Carvalho Chehab 
6436cd7a67a4SMauro Carvalho Chehab 	if (is_dvbt(state)) {
6437cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_dvbt_rf_agc_cfg;
6438cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_dvbt_if_agc_cfg;
6439cd7a67a4SMauro Carvalho Chehab 	} else if (is_qam(state)) {
6440cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_qam_rf_agc_cfg;
6441cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_qam_if_agc_cfg;
644259a7a23cSMauro Carvalho Chehab 	} else {
6443cd7a67a4SMauro Carvalho Chehab 		rf_agc = state->m_atv_rf_agc_cfg;
6444cd7a67a4SMauro Carvalho Chehab 		if_agc = state->m_atv_if_agc_cfg;
644559a7a23cSMauro Carvalho Chehab 	}
644659a7a23cSMauro Carvalho Chehab 
6447cd7a67a4SMauro Carvalho Chehab 	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6448cd7a67a4SMauro Carvalho Chehab 		/* SCU output_level */
644959a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
645059a7a23cSMauro Carvalho Chehab 		if (status < 0)
645159a7a23cSMauro Carvalho Chehab 			return status;
645259a7a23cSMauro Carvalho Chehab 
645359a7a23cSMauro Carvalho Chehab 		/* SCU c.o.c. */
6454d259a5eeSChristophe JAILLET 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
645559a7a23cSMauro Carvalho Chehab 		if (status < 0)
645659a7a23cSMauro Carvalho Chehab 			return status;
645759a7a23cSMauro Carvalho Chehab 
645859a7a23cSMauro Carvalho Chehab 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6459cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = scu_lvl + scu_coc;
646059a7a23cSMauro Carvalho Chehab 		else
6461cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = 0xffff;
646259a7a23cSMauro Carvalho Chehab 
646359a7a23cSMauro Carvalho Chehab 		/* Take RF gain into account */
6464cd7a67a4SMauro Carvalho Chehab 		total_gain += tuner_rf_gain;
646559a7a23cSMauro Carvalho Chehab 
646659a7a23cSMauro Carvalho Chehab 		/* clip output value */
6467cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level < rf_agc.min_output_level)
6468cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.min_output_level;
6469cd7a67a4SMauro Carvalho Chehab 		if (rf_agc.output_level > rf_agc.max_output_level)
6470cd7a67a4SMauro Carvalho Chehab 			rf_agc.output_level = rf_agc.max_output_level;
647159a7a23cSMauro Carvalho Chehab 
6472cd7a67a4SMauro Carvalho Chehab 		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6473cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
647459a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6475cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_rf_gain)) *
6476cd7a67a4SMauro Carvalho Chehab 				((u32)(rf_agc.output_level - rf_agc.min_output_level))
6477cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
647859a7a23cSMauro Carvalho Chehab 		}
647959a7a23cSMauro Carvalho Chehab 	}
648059a7a23cSMauro Carvalho Chehab 
6481cd7a67a4SMauro Carvalho Chehab 	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
648259a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6483cd7a67a4SMauro Carvalho Chehab 				&if_agc.output_level);
648459a7a23cSMauro Carvalho Chehab 		if (status < 0)
648559a7a23cSMauro Carvalho Chehab 			return status;
648659a7a23cSMauro Carvalho Chehab 
648759a7a23cSMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6488cd7a67a4SMauro Carvalho Chehab 				&if_agc.top);
648959a7a23cSMauro Carvalho Chehab 		if (status < 0)
649059a7a23cSMauro Carvalho Chehab 			return status;
649159a7a23cSMauro Carvalho Chehab 
649259a7a23cSMauro Carvalho Chehab 		/* Take IF gain into account */
6493cd7a67a4SMauro Carvalho Chehab 		total_gain += (u32) tuner_if_gain;
649459a7a23cSMauro Carvalho Chehab 
649559a7a23cSMauro Carvalho Chehab 		/* clip output value */
6496cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level < if_agc.min_output_level)
6497cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.min_output_level;
6498cd7a67a4SMauro Carvalho Chehab 		if (if_agc.output_level > if_agc.max_output_level)
6499cd7a67a4SMauro Carvalho Chehab 			if_agc.output_level = if_agc.max_output_level;
650059a7a23cSMauro Carvalho Chehab 
6501cd7a67a4SMauro Carvalho Chehab 		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
6502cd7a67a4SMauro Carvalho Chehab 		if (agc_range > 0) {
650359a7a23cSMauro Carvalho Chehab 			atten += 100UL *
6504cd7a67a4SMauro Carvalho Chehab 				((u32)(tuner_if_gain)) *
6505cd7a67a4SMauro Carvalho Chehab 				((u32)(if_agc.output_level - if_agc.min_output_level))
6506cd7a67a4SMauro Carvalho Chehab 				/ agc_range;
650759a7a23cSMauro Carvalho Chehab 		}
650859a7a23cSMauro Carvalho Chehab 	}
650959a7a23cSMauro Carvalho Chehab 
651059a7a23cSMauro Carvalho Chehab 	/*
651159a7a23cSMauro Carvalho Chehab 	 * Convert to 0..65535 scale.
651259a7a23cSMauro Carvalho Chehab 	 * If it can't be measured (AGC is disabled), just show 100%.
651359a7a23cSMauro Carvalho Chehab 	 */
6514cd7a67a4SMauro Carvalho Chehab 	if (total_gain > 0)
6515cd7a67a4SMauro Carvalho Chehab 		*strength = (65535UL * atten / total_gain / 100);
651659a7a23cSMauro Carvalho Chehab 	else
651759a7a23cSMauro Carvalho Chehab 		*strength = 65535;
651859a7a23cSMauro Carvalho Chehab 
651959a7a23cSMauro Carvalho Chehab 	return 0;
652059a7a23cSMauro Carvalho Chehab }
652159a7a23cSMauro Carvalho Chehab 
65228f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe)
65239a0bf528SMauro Carvalho Chehab {
65248f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
65259a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
65268f3741e0SMauro Carvalho Chehab 	int status;
65279a0bf528SMauro Carvalho Chehab 	u32 stat;
65288f3741e0SMauro Carvalho Chehab 	u16 reg16;
65298f3741e0SMauro Carvalho Chehab 	u32 post_bit_count;
65308f3741e0SMauro Carvalho Chehab 	u32 post_bit_err_count;
65318f3741e0SMauro Carvalho Chehab 	u32 post_bit_error_scale;
65328f3741e0SMauro Carvalho Chehab 	u32 pre_bit_err_count;
65338f3741e0SMauro Carvalho Chehab 	u32 pre_bit_count;
65348f3741e0SMauro Carvalho Chehab 	u32 pkt_count;
65358f3741e0SMauro Carvalho Chehab 	u32 pkt_error_count;
653659a7a23cSMauro Carvalho Chehab 	s32 cnr;
65379a0bf528SMauro Carvalho Chehab 
6538cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
65399a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6540cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
65419a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
65429a0bf528SMauro Carvalho Chehab 
65438f3741e0SMauro Carvalho Chehab 	/* get status */
65448f3741e0SMauro Carvalho Chehab 	state->fe_status = 0;
6545cd7a67a4SMauro Carvalho Chehab 	get_lock_status(state, &stat);
65469a0bf528SMauro Carvalho Chehab 	if (stat == MPEG_LOCK)
65478f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x1f;
65489a0bf528SMauro Carvalho Chehab 	if (stat == FEC_LOCK)
65498f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x0f;
65509a0bf528SMauro Carvalho Chehab 	if (stat == DEMOD_LOCK)
65518f3741e0SMauro Carvalho Chehab 		state->fe_status |= 0x07;
65528f3741e0SMauro Carvalho Chehab 
655359a7a23cSMauro Carvalho Chehab 	/*
655459a7a23cSMauro Carvalho Chehab 	 * Estimate signal strength from AGC
655559a7a23cSMauro Carvalho Chehab 	 */
655659a7a23cSMauro Carvalho Chehab 	get_strength(state, &c->strength.stat[0].uvalue);
655759a7a23cSMauro Carvalho Chehab 	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
655859a7a23cSMauro Carvalho Chehab 
655959a7a23cSMauro Carvalho Chehab 
65608f3741e0SMauro Carvalho Chehab 	if (stat >= DEMOD_LOCK) {
6561cd7a67a4SMauro Carvalho Chehab 		get_signal_to_noise(state, &cnr);
65628f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].svalue = cnr * 100;
65638f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
65648f3741e0SMauro Carvalho Chehab 	} else {
65658f3741e0SMauro Carvalho Chehab 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65668f3741e0SMauro Carvalho Chehab 	}
65678f3741e0SMauro Carvalho Chehab 
65688f3741e0SMauro Carvalho Chehab 	if (stat < FEC_LOCK) {
65698f3741e0SMauro Carvalho Chehab 		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65708f3741e0SMauro Carvalho Chehab 		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65718f3741e0SMauro Carvalho Chehab 		c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65728f3741e0SMauro Carvalho Chehab 		c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65738f3741e0SMauro Carvalho Chehab 		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65748f3741e0SMauro Carvalho Chehab 		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65758f3741e0SMauro Carvalho Chehab 		return 0;
65768f3741e0SMauro Carvalho Chehab 	}
65778f3741e0SMauro Carvalho Chehab 
65788f3741e0SMauro Carvalho Chehab 	/* Get post BER */
65798f3741e0SMauro Carvalho Chehab 
65808f3741e0SMauro Carvalho Chehab 	/* BER measurement is valid if at least FEC lock is achieved */
65818f3741e0SMauro Carvalho Chehab 
6582ab5060cdSMauro Carvalho Chehab 	/*
6583ab5060cdSMauro Carvalho Chehab 	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6584ab5060cdSMauro Carvalho Chehab 	 * written to set nr of symbols or bits over which to measure
6585ab5060cdSMauro Carvalho Chehab 	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6586ab5060cdSMauro Carvalho Chehab 	 */
65878f3741e0SMauro Carvalho Chehab 
65888f3741e0SMauro Carvalho Chehab 	/* Read registers for post/preViterbi BER calculation */
65898f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
65908f3741e0SMauro Carvalho Chehab 	if (status < 0)
65918f3741e0SMauro Carvalho Chehab 		goto error;
65928f3741e0SMauro Carvalho Chehab 	pre_bit_err_count = reg16;
65938f3741e0SMauro Carvalho Chehab 
65948f3741e0SMauro Carvalho Chehab 	status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
65958f3741e0SMauro Carvalho Chehab 	if (status < 0)
65968f3741e0SMauro Carvalho Chehab 		goto error;
65978f3741e0SMauro Carvalho Chehab 	pre_bit_count = reg16;
65988f3741e0SMauro Carvalho Chehab 
65998f3741e0SMauro Carvalho Chehab 	/* Number of bit-errors */
66008f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
66018f3741e0SMauro Carvalho Chehab 	if (status < 0)
66028f3741e0SMauro Carvalho Chehab 		goto error;
66038f3741e0SMauro Carvalho Chehab 	post_bit_err_count = reg16;
66048f3741e0SMauro Carvalho Chehab 
66058f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
66068f3741e0SMauro Carvalho Chehab 	if (status < 0)
66078f3741e0SMauro Carvalho Chehab 		goto error;
66088f3741e0SMauro Carvalho Chehab 	post_bit_error_scale = reg16;
66098f3741e0SMauro Carvalho Chehab 
66108f3741e0SMauro Carvalho Chehab 	status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
66118f3741e0SMauro Carvalho Chehab 	if (status < 0)
66128f3741e0SMauro Carvalho Chehab 		goto error;
66138f3741e0SMauro Carvalho Chehab 	pkt_count = reg16;
66148f3741e0SMauro Carvalho Chehab 
66158f3741e0SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
66168f3741e0SMauro Carvalho Chehab 	if (status < 0)
66178f3741e0SMauro Carvalho Chehab 		goto error;
66188f3741e0SMauro Carvalho Chehab 	pkt_error_count = reg16;
66198f3741e0SMauro Carvalho Chehab 	write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
66208f3741e0SMauro Carvalho Chehab 
66218f3741e0SMauro Carvalho Chehab 	post_bit_err_count *= post_bit_error_scale;
66228f3741e0SMauro Carvalho Chehab 
66238f3741e0SMauro Carvalho Chehab 	post_bit_count = pkt_count * 204 * 8;
66248f3741e0SMauro Carvalho Chehab 
66258f3741e0SMauro Carvalho Chehab 	/* Store the results */
66268f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
66278f3741e0SMauro Carvalho Chehab 	c->block_error.stat[0].uvalue += pkt_error_count;
66288f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].scale = FE_SCALE_COUNTER;
66298f3741e0SMauro Carvalho Chehab 	c->block_count.stat[0].uvalue += pkt_count;
66308f3741e0SMauro Carvalho Chehab 
66318f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66328f3741e0SMauro Carvalho Chehab 	c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
66338f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66348f3741e0SMauro Carvalho Chehab 	c->pre_bit_count.stat[0].uvalue += pre_bit_count;
66358f3741e0SMauro Carvalho Chehab 
66368f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
66378f3741e0SMauro Carvalho Chehab 	c->post_bit_error.stat[0].uvalue += post_bit_err_count;
66388f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
66398f3741e0SMauro Carvalho Chehab 	c->post_bit_count.stat[0].uvalue += post_bit_count;
66408f3741e0SMauro Carvalho Chehab 
66418f3741e0SMauro Carvalho Chehab error:
66428f3741e0SMauro Carvalho Chehab 	return status;
66438f3741e0SMauro Carvalho Chehab }
66448f3741e0SMauro Carvalho Chehab 
66458f3741e0SMauro Carvalho Chehab 
66460df289a2SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status)
66478f3741e0SMauro Carvalho Chehab {
66488f3741e0SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66498f3741e0SMauro Carvalho Chehab 	int rc;
66508f3741e0SMauro Carvalho Chehab 
66518f3741e0SMauro Carvalho Chehab 	dprintk(1, "\n");
66528f3741e0SMauro Carvalho Chehab 
66538f3741e0SMauro Carvalho Chehab 	rc = drxk_get_stats(fe);
66548f3741e0SMauro Carvalho Chehab 	if (rc < 0)
66558f3741e0SMauro Carvalho Chehab 		return rc;
66568f3741e0SMauro Carvalho Chehab 
66578f3741e0SMauro Carvalho Chehab 	*status = state->fe_status;
66588f3741e0SMauro Carvalho Chehab 
66599a0bf528SMauro Carvalho Chehab 	return 0;
66609a0bf528SMauro Carvalho Chehab }
66619a0bf528SMauro Carvalho Chehab 
66629a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
66639a0bf528SMauro Carvalho Chehab 				     u16 *strength)
66649a0bf528SMauro Carvalho Chehab {
66659a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
6666340e7696SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
66679a0bf528SMauro Carvalho Chehab 
66689a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66699a0bf528SMauro Carvalho Chehab 
6670cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66719a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6672cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66739a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66749a0bf528SMauro Carvalho Chehab 
6675340e7696SMauro Carvalho Chehab 	*strength = c->strength.stat[0].uvalue;
66769a0bf528SMauro Carvalho Chehab 	return 0;
66779a0bf528SMauro Carvalho Chehab }
66789a0bf528SMauro Carvalho Chehab 
66799a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
66809a0bf528SMauro Carvalho Chehab {
66819a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
66829a0bf528SMauro Carvalho Chehab 	s32 snr2;
66839a0bf528SMauro Carvalho Chehab 
66849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
66859a0bf528SMauro Carvalho Chehab 
6686cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
66879a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6688cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
66899a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
66909a0bf528SMauro Carvalho Chehab 
6691cd7a67a4SMauro Carvalho Chehab 	get_signal_to_noise(state, &snr2);
66928f3741e0SMauro Carvalho Chehab 
66938f3741e0SMauro Carvalho Chehab 	/* No negative SNR, clip to zero */
66948f3741e0SMauro Carvalho Chehab 	if (snr2 < 0)
66958f3741e0SMauro Carvalho Chehab 		snr2 = 0;
66969a0bf528SMauro Carvalho Chehab 	*snr = snr2 & 0xffff;
66979a0bf528SMauro Carvalho Chehab 	return 0;
66989a0bf528SMauro Carvalho Chehab }
66999a0bf528SMauro Carvalho Chehab 
67009a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
67019a0bf528SMauro Carvalho Chehab {
67029a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
67039a0bf528SMauro Carvalho Chehab 	u16 err;
67049a0bf528SMauro Carvalho Chehab 
67059a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67069a0bf528SMauro Carvalho Chehab 
6707cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
67089a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6709cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
67109a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
67119a0bf528SMauro Carvalho Chehab 
6712cd7a67a4SMauro Carvalho Chehab 	dvbtqam_get_acc_pkt_err(state, &err);
67139a0bf528SMauro Carvalho Chehab 	*ucblocks = (u32) err;
67149a0bf528SMauro Carvalho Chehab 	return 0;
67159a0bf528SMauro Carvalho Chehab }
67169a0bf528SMauro Carvalho Chehab 
6717ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe,
6718ab5060cdSMauro Carvalho Chehab 				  struct dvb_frontend_tune_settings *sets)
67199a0bf528SMauro Carvalho Chehab {
67209a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
67219a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
67229a0bf528SMauro Carvalho Chehab 
67239a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67249a0bf528SMauro Carvalho Chehab 
6725cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_NO_DEV)
67269a0bf528SMauro Carvalho Chehab 		return -ENODEV;
6727cd7a67a4SMauro Carvalho Chehab 	if (state->m_drxk_state == DRXK_UNINITIALIZED)
67289a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
67299a0bf528SMauro Carvalho Chehab 
67309a0bf528SMauro Carvalho Chehab 	switch (p->delivery_system) {
67319a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_A:
67329a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_C:
67339a0bf528SMauro Carvalho Chehab 	case SYS_DVBT:
67349a0bf528SMauro Carvalho Chehab 		sets->min_delay_ms = 3000;
67359a0bf528SMauro Carvalho Chehab 		sets->max_drift = 0;
67369a0bf528SMauro Carvalho Chehab 		sets->step_size = 0;
67379a0bf528SMauro Carvalho Chehab 		return 0;
67389a0bf528SMauro Carvalho Chehab 	default:
67399a0bf528SMauro Carvalho Chehab 		return -EINVAL;
67409a0bf528SMauro Carvalho Chehab 	}
67419a0bf528SMauro Carvalho Chehab }
67429a0bf528SMauro Carvalho Chehab 
6743bd336e63SMax Kellermann static const struct dvb_frontend_ops drxk_ops = {
67449a0bf528SMauro Carvalho Chehab 	/* .delsys will be filled dynamically */
67459a0bf528SMauro Carvalho Chehab 	.info = {
67469a0bf528SMauro Carvalho Chehab 		.name = "DRXK",
67479a0bf528SMauro Carvalho Chehab 		.frequency_min = 47000000,
67489a0bf528SMauro Carvalho Chehab 		.frequency_max = 865000000,
67499a0bf528SMauro Carvalho Chehab 		 /* For DVB-C */
67509a0bf528SMauro Carvalho Chehab 		.symbol_rate_min = 870000,
67519a0bf528SMauro Carvalho Chehab 		.symbol_rate_max = 11700000,
67529a0bf528SMauro Carvalho Chehab 		/* For DVB-T */
67539a0bf528SMauro Carvalho Chehab 		.frequency_stepsize = 166667,
67549a0bf528SMauro Carvalho Chehab 
67559a0bf528SMauro Carvalho Chehab 		.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
67569a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
67579a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
67589a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
67599a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
67609a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
67619a0bf528SMauro Carvalho Chehab 	},
67629a0bf528SMauro Carvalho Chehab 
67639a0bf528SMauro Carvalho Chehab 	.release = drxk_release,
67649a0bf528SMauro Carvalho Chehab 	.sleep = drxk_sleep,
67659a0bf528SMauro Carvalho Chehab 	.i2c_gate_ctrl = drxk_gate_ctrl,
67669a0bf528SMauro Carvalho Chehab 
67679a0bf528SMauro Carvalho Chehab 	.set_frontend = drxk_set_parameters,
67689a0bf528SMauro Carvalho Chehab 	.get_tune_settings = drxk_get_tune_settings,
67699a0bf528SMauro Carvalho Chehab 
67709a0bf528SMauro Carvalho Chehab 	.read_status = drxk_read_status,
67719a0bf528SMauro Carvalho Chehab 	.read_signal_strength = drxk_read_signal_strength,
67729a0bf528SMauro Carvalho Chehab 	.read_snr = drxk_read_snr,
67739a0bf528SMauro Carvalho Chehab 	.read_ucblocks = drxk_read_ucblocks,
67749a0bf528SMauro Carvalho Chehab };
67759a0bf528SMauro Carvalho Chehab 
67769a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
67779a0bf528SMauro Carvalho Chehab 				 struct i2c_adapter *i2c)
67789a0bf528SMauro Carvalho Chehab {
67798f3741e0SMauro Carvalho Chehab 	struct dtv_frontend_properties *p;
67809a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = NULL;
67819a0bf528SMauro Carvalho Chehab 	u8 adr = config->adr;
67829a0bf528SMauro Carvalho Chehab 	int status;
67839a0bf528SMauro Carvalho Chehab 
67849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
67859a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
67869a0bf528SMauro Carvalho Chehab 	if (!state)
67879a0bf528SMauro Carvalho Chehab 		return NULL;
67889a0bf528SMauro Carvalho Chehab 
67899a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
67909a0bf528SMauro Carvalho Chehab 	state->demod_address = adr;
67919a0bf528SMauro Carvalho Chehab 	state->single_master = config->single_master;
67929a0bf528SMauro Carvalho Chehab 	state->microcode_name = config->microcode_name;
67939a0bf528SMauro Carvalho Chehab 	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
67949a0bf528SMauro Carvalho Chehab 	state->no_i2c_bridge = config->no_i2c_bridge;
67959a0bf528SMauro Carvalho Chehab 	state->antenna_gpio = config->antenna_gpio;
67969a0bf528SMauro Carvalho Chehab 	state->antenna_dvbt = config->antenna_dvbt;
6797cd7a67a4SMauro Carvalho Chehab 	state->m_chunk_size = config->chunk_size;
67989a0bf528SMauro Carvalho Chehab 	state->enable_merr_cfg = config->enable_merr_cfg;
67999a0bf528SMauro Carvalho Chehab 
68009a0bf528SMauro Carvalho Chehab 	if (config->dynamic_clk) {
68015a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = false;
68025a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = false;
68039a0bf528SMauro Carvalho Chehab 	} else {
68045a7f7b79SMauro Carvalho Chehab 		state->m_dvbt_static_clk = true;
68055a7f7b79SMauro Carvalho Chehab 		state->m_dvbc_static_clk = true;
68069a0bf528SMauro Carvalho Chehab 	}
68079a0bf528SMauro Carvalho Chehab 
68089a0bf528SMauro Carvalho Chehab 
68099a0bf528SMauro Carvalho Chehab 	if (config->mpeg_out_clk_strength)
6810cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
68119a0bf528SMauro Carvalho Chehab 	else
6812cd7a67a4SMauro Carvalho Chehab 		state->m_ts_clockk_strength = 0x06;
68139a0bf528SMauro Carvalho Chehab 
68149a0bf528SMauro Carvalho Chehab 	if (config->parallel_ts)
6815cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = true;
68169a0bf528SMauro Carvalho Chehab 	else
6817cd7a67a4SMauro Carvalho Chehab 		state->m_enable_parallel = false;
68189a0bf528SMauro Carvalho Chehab 
68199a0bf528SMauro Carvalho Chehab 	/* NOTE: as more UIO bits will be used, add them to the mask */
6820cd7a67a4SMauro Carvalho Chehab 	state->uio_mask = config->antenna_gpio;
68219a0bf528SMauro Carvalho Chehab 
68229a0bf528SMauro Carvalho Chehab 	/* Default gpio to DVB-C */
68239a0bf528SMauro Carvalho Chehab 	if (!state->antenna_dvbt && state->antenna_gpio)
6824cd7a67a4SMauro Carvalho Chehab 		state->m_gpio |= state->antenna_gpio;
68259a0bf528SMauro Carvalho Chehab 	else
6826cd7a67a4SMauro Carvalho Chehab 		state->m_gpio &= ~state->antenna_gpio;
68279a0bf528SMauro Carvalho Chehab 
68289a0bf528SMauro Carvalho Chehab 	mutex_init(&state->mutex);
68299a0bf528SMauro Carvalho Chehab 
68309a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
68319a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
68329a0bf528SMauro Carvalho Chehab 
68339a0bf528SMauro Carvalho Chehab 	init_state(state);
68349a0bf528SMauro Carvalho Chehab 
68359a0bf528SMauro Carvalho Chehab 	/* Load firmware and initialize DRX-K */
68369a0bf528SMauro Carvalho Chehab 	if (state->microcode_name) {
68378e30783bSMauro Carvalho Chehab 		const struct firmware *fw = NULL;
68388e30783bSMauro Carvalho Chehab 
68398e30783bSMauro Carvalho Chehab 		status = request_firmware(&fw, state->microcode_name,
68408e30783bSMauro Carvalho Chehab 					  state->i2c->dev.parent);
68418e30783bSMauro Carvalho Chehab 		if (status < 0)
68428e30783bSMauro Carvalho Chehab 			fw = NULL;
68438e30783bSMauro Carvalho Chehab 		load_firmware_cb(fw, state);
68449a0bf528SMauro Carvalho Chehab 	} else if (init_drxk(state) < 0)
68459a0bf528SMauro Carvalho Chehab 		goto error;
68469a0bf528SMauro Carvalho Chehab 
68478f3741e0SMauro Carvalho Chehab 
68488f3741e0SMauro Carvalho Chehab 	/* Initialize stats */
68498f3741e0SMauro Carvalho Chehab 	p = &state->frontend.dtv_property_cache;
68508f3741e0SMauro Carvalho Chehab 	p->strength.len = 1;
68518f3741e0SMauro Carvalho Chehab 	p->cnr.len = 1;
68528f3741e0SMauro Carvalho Chehab 	p->block_error.len = 1;
68538f3741e0SMauro Carvalho Chehab 	p->block_count.len = 1;
68548f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.len = 1;
68558f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.len = 1;
68568f3741e0SMauro Carvalho Chehab 	p->post_bit_error.len = 1;
68578f3741e0SMauro Carvalho Chehab 	p->post_bit_count.len = 1;
68588f3741e0SMauro Carvalho Chehab 
68598f3741e0SMauro Carvalho Chehab 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
68608f3741e0SMauro Carvalho Chehab 	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68618f3741e0SMauro Carvalho Chehab 	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68628f3741e0SMauro Carvalho Chehab 	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68638f3741e0SMauro Carvalho Chehab 	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68648f3741e0SMauro Carvalho Chehab 	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68658f3741e0SMauro Carvalho Chehab 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68668f3741e0SMauro Carvalho Chehab 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68678f3741e0SMauro Carvalho Chehab 
68683a4398f5SMauro Carvalho Chehab 	pr_info("frontend initialized.\n");
68699a0bf528SMauro Carvalho Chehab 	return &state->frontend;
68709a0bf528SMauro Carvalho Chehab 
68719a0bf528SMauro Carvalho Chehab error:
68723a4398f5SMauro Carvalho Chehab 	pr_err("not found\n");
68739a0bf528SMauro Carvalho Chehab 	kfree(state);
68749a0bf528SMauro Carvalho Chehab 	return NULL;
68759a0bf528SMauro Carvalho Chehab }
68769a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach);
68779a0bf528SMauro Carvalho Chehab 
68789a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
68799a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
68809a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6881