19a0bf528SMauro Carvalho Chehab /*
29a0bf528SMauro Carvalho Chehab  * drxk_hard: DRX-K DVB-C/T demodulator driver
39a0bf528SMauro Carvalho Chehab  *
49a0bf528SMauro Carvalho Chehab  * Copyright (C) 2010-2011 Digital Devices GmbH
59a0bf528SMauro Carvalho Chehab  *
69a0bf528SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or
79a0bf528SMauro Carvalho Chehab  * modify it under the terms of the GNU General Public License
89a0bf528SMauro Carvalho Chehab  * version 2 only, as published by the Free Software Foundation.
99a0bf528SMauro Carvalho Chehab  *
109a0bf528SMauro Carvalho Chehab  *
119a0bf528SMauro Carvalho Chehab  * This program is distributed in the hope that it will be useful,
129a0bf528SMauro Carvalho Chehab  * but WITHOUT ANY WARRANTY; without even the implied warranty of
139a0bf528SMauro Carvalho Chehab  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149a0bf528SMauro Carvalho Chehab  * GNU General Public License for more details.
159a0bf528SMauro Carvalho Chehab  *
169a0bf528SMauro Carvalho Chehab  *
179a0bf528SMauro Carvalho Chehab  * You should have received a copy of the GNU General Public License
189a0bf528SMauro Carvalho Chehab  * along with this program; if not, write to the Free Software
199a0bf528SMauro Carvalho Chehab  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
209a0bf528SMauro Carvalho Chehab  * 02110-1301, USA
219a0bf528SMauro Carvalho Chehab  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
229a0bf528SMauro Carvalho Chehab  */
239a0bf528SMauro Carvalho Chehab 
249a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
259a0bf528SMauro Carvalho Chehab #include <linux/module.h>
269a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
279a0bf528SMauro Carvalho Chehab #include <linux/init.h>
289a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
299a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
309a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
319a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
329a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
339a0bf528SMauro Carvalho Chehab 
349a0bf528SMauro Carvalho Chehab #include "dvb_frontend.h"
359a0bf528SMauro Carvalho Chehab #include "drxk.h"
369a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
379a0bf528SMauro Carvalho Chehab 
389a0bf528SMauro Carvalho Chehab static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
399a0bf528SMauro Carvalho Chehab static int PowerDownQAM(struct drxk_state *state);
409a0bf528SMauro Carvalho Chehab static int SetDVBTStandard(struct drxk_state *state,
419a0bf528SMauro Carvalho Chehab 			   enum OperationMode oMode);
429a0bf528SMauro Carvalho Chehab static int SetQAMStandard(struct drxk_state *state,
439a0bf528SMauro Carvalho Chehab 			  enum OperationMode oMode);
449a0bf528SMauro Carvalho Chehab static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
459a0bf528SMauro Carvalho Chehab 		  s32 tunerFreqOffset);
469a0bf528SMauro Carvalho Chehab static int SetDVBTStandard(struct drxk_state *state,
479a0bf528SMauro Carvalho Chehab 			   enum OperationMode oMode);
489a0bf528SMauro Carvalho Chehab static int DVBTStart(struct drxk_state *state);
499a0bf528SMauro Carvalho Chehab static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
509a0bf528SMauro Carvalho Chehab 		   s32 tunerFreqOffset);
519a0bf528SMauro Carvalho Chehab static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
529a0bf528SMauro Carvalho Chehab static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
539a0bf528SMauro Carvalho Chehab static int SwitchAntennaToQAM(struct drxk_state *state);
549a0bf528SMauro Carvalho Chehab static int SwitchAntennaToDVBT(struct drxk_state *state);
559a0bf528SMauro Carvalho Chehab 
569a0bf528SMauro Carvalho Chehab static bool IsDVBT(struct drxk_state *state)
579a0bf528SMauro Carvalho Chehab {
589a0bf528SMauro Carvalho Chehab 	return state->m_OperationMode == OM_DVBT;
599a0bf528SMauro Carvalho Chehab }
609a0bf528SMauro Carvalho Chehab 
619a0bf528SMauro Carvalho Chehab static bool IsQAM(struct drxk_state *state)
629a0bf528SMauro Carvalho Chehab {
639a0bf528SMauro Carvalho Chehab 	return state->m_OperationMode == OM_QAM_ITU_A ||
649a0bf528SMauro Carvalho Chehab 	    state->m_OperationMode == OM_QAM_ITU_B ||
659a0bf528SMauro Carvalho Chehab 	    state->m_OperationMode == OM_QAM_ITU_C;
669a0bf528SMauro Carvalho Chehab }
679a0bf528SMauro Carvalho Chehab 
689a0bf528SMauro Carvalho Chehab bool IsA1WithPatchCode(struct drxk_state *state)
699a0bf528SMauro Carvalho Chehab {
709a0bf528SMauro Carvalho Chehab 	return state->m_DRXK_A1_PATCH_CODE;
719a0bf528SMauro Carvalho Chehab }
729a0bf528SMauro Carvalho Chehab 
739a0bf528SMauro Carvalho Chehab bool IsA1WithRomCode(struct drxk_state *state)
749a0bf528SMauro Carvalho Chehab {
759a0bf528SMauro Carvalho Chehab 	return state->m_DRXK_A1_ROM_CODE;
769a0bf528SMauro Carvalho Chehab }
779a0bf528SMauro Carvalho Chehab 
789a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
799a0bf528SMauro Carvalho Chehab 
809a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
819a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
829a0bf528SMauro Carvalho Chehab 
839a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83  165
849a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93  250
859a0bf528SMauro Carvalho Chehab 
869a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
879a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
889a0bf528SMauro Carvalho Chehab #endif
899a0bf528SMauro Carvalho Chehab 
909a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
919a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
929a0bf528SMauro Carvalho Chehab #endif
939a0bf528SMauro Carvalho Chehab 
949a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
959a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
969a0bf528SMauro Carvalho Chehab 
979a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
989a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV   4
999a0bf528SMauro Carvalho Chehab #endif
1009a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
1019a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV   6
1029a0bf528SMauro Carvalho Chehab #endif
1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
1049a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV   7
1059a0bf528SMauro Carvalho Chehab #endif
1069a0bf528SMauro Carvalho Chehab 
1079a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
1089a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM   3
1099a0bf528SMauro Carvalho Chehab #endif
1109a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
1119a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM   4
1129a0bf528SMauro Carvalho Chehab #endif
1139a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
1149a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM   7
1159a0bf528SMauro Carvalho Chehab #endif
1169a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
1179a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
1189a0bf528SMauro Carvalho Chehab #endif
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
1209a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1239a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
1249a0bf528SMauro Carvalho Chehab #endif
1259a0bf528SMauro Carvalho Chehab 
1269a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1279a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1289a0bf528SMauro Carvalho Chehab #endif
1299a0bf528SMauro Carvalho Chehab 
1309a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1319a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
1329a0bf528SMauro Carvalho Chehab #endif
1339a0bf528SMauro Carvalho Chehab 
1349a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1359a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
1369a0bf528SMauro Carvalho Chehab #endif
1379a0bf528SMauro Carvalho Chehab 
1389a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1399a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
1409a0bf528SMauro Carvalho Chehab #endif
1419a0bf528SMauro Carvalho Chehab 
1429a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1439a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
1449a0bf528SMauro Carvalho Chehab #endif
1459a0bf528SMauro Carvalho Chehab 
1469a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
1479a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
1489a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
1499a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG      24
1509a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
1519a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
1529a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM      48
1539a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE        0
1549a0bf528SMauro Carvalho Chehab 
1559a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT                100
1569a0bf528SMauro Carvalho Chehab 
1579a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS      2
1589a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE     6
1599a0bf528SMauro Carvalho Chehab 
1609a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS      28
1619a0bf528SMauro Carvalho Chehab 
1629a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1639a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
1649a0bf528SMauro Carvalho Chehab #endif
1659a0bf528SMauro Carvalho Chehab 
1669a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
1679a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
1689a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
1699a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
1709a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
1719a0bf528SMauro Carvalho Chehab 
1729a0bf528SMauro Carvalho Chehab static unsigned int debug;
1739a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1749a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1759a0bf528SMauro Carvalho Chehab 
1769a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do {			\
1779a0bf528SMauro Carvalho Chehab if (debug >= level)						\
1789a0bf528SMauro Carvalho Chehab 	printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg);	\
1799a0bf528SMauro Carvalho Chehab } while (0)
1809a0bf528SMauro Carvalho Chehab 
1819a0bf528SMauro Carvalho Chehab 
1829a0bf528SMauro Carvalho Chehab static inline u32 MulDiv32(u32 a, u32 b, u32 c)
1839a0bf528SMauro Carvalho Chehab {
1849a0bf528SMauro Carvalho Chehab 	u64 tmp64;
1859a0bf528SMauro Carvalho Chehab 
1869a0bf528SMauro Carvalho Chehab 	tmp64 = (u64) a * (u64) b;
1879a0bf528SMauro Carvalho Chehab 	do_div(tmp64, c);
1889a0bf528SMauro Carvalho Chehab 
1899a0bf528SMauro Carvalho Chehab 	return (u32) tmp64;
1909a0bf528SMauro Carvalho Chehab }
1919a0bf528SMauro Carvalho Chehab 
1929a0bf528SMauro Carvalho Chehab inline u32 Frac28a(u32 a, u32 c)
1939a0bf528SMauro Carvalho Chehab {
1949a0bf528SMauro Carvalho Chehab 	int i = 0;
1959a0bf528SMauro Carvalho Chehab 	u32 Q1 = 0;
1969a0bf528SMauro Carvalho Chehab 	u32 R0 = 0;
1979a0bf528SMauro Carvalho Chehab 
1989a0bf528SMauro Carvalho Chehab 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
1999a0bf528SMauro Carvalho Chehab 	Q1 = a / c;		/* integer part, only the 4 least significant bits
2009a0bf528SMauro Carvalho Chehab 				   will be visible in the result */
2019a0bf528SMauro Carvalho Chehab 
2029a0bf528SMauro Carvalho Chehab 	/* division using radix 16, 7 nibbles in the result */
2039a0bf528SMauro Carvalho Chehab 	for (i = 0; i < 7; i++) {
2049a0bf528SMauro Carvalho Chehab 		Q1 = (Q1 << 4) | (R0 / c);
2059a0bf528SMauro Carvalho Chehab 		R0 = (R0 % c) << 4;
2069a0bf528SMauro Carvalho Chehab 	}
2079a0bf528SMauro Carvalho Chehab 	/* rounding */
2089a0bf528SMauro Carvalho Chehab 	if ((R0 >> 3) >= c)
2099a0bf528SMauro Carvalho Chehab 		Q1++;
2109a0bf528SMauro Carvalho Chehab 
2119a0bf528SMauro Carvalho Chehab 	return Q1;
2129a0bf528SMauro Carvalho Chehab }
2139a0bf528SMauro Carvalho Chehab 
2149a0bf528SMauro Carvalho Chehab static u32 Log10Times100(u32 x)
2159a0bf528SMauro Carvalho Chehab {
2169a0bf528SMauro Carvalho Chehab 	static const u8 scale = 15;
2179a0bf528SMauro Carvalho Chehab 	static const u8 indexWidth = 5;
2189a0bf528SMauro Carvalho Chehab 	u8 i = 0;
2199a0bf528SMauro Carvalho Chehab 	u32 y = 0;
2209a0bf528SMauro Carvalho Chehab 	u32 d = 0;
2219a0bf528SMauro Carvalho Chehab 	u32 k = 0;
2229a0bf528SMauro Carvalho Chehab 	u32 r = 0;
2239a0bf528SMauro Carvalho Chehab 	/*
2249a0bf528SMauro Carvalho Chehab 	   log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
2259a0bf528SMauro Carvalho Chehab 	   0 <= n < ((1<<INDEXWIDTH)+1)
2269a0bf528SMauro Carvalho Chehab 	 */
2279a0bf528SMauro Carvalho Chehab 
2289a0bf528SMauro Carvalho Chehab 	static const u32 log2lut[] = {
2299a0bf528SMauro Carvalho Chehab 		0,		/* 0.000000 */
2309a0bf528SMauro Carvalho Chehab 		290941,		/* 290941.300628 */
2319a0bf528SMauro Carvalho Chehab 		573196,		/* 573196.476418 */
2329a0bf528SMauro Carvalho Chehab 		847269,		/* 847269.179851 */
2339a0bf528SMauro Carvalho Chehab 		1113620,	/* 1113620.489452 */
2349a0bf528SMauro Carvalho Chehab 		1372674,	/* 1372673.576986 */
2359a0bf528SMauro Carvalho Chehab 		1624818,	/* 1624817.752104 */
2369a0bf528SMauro Carvalho Chehab 		1870412,	/* 1870411.981536 */
2379a0bf528SMauro Carvalho Chehab 		2109788,	/* 2109787.962654 */
2389a0bf528SMauro Carvalho Chehab 		2343253,	/* 2343252.817465 */
2399a0bf528SMauro Carvalho Chehab 		2571091,	/* 2571091.461923 */
2409a0bf528SMauro Carvalho Chehab 		2793569,	/* 2793568.696416 */
2419a0bf528SMauro Carvalho Chehab 		3010931,	/* 3010931.055901 */
2429a0bf528SMauro Carvalho Chehab 		3223408,	/* 3223408.452106 */
2439a0bf528SMauro Carvalho Chehab 		3431216,	/* 3431215.635215 */
2449a0bf528SMauro Carvalho Chehab 		3634553,	/* 3634553.498355 */
2459a0bf528SMauro Carvalho Chehab 		3833610,	/* 3833610.244726 */
2469a0bf528SMauro Carvalho Chehab 		4028562,	/* 4028562.434393 */
2479a0bf528SMauro Carvalho Chehab 		4219576,	/* 4219575.925308 */
2489a0bf528SMauro Carvalho Chehab 		4406807,	/* 4406806.721144 */
2499a0bf528SMauro Carvalho Chehab 		4590402,	/* 4590401.736809 */
2509a0bf528SMauro Carvalho Chehab 		4770499,	/* 4770499.491025 */
2519a0bf528SMauro Carvalho Chehab 		4947231,	/* 4947230.734179 */
2529a0bf528SMauro Carvalho Chehab 		5120719,	/* 5120719.018555 */
2539a0bf528SMauro Carvalho Chehab 		5291081,	/* 5291081.217197 */
2549a0bf528SMauro Carvalho Chehab 		5458428,	/* 5458427.996830 */
2559a0bf528SMauro Carvalho Chehab 		5622864,	/* 5622864.249668 */
2569a0bf528SMauro Carvalho Chehab 		5784489,	/* 5784489.488298 */
2579a0bf528SMauro Carvalho Chehab 		5943398,	/* 5943398.207380 */
2589a0bf528SMauro Carvalho Chehab 		6099680,	/* 6099680.215452 */
2599a0bf528SMauro Carvalho Chehab 		6253421,	/* 6253420.939751 */
2609a0bf528SMauro Carvalho Chehab 		6404702,	/* 6404701.706649 */
2619a0bf528SMauro Carvalho Chehab 		6553600,	/* 6553600.000000 */
2629a0bf528SMauro Carvalho Chehab 	};
2639a0bf528SMauro Carvalho Chehab 
2649a0bf528SMauro Carvalho Chehab 
2659a0bf528SMauro Carvalho Chehab 	if (x == 0)
2669a0bf528SMauro Carvalho Chehab 		return 0;
2679a0bf528SMauro Carvalho Chehab 
2689a0bf528SMauro Carvalho Chehab 	/* Scale x (normalize) */
2699a0bf528SMauro Carvalho Chehab 	/* computing y in log(x/y) = log(x) - log(y) */
2709a0bf528SMauro Carvalho Chehab 	if ((x & ((0xffffffff) << (scale + 1))) == 0) {
2719a0bf528SMauro Carvalho Chehab 		for (k = scale; k > 0; k--) {
2729a0bf528SMauro Carvalho Chehab 			if (x & (((u32) 1) << scale))
2739a0bf528SMauro Carvalho Chehab 				break;
2749a0bf528SMauro Carvalho Chehab 			x <<= 1;
2759a0bf528SMauro Carvalho Chehab 		}
2769a0bf528SMauro Carvalho Chehab 	} else {
2779a0bf528SMauro Carvalho Chehab 		for (k = scale; k < 31; k++) {
2789a0bf528SMauro Carvalho Chehab 			if ((x & (((u32) (-1)) << (scale + 1))) == 0)
2799a0bf528SMauro Carvalho Chehab 				break;
2809a0bf528SMauro Carvalho Chehab 			x >>= 1;
2819a0bf528SMauro Carvalho Chehab 		}
2829a0bf528SMauro Carvalho Chehab 	}
2839a0bf528SMauro Carvalho Chehab 	/*
2849a0bf528SMauro Carvalho Chehab 	   Now x has binary point between bit[scale] and bit[scale-1]
2859a0bf528SMauro Carvalho Chehab 	   and 1.0 <= x < 2.0 */
2869a0bf528SMauro Carvalho Chehab 
2879a0bf528SMauro Carvalho Chehab 	/* correction for divison: log(x) = log(x/y)+log(y) */
2889a0bf528SMauro Carvalho Chehab 	y = k * ((((u32) 1) << scale) * 200);
2899a0bf528SMauro Carvalho Chehab 
2909a0bf528SMauro Carvalho Chehab 	/* remove integer part */
2919a0bf528SMauro Carvalho Chehab 	x &= ((((u32) 1) << scale) - 1);
2929a0bf528SMauro Carvalho Chehab 	/* get index */
2939a0bf528SMauro Carvalho Chehab 	i = (u8) (x >> (scale - indexWidth));
2949a0bf528SMauro Carvalho Chehab 	/* compute delta (x - a) */
2959a0bf528SMauro Carvalho Chehab 	d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
2969a0bf528SMauro Carvalho Chehab 	/* compute log, multiplication (d* (..)) must be within range ! */
2979a0bf528SMauro Carvalho Chehab 	y += log2lut[i] +
2989a0bf528SMauro Carvalho Chehab 	    ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
2999a0bf528SMauro Carvalho Chehab 	/* Conver to log10() */
3009a0bf528SMauro Carvalho Chehab 	y /= 108853;		/* (log2(10) << scale) */
3019a0bf528SMauro Carvalho Chehab 	r = (y >> 1);
3029a0bf528SMauro Carvalho Chehab 	/* rounding */
3039a0bf528SMauro Carvalho Chehab 	if (y & ((u32) 1))
3049a0bf528SMauro Carvalho Chehab 		r++;
3059a0bf528SMauro Carvalho Chehab 	return r;
3069a0bf528SMauro Carvalho Chehab }
3079a0bf528SMauro Carvalho Chehab 
3089a0bf528SMauro Carvalho Chehab /****************************************************************************/
3099a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
3109a0bf528SMauro Carvalho Chehab /****************************************************************************/
3119a0bf528SMauro Carvalho Chehab 
3129a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
3139a0bf528SMauro Carvalho Chehab {
3149a0bf528SMauro Carvalho Chehab 	i2c_lock_adapter(state->i2c);
3159a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = true;
3169a0bf528SMauro Carvalho Chehab 
3179a0bf528SMauro Carvalho Chehab 	return 0;
3189a0bf528SMauro Carvalho Chehab }
3199a0bf528SMauro Carvalho Chehab 
3209a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
3219a0bf528SMauro Carvalho Chehab {
3229a0bf528SMauro Carvalho Chehab 	if (!state->drxk_i2c_exclusive_lock)
3239a0bf528SMauro Carvalho Chehab 		return;
3249a0bf528SMauro Carvalho Chehab 
3259a0bf528SMauro Carvalho Chehab 	i2c_unlock_adapter(state->i2c);
3269a0bf528SMauro Carvalho Chehab 	state->drxk_i2c_exclusive_lock = false;
3279a0bf528SMauro Carvalho Chehab }
3289a0bf528SMauro Carvalho Chehab 
3299a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
3309a0bf528SMauro Carvalho Chehab 			     unsigned len)
3319a0bf528SMauro Carvalho Chehab {
3329a0bf528SMauro Carvalho Chehab 	if (state->drxk_i2c_exclusive_lock)
3339a0bf528SMauro Carvalho Chehab 		return __i2c_transfer(state->i2c, msgs, len);
3349a0bf528SMauro Carvalho Chehab 	else
3359a0bf528SMauro Carvalho Chehab 		return i2c_transfer(state->i2c, msgs, len);
3369a0bf528SMauro Carvalho Chehab }
3379a0bf528SMauro Carvalho Chehab 
3389a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
3399a0bf528SMauro Carvalho Chehab {
3409a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
3419a0bf528SMauro Carvalho Chehab 				    .buf = val, .len = 1}
3429a0bf528SMauro Carvalho Chehab 	};
3439a0bf528SMauro Carvalho Chehab 
3449a0bf528SMauro Carvalho Chehab 	return drxk_i2c_transfer(state, msgs, 1);
3459a0bf528SMauro Carvalho Chehab }
3469a0bf528SMauro Carvalho Chehab 
3479a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
3489a0bf528SMauro Carvalho Chehab {
3499a0bf528SMauro Carvalho Chehab 	int status;
3509a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg = {
3519a0bf528SMauro Carvalho Chehab 	    .addr = adr, .flags = 0, .buf = data, .len = len };
3529a0bf528SMauro Carvalho Chehab 
3539a0bf528SMauro Carvalho Chehab 	dprintk(3, ":");
3549a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
3559a0bf528SMauro Carvalho Chehab 		int i;
3569a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
3579a0bf528SMauro Carvalho Chehab 			printk(KERN_CONT " %02x", data[i]);
3589a0bf528SMauro Carvalho Chehab 		printk(KERN_CONT "\n");
3599a0bf528SMauro Carvalho Chehab 	}
3609a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, &msg, 1);
3619a0bf528SMauro Carvalho Chehab 	if (status >= 0 && status != 1)
3629a0bf528SMauro Carvalho Chehab 		status = -EIO;
3639a0bf528SMauro Carvalho Chehab 
3649a0bf528SMauro Carvalho Chehab 	if (status < 0)
3659a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
3669a0bf528SMauro Carvalho Chehab 
3679a0bf528SMauro Carvalho Chehab 	return status;
3689a0bf528SMauro Carvalho Chehab }
3699a0bf528SMauro Carvalho Chehab 
3709a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
3719a0bf528SMauro Carvalho Chehab 		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
3729a0bf528SMauro Carvalho Chehab {
3739a0bf528SMauro Carvalho Chehab 	int status;
3749a0bf528SMauro Carvalho Chehab 	struct i2c_msg msgs[2] = {
3759a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = 0,
3769a0bf528SMauro Carvalho Chehab 				    .buf = msg, .len = len},
3779a0bf528SMauro Carvalho Chehab 		{.addr = adr, .flags = I2C_M_RD,
3789a0bf528SMauro Carvalho Chehab 		 .buf = answ, .len = alen}
3799a0bf528SMauro Carvalho Chehab 	};
3809a0bf528SMauro Carvalho Chehab 
3819a0bf528SMauro Carvalho Chehab 	status = drxk_i2c_transfer(state, msgs, 2);
3829a0bf528SMauro Carvalho Chehab 	if (status != 2) {
3839a0bf528SMauro Carvalho Chehab 		if (debug > 2)
3849a0bf528SMauro Carvalho Chehab 			printk(KERN_CONT ": ERROR!\n");
3859a0bf528SMauro Carvalho Chehab 		if (status >= 0)
3869a0bf528SMauro Carvalho Chehab 			status = -EIO;
3879a0bf528SMauro Carvalho Chehab 
3889a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
3899a0bf528SMauro Carvalho Chehab 		return status;
3909a0bf528SMauro Carvalho Chehab 	}
3919a0bf528SMauro Carvalho Chehab 	if (debug > 2) {
3929a0bf528SMauro Carvalho Chehab 		int i;
3939a0bf528SMauro Carvalho Chehab 		dprintk(2, ": read from");
3949a0bf528SMauro Carvalho Chehab 		for (i = 0; i < len; i++)
3959a0bf528SMauro Carvalho Chehab 			printk(KERN_CONT " %02x", msg[i]);
3969a0bf528SMauro Carvalho Chehab 		printk(KERN_CONT ", value = ");
3979a0bf528SMauro Carvalho Chehab 		for (i = 0; i < alen; i++)
3989a0bf528SMauro Carvalho Chehab 			printk(KERN_CONT " %02x", answ[i]);
3999a0bf528SMauro Carvalho Chehab 		printk(KERN_CONT "\n");
4009a0bf528SMauro Carvalho Chehab 	}
4019a0bf528SMauro Carvalho Chehab 	return 0;
4029a0bf528SMauro Carvalho Chehab }
4039a0bf528SMauro Carvalho Chehab 
4049a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
4059a0bf528SMauro Carvalho Chehab {
4069a0bf528SMauro Carvalho Chehab 	int status;
4079a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[2], len;
4089a0bf528SMauro Carvalho Chehab 
4099a0bf528SMauro Carvalho Chehab 	if (state->single_master)
4109a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
4119a0bf528SMauro Carvalho Chehab 
4129a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
4139a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
4149a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
4159a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
4169a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
4179a0bf528SMauro Carvalho Chehab 		len = 4;
4189a0bf528SMauro Carvalho Chehab 	} else {
4199a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
4209a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
4219a0bf528SMauro Carvalho Chehab 		len = 2;
4229a0bf528SMauro Carvalho Chehab 	}
4239a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
4249a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 2);
4259a0bf528SMauro Carvalho Chehab 	if (status < 0)
4269a0bf528SMauro Carvalho Chehab 		return status;
4279a0bf528SMauro Carvalho Chehab 	if (data)
4289a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8);
4299a0bf528SMauro Carvalho Chehab 
4309a0bf528SMauro Carvalho Chehab 	return 0;
4319a0bf528SMauro Carvalho Chehab }
4329a0bf528SMauro Carvalho Chehab 
4339a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
4349a0bf528SMauro Carvalho Chehab {
4359a0bf528SMauro Carvalho Chehab 	return read16_flags(state, reg, data, 0);
4369a0bf528SMauro Carvalho Chehab }
4379a0bf528SMauro Carvalho Chehab 
4389a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
4399a0bf528SMauro Carvalho Chehab {
4409a0bf528SMauro Carvalho Chehab 	int status;
4419a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm1[4], mm2[4], len;
4429a0bf528SMauro Carvalho Chehab 
4439a0bf528SMauro Carvalho Chehab 	if (state->single_master)
4449a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
4459a0bf528SMauro Carvalho Chehab 
4469a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
4479a0bf528SMauro Carvalho Chehab 		mm1[0] = (((reg << 1) & 0xFF) | 0x01);
4489a0bf528SMauro Carvalho Chehab 		mm1[1] = ((reg >> 16) & 0xFF);
4499a0bf528SMauro Carvalho Chehab 		mm1[2] = ((reg >> 24) & 0xFF) | flags;
4509a0bf528SMauro Carvalho Chehab 		mm1[3] = ((reg >> 7) & 0xFF);
4519a0bf528SMauro Carvalho Chehab 		len = 4;
4529a0bf528SMauro Carvalho Chehab 	} else {
4539a0bf528SMauro Carvalho Chehab 		mm1[0] = ((reg << 1) & 0xFF);
4549a0bf528SMauro Carvalho Chehab 		mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
4559a0bf528SMauro Carvalho Chehab 		len = 2;
4569a0bf528SMauro Carvalho Chehab 	}
4579a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
4589a0bf528SMauro Carvalho Chehab 	status = i2c_read(state, adr, mm1, len, mm2, 4);
4599a0bf528SMauro Carvalho Chehab 	if (status < 0)
4609a0bf528SMauro Carvalho Chehab 		return status;
4619a0bf528SMauro Carvalho Chehab 	if (data)
4629a0bf528SMauro Carvalho Chehab 		*data = mm2[0] | (mm2[1] << 8) |
4639a0bf528SMauro Carvalho Chehab 		    (mm2[2] << 16) | (mm2[3] << 24);
4649a0bf528SMauro Carvalho Chehab 
4659a0bf528SMauro Carvalho Chehab 	return 0;
4669a0bf528SMauro Carvalho Chehab }
4679a0bf528SMauro Carvalho Chehab 
4689a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
4699a0bf528SMauro Carvalho Chehab {
4709a0bf528SMauro Carvalho Chehab 	return read32_flags(state, reg, data, 0);
4719a0bf528SMauro Carvalho Chehab }
4729a0bf528SMauro Carvalho Chehab 
4739a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
4749a0bf528SMauro Carvalho Chehab {
4759a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[6], len;
4769a0bf528SMauro Carvalho Chehab 
4779a0bf528SMauro Carvalho Chehab 	if (state->single_master)
4789a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
4799a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
4809a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
4819a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
4829a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
4839a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
4849a0bf528SMauro Carvalho Chehab 		len = 4;
4859a0bf528SMauro Carvalho Chehab 	} else {
4869a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
4879a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
4889a0bf528SMauro Carvalho Chehab 		len = 2;
4899a0bf528SMauro Carvalho Chehab 	}
4909a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
4919a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
4929a0bf528SMauro Carvalho Chehab 
4939a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
4949a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 2);
4959a0bf528SMauro Carvalho Chehab }
4969a0bf528SMauro Carvalho Chehab 
4979a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
4989a0bf528SMauro Carvalho Chehab {
4999a0bf528SMauro Carvalho Chehab 	return write16_flags(state, reg, data, 0);
5009a0bf528SMauro Carvalho Chehab }
5019a0bf528SMauro Carvalho Chehab 
5029a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
5039a0bf528SMauro Carvalho Chehab {
5049a0bf528SMauro Carvalho Chehab 	u8 adr = state->demod_address, mm[8], len;
5059a0bf528SMauro Carvalho Chehab 
5069a0bf528SMauro Carvalho Chehab 	if (state->single_master)
5079a0bf528SMauro Carvalho Chehab 		flags |= 0xC0;
5089a0bf528SMauro Carvalho Chehab 	if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
5099a0bf528SMauro Carvalho Chehab 		mm[0] = (((reg << 1) & 0xFF) | 0x01);
5109a0bf528SMauro Carvalho Chehab 		mm[1] = ((reg >> 16) & 0xFF);
5119a0bf528SMauro Carvalho Chehab 		mm[2] = ((reg >> 24) & 0xFF) | flags;
5129a0bf528SMauro Carvalho Chehab 		mm[3] = ((reg >> 7) & 0xFF);
5139a0bf528SMauro Carvalho Chehab 		len = 4;
5149a0bf528SMauro Carvalho Chehab 	} else {
5159a0bf528SMauro Carvalho Chehab 		mm[0] = ((reg << 1) & 0xFF);
5169a0bf528SMauro Carvalho Chehab 		mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
5179a0bf528SMauro Carvalho Chehab 		len = 2;
5189a0bf528SMauro Carvalho Chehab 	}
5199a0bf528SMauro Carvalho Chehab 	mm[len] = data & 0xff;
5209a0bf528SMauro Carvalho Chehab 	mm[len + 1] = (data >> 8) & 0xff;
5219a0bf528SMauro Carvalho Chehab 	mm[len + 2] = (data >> 16) & 0xff;
5229a0bf528SMauro Carvalho Chehab 	mm[len + 3] = (data >> 24) & 0xff;
5239a0bf528SMauro Carvalho Chehab 	dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
5249a0bf528SMauro Carvalho Chehab 
5259a0bf528SMauro Carvalho Chehab 	return i2c_write(state, adr, mm, len + 4);
5269a0bf528SMauro Carvalho Chehab }
5279a0bf528SMauro Carvalho Chehab 
5289a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
5299a0bf528SMauro Carvalho Chehab {
5309a0bf528SMauro Carvalho Chehab 	return write32_flags(state, reg, data, 0);
5319a0bf528SMauro Carvalho Chehab }
5329a0bf528SMauro Carvalho Chehab 
5339a0bf528SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 Address,
5349a0bf528SMauro Carvalho Chehab 		      const int BlockSize, const u8 pBlock[])
5359a0bf528SMauro Carvalho Chehab {
5369a0bf528SMauro Carvalho Chehab 	int status = 0, BlkSize = BlockSize;
5379a0bf528SMauro Carvalho Chehab 	u8 Flags = 0;
5389a0bf528SMauro Carvalho Chehab 
5399a0bf528SMauro Carvalho Chehab 	if (state->single_master)
5409a0bf528SMauro Carvalho Chehab 		Flags |= 0xC0;
5419a0bf528SMauro Carvalho Chehab 
5429a0bf528SMauro Carvalho Chehab 	while (BlkSize > 0) {
5439a0bf528SMauro Carvalho Chehab 		int Chunk = BlkSize > state->m_ChunkSize ?
5449a0bf528SMauro Carvalho Chehab 		    state->m_ChunkSize : BlkSize;
5459a0bf528SMauro Carvalho Chehab 		u8 *AdrBuf = &state->Chunk[0];
5469a0bf528SMauro Carvalho Chehab 		u32 AdrLength = 0;
5479a0bf528SMauro Carvalho Chehab 
5489a0bf528SMauro Carvalho Chehab 		if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
5499a0bf528SMauro Carvalho Chehab 			AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
5509a0bf528SMauro Carvalho Chehab 			AdrBuf[1] = ((Address >> 16) & 0xFF);
5519a0bf528SMauro Carvalho Chehab 			AdrBuf[2] = ((Address >> 24) & 0xFF);
5529a0bf528SMauro Carvalho Chehab 			AdrBuf[3] = ((Address >> 7) & 0xFF);
5539a0bf528SMauro Carvalho Chehab 			AdrBuf[2] |= Flags;
5549a0bf528SMauro Carvalho Chehab 			AdrLength = 4;
5559a0bf528SMauro Carvalho Chehab 			if (Chunk == state->m_ChunkSize)
5569a0bf528SMauro Carvalho Chehab 				Chunk -= 2;
5579a0bf528SMauro Carvalho Chehab 		} else {
5589a0bf528SMauro Carvalho Chehab 			AdrBuf[0] = ((Address << 1) & 0xFF);
5599a0bf528SMauro Carvalho Chehab 			AdrBuf[1] = (((Address >> 16) & 0x0F) |
5609a0bf528SMauro Carvalho Chehab 				     ((Address >> 18) & 0xF0));
5619a0bf528SMauro Carvalho Chehab 			AdrLength = 2;
5629a0bf528SMauro Carvalho Chehab 		}
5639a0bf528SMauro Carvalho Chehab 		memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
5649a0bf528SMauro Carvalho Chehab 		dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
5659a0bf528SMauro Carvalho Chehab 		if (debug > 1) {
5669a0bf528SMauro Carvalho Chehab 			int i;
5679a0bf528SMauro Carvalho Chehab 			if (pBlock)
5689a0bf528SMauro Carvalho Chehab 				for (i = 0; i < Chunk; i++)
5699a0bf528SMauro Carvalho Chehab 					printk(KERN_CONT " %02x", pBlock[i]);
5709a0bf528SMauro Carvalho Chehab 			printk(KERN_CONT "\n");
5719a0bf528SMauro Carvalho Chehab 		}
5729a0bf528SMauro Carvalho Chehab 		status = i2c_write(state, state->demod_address,
5739a0bf528SMauro Carvalho Chehab 				   &state->Chunk[0], Chunk + AdrLength);
5749a0bf528SMauro Carvalho Chehab 		if (status < 0) {
5759a0bf528SMauro Carvalho Chehab 			printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
5769a0bf528SMauro Carvalho Chehab 			       __func__, Address);
5779a0bf528SMauro Carvalho Chehab 			break;
5789a0bf528SMauro Carvalho Chehab 		}
5799a0bf528SMauro Carvalho Chehab 		pBlock += Chunk;
5809a0bf528SMauro Carvalho Chehab 		Address += (Chunk >> 1);
5819a0bf528SMauro Carvalho Chehab 		BlkSize -= Chunk;
5829a0bf528SMauro Carvalho Chehab 	}
5839a0bf528SMauro Carvalho Chehab 	return status;
5849a0bf528SMauro Carvalho Chehab }
5859a0bf528SMauro Carvalho Chehab 
5869a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
5879a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
5889a0bf528SMauro Carvalho Chehab #endif
5899a0bf528SMauro Carvalho Chehab 
5909a0bf528SMauro Carvalho Chehab int PowerUpDevice(struct drxk_state *state)
5919a0bf528SMauro Carvalho Chehab {
5929a0bf528SMauro Carvalho Chehab 	int status;
5939a0bf528SMauro Carvalho Chehab 	u8 data = 0;
5949a0bf528SMauro Carvalho Chehab 	u16 retryCount = 0;
5959a0bf528SMauro Carvalho Chehab 
5969a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
5979a0bf528SMauro Carvalho Chehab 
5989a0bf528SMauro Carvalho Chehab 	status = i2c_read1(state, state->demod_address, &data);
5999a0bf528SMauro Carvalho Chehab 	if (status < 0) {
6009a0bf528SMauro Carvalho Chehab 		do {
6019a0bf528SMauro Carvalho Chehab 			data = 0;
6029a0bf528SMauro Carvalho Chehab 			status = i2c_write(state, state->demod_address,
6039a0bf528SMauro Carvalho Chehab 					   &data, 1);
6049a0bf528SMauro Carvalho Chehab 			msleep(10);
6059a0bf528SMauro Carvalho Chehab 			retryCount++;
6069a0bf528SMauro Carvalho Chehab 			if (status < 0)
6079a0bf528SMauro Carvalho Chehab 				continue;
6089a0bf528SMauro Carvalho Chehab 			status = i2c_read1(state, state->demod_address,
6099a0bf528SMauro Carvalho Chehab 					   &data);
6109a0bf528SMauro Carvalho Chehab 		} while (status < 0 &&
6119a0bf528SMauro Carvalho Chehab 			 (retryCount < DRXK_MAX_RETRIES_POWERUP));
6129a0bf528SMauro Carvalho Chehab 		if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
6139a0bf528SMauro Carvalho Chehab 			goto error;
6149a0bf528SMauro Carvalho Chehab 	}
6159a0bf528SMauro Carvalho Chehab 
6169a0bf528SMauro Carvalho Chehab 	/* Make sure all clk domains are active */
6179a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
6189a0bf528SMauro Carvalho Chehab 	if (status < 0)
6199a0bf528SMauro Carvalho Chehab 		goto error;
6209a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6219a0bf528SMauro Carvalho Chehab 	if (status < 0)
6229a0bf528SMauro Carvalho Chehab 		goto error;
6239a0bf528SMauro Carvalho Chehab 	/* Enable pll lock tests */
6249a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PLL_LOCK__A, 1);
6259a0bf528SMauro Carvalho Chehab 	if (status < 0)
6269a0bf528SMauro Carvalho Chehab 		goto error;
6279a0bf528SMauro Carvalho Chehab 
6289a0bf528SMauro Carvalho Chehab 	state->m_currentPowerMode = DRX_POWER_UP;
6299a0bf528SMauro Carvalho Chehab 
6309a0bf528SMauro Carvalho Chehab error:
6319a0bf528SMauro Carvalho Chehab 	if (status < 0)
6329a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6339a0bf528SMauro Carvalho Chehab 
6349a0bf528SMauro Carvalho Chehab 	return status;
6359a0bf528SMauro Carvalho Chehab }
6369a0bf528SMauro Carvalho Chehab 
6379a0bf528SMauro Carvalho Chehab 
6389a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
6399a0bf528SMauro Carvalho Chehab {
6409a0bf528SMauro Carvalho Chehab 	/*
6419a0bf528SMauro Carvalho Chehab 	 * FIXME: most (all?) of the values bellow should be moved into
6429a0bf528SMauro Carvalho Chehab 	 * struct drxk_config, as they are probably board-specific
6439a0bf528SMauro Carvalho Chehab 	 */
6449a0bf528SMauro Carvalho Chehab 	u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
6459a0bf528SMauro Carvalho Chehab 	u32 ulVSBIfAgcOutputLevel = 0;
6469a0bf528SMauro Carvalho Chehab 	u32 ulVSBIfAgcMinLevel = 0;
6479a0bf528SMauro Carvalho Chehab 	u32 ulVSBIfAgcMaxLevel = 0x7FFF;
6489a0bf528SMauro Carvalho Chehab 	u32 ulVSBIfAgcSpeed = 3;
6499a0bf528SMauro Carvalho Chehab 
6509a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
6519a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcOutputLevel = 0;
6529a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcMinLevel = 0;
6539a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcMaxLevel = 0x7FFF;
6549a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcSpeed = 3;
6559a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcTop = 9500;
6569a0bf528SMauro Carvalho Chehab 	u32 ulVSBRfAgcCutOffCurrent = 4000;
6579a0bf528SMauro Carvalho Chehab 
6589a0bf528SMauro Carvalho Chehab 	u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
6599a0bf528SMauro Carvalho Chehab 	u32 ulATVIfAgcOutputLevel = 0;
6609a0bf528SMauro Carvalho Chehab 	u32 ulATVIfAgcMinLevel = 0;
6619a0bf528SMauro Carvalho Chehab 	u32 ulATVIfAgcMaxLevel = 0;
6629a0bf528SMauro Carvalho Chehab 	u32 ulATVIfAgcSpeed = 3;
6639a0bf528SMauro Carvalho Chehab 
6649a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
6659a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcOutputLevel = 0;
6669a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcMinLevel = 0;
6679a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcMaxLevel = 0;
6689a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcTop = 9500;
6699a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcCutOffCurrent = 4000;
6709a0bf528SMauro Carvalho Chehab 	u32 ulATVRfAgcSpeed = 3;
6719a0bf528SMauro Carvalho Chehab 
6729a0bf528SMauro Carvalho Chehab 	u32 ulQual83 = DEFAULT_MER_83;
6739a0bf528SMauro Carvalho Chehab 	u32 ulQual93 = DEFAULT_MER_93;
6749a0bf528SMauro Carvalho Chehab 
6759a0bf528SMauro Carvalho Chehab 	u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
6769a0bf528SMauro Carvalho Chehab 	u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
6779a0bf528SMauro Carvalho Chehab 
6789a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
6799a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_mode output mode is drive always */
6809a0bf528SMauro Carvalho Chehab 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
6819a0bf528SMauro Carvalho Chehab 	u32 ulGPIOCfg = 0x0113;
6829a0bf528SMauro Carvalho Chehab 	u32 ulInvertTSClock = 0;
6839a0bf528SMauro Carvalho Chehab 	u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
6849a0bf528SMauro Carvalho Chehab 	u32 ulDVBTBitrate = 50000000;
6859a0bf528SMauro Carvalho Chehab 	u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
6869a0bf528SMauro Carvalho Chehab 
6879a0bf528SMauro Carvalho Chehab 	u32 ulInsertRSByte = 0;
6889a0bf528SMauro Carvalho Chehab 
6899a0bf528SMauro Carvalho Chehab 	u32 ulRfMirror = 1;
6909a0bf528SMauro Carvalho Chehab 	u32 ulPowerDown = 0;
6919a0bf528SMauro Carvalho Chehab 
6929a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
6939a0bf528SMauro Carvalho Chehab 
6949a0bf528SMauro Carvalho Chehab 	state->m_hasLNA = false;
6959a0bf528SMauro Carvalho Chehab 	state->m_hasDVBT = false;
6969a0bf528SMauro Carvalho Chehab 	state->m_hasDVBC = false;
6979a0bf528SMauro Carvalho Chehab 	state->m_hasATV = false;
6989a0bf528SMauro Carvalho Chehab 	state->m_hasOOB = false;
6999a0bf528SMauro Carvalho Chehab 	state->m_hasAudio = false;
7009a0bf528SMauro Carvalho Chehab 
7019a0bf528SMauro Carvalho Chehab 	if (!state->m_ChunkSize)
7029a0bf528SMauro Carvalho Chehab 		state->m_ChunkSize = 124;
7039a0bf528SMauro Carvalho Chehab 
7049a0bf528SMauro Carvalho Chehab 	state->m_oscClockFreq = 0;
7059a0bf528SMauro Carvalho Chehab 	state->m_smartAntInverted = false;
7069a0bf528SMauro Carvalho Chehab 	state->m_bPDownOpenBridge = false;
7079a0bf528SMauro Carvalho Chehab 
7089a0bf528SMauro Carvalho Chehab 	/* real system clock frequency in kHz */
7099a0bf528SMauro Carvalho Chehab 	state->m_sysClockFreq = 151875;
7109a0bf528SMauro Carvalho Chehab 	/* Timing div, 250ns/Psys */
7119a0bf528SMauro Carvalho Chehab 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
7129a0bf528SMauro Carvalho Chehab 	state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
7139a0bf528SMauro Carvalho Chehab 				   HI_I2C_DELAY) / 1000;
7149a0bf528SMauro Carvalho Chehab 	/* Clipping */
7159a0bf528SMauro Carvalho Chehab 	if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
7169a0bf528SMauro Carvalho Chehab 		state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
7179a0bf528SMauro Carvalho Chehab 	state->m_HICfgWakeUpKey = (state->demod_address << 1);
7189a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
7199a0bf528SMauro Carvalho Chehab 	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
7209a0bf528SMauro Carvalho Chehab 
7219a0bf528SMauro Carvalho Chehab 	state->m_bPowerDown = (ulPowerDown != 0);
7229a0bf528SMauro Carvalho Chehab 
7239a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A1_PATCH_CODE = false;
7249a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A1_ROM_CODE = false;
7259a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A2_ROM_CODE = false;
7269a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A3_ROM_CODE = false;
7279a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A2_PATCH_CODE = false;
7289a0bf528SMauro Carvalho Chehab 	state->m_DRXK_A3_PATCH_CODE = false;
7299a0bf528SMauro Carvalho Chehab 
7309a0bf528SMauro Carvalho Chehab 	/* Init AGC and PGA parameters */
7319a0bf528SMauro Carvalho Chehab 	/* VSB IF */
7329a0bf528SMauro Carvalho Chehab 	state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
7339a0bf528SMauro Carvalho Chehab 	state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
7349a0bf528SMauro Carvalho Chehab 	state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
7359a0bf528SMauro Carvalho Chehab 	state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
7369a0bf528SMauro Carvalho Chehab 	state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
7379a0bf528SMauro Carvalho Chehab 	state->m_vsbPgaCfg = 140;
7389a0bf528SMauro Carvalho Chehab 
7399a0bf528SMauro Carvalho Chehab 	/* VSB RF */
7409a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
7419a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
7429a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
7439a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
7449a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
7459a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
7469a0bf528SMauro Carvalho Chehab 	state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
7479a0bf528SMauro Carvalho Chehab 	state->m_vsbPreSawCfg.reference = 0x07;
7489a0bf528SMauro Carvalho Chehab 	state->m_vsbPreSawCfg.usePreSaw = true;
7499a0bf528SMauro Carvalho Chehab 
7509a0bf528SMauro Carvalho Chehab 	state->m_Quality83percent = DEFAULT_MER_83;
7519a0bf528SMauro Carvalho Chehab 	state->m_Quality93percent = DEFAULT_MER_93;
7529a0bf528SMauro Carvalho Chehab 	if (ulQual93 <= 500 && ulQual83 < ulQual93) {
7539a0bf528SMauro Carvalho Chehab 		state->m_Quality83percent = ulQual83;
7549a0bf528SMauro Carvalho Chehab 		state->m_Quality93percent = ulQual93;
7559a0bf528SMauro Carvalho Chehab 	}
7569a0bf528SMauro Carvalho Chehab 
7579a0bf528SMauro Carvalho Chehab 	/* ATV IF */
7589a0bf528SMauro Carvalho Chehab 	state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
7599a0bf528SMauro Carvalho Chehab 	state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
7609a0bf528SMauro Carvalho Chehab 	state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
7619a0bf528SMauro Carvalho Chehab 	state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
7629a0bf528SMauro Carvalho Chehab 	state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
7639a0bf528SMauro Carvalho Chehab 
7649a0bf528SMauro Carvalho Chehab 	/* ATV RF */
7659a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
7669a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
7679a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
7689a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
7699a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
7709a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
7719a0bf528SMauro Carvalho Chehab 	state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
7729a0bf528SMauro Carvalho Chehab 	state->m_atvPreSawCfg.reference = 0x04;
7739a0bf528SMauro Carvalho Chehab 	state->m_atvPreSawCfg.usePreSaw = true;
7749a0bf528SMauro Carvalho Chehab 
7759a0bf528SMauro Carvalho Chehab 
7769a0bf528SMauro Carvalho Chehab 	/* DVBT RF */
7779a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
7789a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.outputLevel = 0;
7799a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.minOutputLevel = 0;
7809a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
7819a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.top = 0x2100;
7829a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
7839a0bf528SMauro Carvalho Chehab 	state->m_dvbtRfAgcCfg.speed = 1;
7849a0bf528SMauro Carvalho Chehab 
7859a0bf528SMauro Carvalho Chehab 
7869a0bf528SMauro Carvalho Chehab 	/* DVBT IF */
7879a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
7889a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.outputLevel = 0;
7899a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.minOutputLevel = 0;
7909a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
7919a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.top = 13424;
7929a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
7939a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.speed = 3;
7949a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
7959a0bf528SMauro Carvalho Chehab 	state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
7969a0bf528SMauro Carvalho Chehab 	/* state->m_dvbtPgaCfg = 140; */
7979a0bf528SMauro Carvalho Chehab 
7989a0bf528SMauro Carvalho Chehab 	state->m_dvbtPreSawCfg.reference = 4;
7999a0bf528SMauro Carvalho Chehab 	state->m_dvbtPreSawCfg.usePreSaw = false;
8009a0bf528SMauro Carvalho Chehab 
8019a0bf528SMauro Carvalho Chehab 	/* QAM RF */
8029a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
8039a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.outputLevel = 0;
8049a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.minOutputLevel = 6023;
8059a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.maxOutputLevel = 27000;
8069a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.top = 0x2380;
8079a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.cutOffCurrent = 4000;
8089a0bf528SMauro Carvalho Chehab 	state->m_qamRfAgcCfg.speed = 3;
8099a0bf528SMauro Carvalho Chehab 
8109a0bf528SMauro Carvalho Chehab 	/* QAM IF */
8119a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
8129a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.outputLevel = 0;
8139a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.minOutputLevel = 0;
8149a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.maxOutputLevel = 9000;
8159a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.top = 0x0511;
8169a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.cutOffCurrent = 0;
8179a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.speed = 3;
8189a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.IngainTgtMax = 5119;
8199a0bf528SMauro Carvalho Chehab 	state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
8209a0bf528SMauro Carvalho Chehab 
8219a0bf528SMauro Carvalho Chehab 	state->m_qamPgaCfg = 140;
8229a0bf528SMauro Carvalho Chehab 	state->m_qamPreSawCfg.reference = 4;
8239a0bf528SMauro Carvalho Chehab 	state->m_qamPreSawCfg.usePreSaw = false;
8249a0bf528SMauro Carvalho Chehab 
8259a0bf528SMauro Carvalho Chehab 	state->m_OperationMode = OM_NONE;
8269a0bf528SMauro Carvalho Chehab 	state->m_DrxkState = DRXK_UNINITIALIZED;
8279a0bf528SMauro Carvalho Chehab 
8289a0bf528SMauro Carvalho Chehab 	/* MPEG output configuration */
8299a0bf528SMauro Carvalho Chehab 	state->m_enableMPEGOutput = true;	/* If TRUE; enable MPEG ouput */
8309a0bf528SMauro Carvalho Chehab 	state->m_insertRSByte = false;	/* If TRUE; insert RS byte */
8319a0bf528SMauro Carvalho Chehab 	state->m_invertDATA = false;	/* If TRUE; invert DATA signals */
8329a0bf528SMauro Carvalho Chehab 	state->m_invertERR = false;	/* If TRUE; invert ERR signal */
8339a0bf528SMauro Carvalho Chehab 	state->m_invertSTR = false;	/* If TRUE; invert STR signals */
8349a0bf528SMauro Carvalho Chehab 	state->m_invertVAL = false;	/* If TRUE; invert VAL signals */
8359a0bf528SMauro Carvalho Chehab 	state->m_invertCLK = (ulInvertTSClock != 0);	/* If TRUE; invert CLK signals */
8369a0bf528SMauro Carvalho Chehab 
8379a0bf528SMauro Carvalho Chehab 	/* If TRUE; static MPEG clockrate will be used;
8389a0bf528SMauro Carvalho Chehab 	   otherwise clockrate will adapt to the bitrate of the TS */
8399a0bf528SMauro Carvalho Chehab 
8409a0bf528SMauro Carvalho Chehab 	state->m_DVBTBitrate = ulDVBTBitrate;
8419a0bf528SMauro Carvalho Chehab 	state->m_DVBCBitrate = ulDVBCBitrate;
8429a0bf528SMauro Carvalho Chehab 
8439a0bf528SMauro Carvalho Chehab 	state->m_TSDataStrength = (ulTSDataStrength & 0x07);
8449a0bf528SMauro Carvalho Chehab 
8459a0bf528SMauro Carvalho Chehab 	/* Maximum bitrate in b/s in case static clockrate is selected */
8469a0bf528SMauro Carvalho Chehab 	state->m_mpegTsStaticBitrate = 19392658;
8479a0bf528SMauro Carvalho Chehab 	state->m_disableTEIhandling = false;
8489a0bf528SMauro Carvalho Chehab 
8499a0bf528SMauro Carvalho Chehab 	if (ulInsertRSByte)
8509a0bf528SMauro Carvalho Chehab 		state->m_insertRSByte = true;
8519a0bf528SMauro Carvalho Chehab 
8529a0bf528SMauro Carvalho Chehab 	state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
8539a0bf528SMauro Carvalho Chehab 	if (ulMpegLockTimeOut < 10000)
8549a0bf528SMauro Carvalho Chehab 		state->m_MpegLockTimeOut = ulMpegLockTimeOut;
8559a0bf528SMauro Carvalho Chehab 	state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
8569a0bf528SMauro Carvalho Chehab 	if (ulDemodLockTimeOut < 10000)
8579a0bf528SMauro Carvalho Chehab 		state->m_DemodLockTimeOut = ulDemodLockTimeOut;
8589a0bf528SMauro Carvalho Chehab 
8599a0bf528SMauro Carvalho Chehab 	/* QAM defaults */
8609a0bf528SMauro Carvalho Chehab 	state->m_Constellation = DRX_CONSTELLATION_AUTO;
8619a0bf528SMauro Carvalho Chehab 	state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
8629a0bf528SMauro Carvalho Chehab 	state->m_fecRsPlen = 204 * 8;	/* fecRsPlen  annex A */
8639a0bf528SMauro Carvalho Chehab 	state->m_fecRsPrescale = 1;
8649a0bf528SMauro Carvalho Chehab 
8659a0bf528SMauro Carvalho Chehab 	state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
8669a0bf528SMauro Carvalho Chehab 	state->m_agcFastClipCtrlDelay = 0;
8679a0bf528SMauro Carvalho Chehab 
8689a0bf528SMauro Carvalho Chehab 	state->m_GPIOCfg = (ulGPIOCfg);
8699a0bf528SMauro Carvalho Chehab 
8709a0bf528SMauro Carvalho Chehab 	state->m_bPowerDown = false;
8719a0bf528SMauro Carvalho Chehab 	state->m_currentPowerMode = DRX_POWER_DOWN;
8729a0bf528SMauro Carvalho Chehab 
8739a0bf528SMauro Carvalho Chehab 	state->m_rfmirror = (ulRfMirror == 0);
8749a0bf528SMauro Carvalho Chehab 	state->m_IfAgcPol = false;
8759a0bf528SMauro Carvalho Chehab 	return 0;
8769a0bf528SMauro Carvalho Chehab }
8779a0bf528SMauro Carvalho Chehab 
8789a0bf528SMauro Carvalho Chehab static int DRXX_Open(struct drxk_state *state)
8799a0bf528SMauro Carvalho Chehab {
8809a0bf528SMauro Carvalho Chehab 	int status = 0;
8819a0bf528SMauro Carvalho Chehab 	u32 jtag = 0;
8829a0bf528SMauro Carvalho Chehab 	u16 bid = 0;
8839a0bf528SMauro Carvalho Chehab 	u16 key = 0;
8849a0bf528SMauro Carvalho Chehab 
8859a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
8869a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
8879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
8889a0bf528SMauro Carvalho Chehab 	if (status < 0)
8899a0bf528SMauro Carvalho Chehab 		goto error;
8909a0bf528SMauro Carvalho Chehab 	/* Check device id */
8919a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_TOP_COMM_KEY__A, &key);
8929a0bf528SMauro Carvalho Chehab 	if (status < 0)
8939a0bf528SMauro Carvalho Chehab 		goto error;
8949a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
8959a0bf528SMauro Carvalho Chehab 	if (status < 0)
8969a0bf528SMauro Carvalho Chehab 		goto error;
8979a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
8989a0bf528SMauro Carvalho Chehab 	if (status < 0)
8999a0bf528SMauro Carvalho Chehab 		goto error;
9009a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
9019a0bf528SMauro Carvalho Chehab 	if (status < 0)
9029a0bf528SMauro Carvalho Chehab 		goto error;
9039a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
9049a0bf528SMauro Carvalho Chehab error:
9059a0bf528SMauro Carvalho Chehab 	if (status < 0)
9069a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
9079a0bf528SMauro Carvalho Chehab 	return status;
9089a0bf528SMauro Carvalho Chehab }
9099a0bf528SMauro Carvalho Chehab 
9109a0bf528SMauro Carvalho Chehab static int GetDeviceCapabilities(struct drxk_state *state)
9119a0bf528SMauro Carvalho Chehab {
9129a0bf528SMauro Carvalho Chehab 	u16 sioPdrOhwCfg = 0;
9139a0bf528SMauro Carvalho Chehab 	u32 sioTopJtagidLo = 0;
9149a0bf528SMauro Carvalho Chehab 	int status;
9159a0bf528SMauro Carvalho Chehab 	const char *spin = "";
9169a0bf528SMauro Carvalho Chehab 
9179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
9189a0bf528SMauro Carvalho Chehab 
9199a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
9209a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
9219a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
9229a0bf528SMauro Carvalho Chehab 	if (status < 0)
9239a0bf528SMauro Carvalho Chehab 		goto error;
9249a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
9259a0bf528SMauro Carvalho Chehab 	if (status < 0)
9269a0bf528SMauro Carvalho Chehab 		goto error;
9279a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
9289a0bf528SMauro Carvalho Chehab 	if (status < 0)
9299a0bf528SMauro Carvalho Chehab 		goto error;
9309a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
9319a0bf528SMauro Carvalho Chehab 	if (status < 0)
9329a0bf528SMauro Carvalho Chehab 		goto error;
9339a0bf528SMauro Carvalho Chehab 
9349a0bf528SMauro Carvalho Chehab 	switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
9359a0bf528SMauro Carvalho Chehab 	case 0:
9369a0bf528SMauro Carvalho Chehab 		/* ignore (bypass ?) */
9379a0bf528SMauro Carvalho Chehab 		break;
9389a0bf528SMauro Carvalho Chehab 	case 1:
9399a0bf528SMauro Carvalho Chehab 		/* 27 MHz */
9409a0bf528SMauro Carvalho Chehab 		state->m_oscClockFreq = 27000;
9419a0bf528SMauro Carvalho Chehab 		break;
9429a0bf528SMauro Carvalho Chehab 	case 2:
9439a0bf528SMauro Carvalho Chehab 		/* 20.25 MHz */
9449a0bf528SMauro Carvalho Chehab 		state->m_oscClockFreq = 20250;
9459a0bf528SMauro Carvalho Chehab 		break;
9469a0bf528SMauro Carvalho Chehab 	case 3:
9479a0bf528SMauro Carvalho Chehab 		/* 4 MHz */
9489a0bf528SMauro Carvalho Chehab 		state->m_oscClockFreq = 20250;
9499a0bf528SMauro Carvalho Chehab 		break;
9509a0bf528SMauro Carvalho Chehab 	default:
9519a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
9529a0bf528SMauro Carvalho Chehab 		return -EINVAL;
9539a0bf528SMauro Carvalho Chehab 	}
9549a0bf528SMauro Carvalho Chehab 	/*
9559a0bf528SMauro Carvalho Chehab 		Determine device capabilities
9569a0bf528SMauro Carvalho Chehab 		Based on pinning v14
9579a0bf528SMauro Carvalho Chehab 		*/
9589a0bf528SMauro Carvalho Chehab 	status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
9599a0bf528SMauro Carvalho Chehab 	if (status < 0)
9609a0bf528SMauro Carvalho Chehab 		goto error;
9619a0bf528SMauro Carvalho Chehab 
9629a0bf528SMauro Carvalho Chehab 	printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
9639a0bf528SMauro Carvalho Chehab 
9649a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
9659a0bf528SMauro Carvalho Chehab 	switch ((sioTopJtagidLo >> 29) & 0xF) {
9669a0bf528SMauro Carvalho Chehab 	case 0:
9679a0bf528SMauro Carvalho Chehab 		state->m_deviceSpin = DRXK_SPIN_A1;
9689a0bf528SMauro Carvalho Chehab 		spin = "A1";
9699a0bf528SMauro Carvalho Chehab 		break;
9709a0bf528SMauro Carvalho Chehab 	case 2:
9719a0bf528SMauro Carvalho Chehab 		state->m_deviceSpin = DRXK_SPIN_A2;
9729a0bf528SMauro Carvalho Chehab 		spin = "A2";
9739a0bf528SMauro Carvalho Chehab 		break;
9749a0bf528SMauro Carvalho Chehab 	case 3:
9759a0bf528SMauro Carvalho Chehab 		state->m_deviceSpin = DRXK_SPIN_A3;
9769a0bf528SMauro Carvalho Chehab 		spin = "A3";
9779a0bf528SMauro Carvalho Chehab 		break;
9789a0bf528SMauro Carvalho Chehab 	default:
9799a0bf528SMauro Carvalho Chehab 		state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
9809a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
9819a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Spin %d unknown\n",
9829a0bf528SMauro Carvalho Chehab 		       (sioTopJtagidLo >> 29) & 0xF);
9839a0bf528SMauro Carvalho Chehab 		goto error2;
9849a0bf528SMauro Carvalho Chehab 	}
9859a0bf528SMauro Carvalho Chehab 	switch ((sioTopJtagidLo >> 12) & 0xFF) {
9869a0bf528SMauro Carvalho Chehab 	case 0x13:
9879a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3913K_TYPE_ID */
9889a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
9899a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
9909a0bf528SMauro Carvalho Chehab 		state->m_hasATV = false;
9919a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = false;
9929a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
9939a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = true;
9949a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
9959a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = false;
9969a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = false;
9979a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
9989a0bf528SMauro Carvalho Chehab 		break;
9999a0bf528SMauro Carvalho Chehab 	case 0x15:
10009a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3915K_TYPE_ID */
10019a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10029a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10039a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10049a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = false;
10059a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10069a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = false;
10079a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10089a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10099a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10109a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10119a0bf528SMauro Carvalho Chehab 		break;
10129a0bf528SMauro Carvalho Chehab 	case 0x16:
10139a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3916K_TYPE_ID */
10149a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10159a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10169a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10179a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = false;
10189a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10199a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = false;
10209a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10219a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10229a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10239a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10249a0bf528SMauro Carvalho Chehab 		break;
10259a0bf528SMauro Carvalho Chehab 	case 0x18:
10269a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3918K_TYPE_ID */
10279a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10289a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10299a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10309a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = true;
10319a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10329a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = false;
10339a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10349a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10359a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10369a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10379a0bf528SMauro Carvalho Chehab 		break;
10389a0bf528SMauro Carvalho Chehab 	case 0x21:
10399a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3921K_TYPE_ID */
10409a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10419a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10429a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10439a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = true;
10449a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10459a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = true;
10469a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10479a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10489a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10499a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10509a0bf528SMauro Carvalho Chehab 		break;
10519a0bf528SMauro Carvalho Chehab 	case 0x23:
10529a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3923K_TYPE_ID */
10539a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10549a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10559a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10569a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = true;
10579a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10589a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = true;
10599a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10609a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10619a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10629a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10639a0bf528SMauro Carvalho Chehab 		break;
10649a0bf528SMauro Carvalho Chehab 	case 0x25:
10659a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3925K_TYPE_ID */
10669a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10679a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10689a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10699a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = true;
10709a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10719a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = true;
10729a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10739a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10749a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10759a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10769a0bf528SMauro Carvalho Chehab 		break;
10779a0bf528SMauro Carvalho Chehab 	case 0x26:
10789a0bf528SMauro Carvalho Chehab 		/* typeId = DRX3926K_TYPE_ID */
10799a0bf528SMauro Carvalho Chehab 		state->m_hasLNA = false;
10809a0bf528SMauro Carvalho Chehab 		state->m_hasOOB = false;
10819a0bf528SMauro Carvalho Chehab 		state->m_hasATV = true;
10829a0bf528SMauro Carvalho Chehab 		state->m_hasAudio = false;
10839a0bf528SMauro Carvalho Chehab 		state->m_hasDVBT = true;
10849a0bf528SMauro Carvalho Chehab 		state->m_hasDVBC = true;
10859a0bf528SMauro Carvalho Chehab 		state->m_hasSAWSW = true;
10869a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO2 = true;
10879a0bf528SMauro Carvalho Chehab 		state->m_hasGPIO1 = true;
10889a0bf528SMauro Carvalho Chehab 		state->m_hasIRQN = false;
10899a0bf528SMauro Carvalho Chehab 		break;
10909a0bf528SMauro Carvalho Chehab 	default:
10919a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
10929a0bf528SMauro Carvalho Chehab 			((sioTopJtagidLo >> 12) & 0xFF));
10939a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
10949a0bf528SMauro Carvalho Chehab 		goto error2;
10959a0bf528SMauro Carvalho Chehab 	}
10969a0bf528SMauro Carvalho Chehab 
10979a0bf528SMauro Carvalho Chehab 	printk(KERN_INFO
10989a0bf528SMauro Carvalho Chehab 	       "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
10999a0bf528SMauro Carvalho Chehab 	       ((sioTopJtagidLo >> 12) & 0xFF), spin,
11009a0bf528SMauro Carvalho Chehab 	       state->m_oscClockFreq / 1000,
11019a0bf528SMauro Carvalho Chehab 	       state->m_oscClockFreq % 1000);
11029a0bf528SMauro Carvalho Chehab 
11039a0bf528SMauro Carvalho Chehab error:
11049a0bf528SMauro Carvalho Chehab 	if (status < 0)
11059a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
11069a0bf528SMauro Carvalho Chehab 
11079a0bf528SMauro Carvalho Chehab error2:
11089a0bf528SMauro Carvalho Chehab 	return status;
11099a0bf528SMauro Carvalho Chehab }
11109a0bf528SMauro Carvalho Chehab 
11119a0bf528SMauro Carvalho Chehab static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
11129a0bf528SMauro Carvalho Chehab {
11139a0bf528SMauro Carvalho Chehab 	int status;
11149a0bf528SMauro Carvalho Chehab 	bool powerdown_cmd;
11159a0bf528SMauro Carvalho Chehab 
11169a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
11179a0bf528SMauro Carvalho Chehab 
11189a0bf528SMauro Carvalho Chehab 	/* Write command */
11199a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
11209a0bf528SMauro Carvalho Chehab 	if (status < 0)
11219a0bf528SMauro Carvalho Chehab 		goto error;
11229a0bf528SMauro Carvalho Chehab 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
11239a0bf528SMauro Carvalho Chehab 		msleep(1);
11249a0bf528SMauro Carvalho Chehab 
11259a0bf528SMauro Carvalho Chehab 	powerdown_cmd =
11269a0bf528SMauro Carvalho Chehab 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
11279a0bf528SMauro Carvalho Chehab 		    ((state->m_HICfgCtrl) &
11289a0bf528SMauro Carvalho Chehab 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
11299a0bf528SMauro Carvalho Chehab 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
11309a0bf528SMauro Carvalho Chehab 	if (powerdown_cmd == false) {
11319a0bf528SMauro Carvalho Chehab 		/* Wait until command rdy */
11329a0bf528SMauro Carvalho Chehab 		u32 retryCount = 0;
11339a0bf528SMauro Carvalho Chehab 		u16 waitCmd;
11349a0bf528SMauro Carvalho Chehab 
11359a0bf528SMauro Carvalho Chehab 		do {
11369a0bf528SMauro Carvalho Chehab 			msleep(1);
11379a0bf528SMauro Carvalho Chehab 			retryCount += 1;
11389a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
11399a0bf528SMauro Carvalho Chehab 					  &waitCmd);
11409a0bf528SMauro Carvalho Chehab 		} while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
11419a0bf528SMauro Carvalho Chehab 			 && (waitCmd != 0));
11429a0bf528SMauro Carvalho Chehab 		if (status < 0)
11439a0bf528SMauro Carvalho Chehab 			goto error;
11449a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
11459a0bf528SMauro Carvalho Chehab 	}
11469a0bf528SMauro Carvalho Chehab error:
11479a0bf528SMauro Carvalho Chehab 	if (status < 0)
11489a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
11499a0bf528SMauro Carvalho Chehab 
11509a0bf528SMauro Carvalho Chehab 	return status;
11519a0bf528SMauro Carvalho Chehab }
11529a0bf528SMauro Carvalho Chehab 
11539a0bf528SMauro Carvalho Chehab static int HI_CfgCommand(struct drxk_state *state)
11549a0bf528SMauro Carvalho Chehab {
11559a0bf528SMauro Carvalho Chehab 	int status;
11569a0bf528SMauro Carvalho Chehab 
11579a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
11589a0bf528SMauro Carvalho Chehab 
11599a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
11609a0bf528SMauro Carvalho Chehab 
11619a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
11629a0bf528SMauro Carvalho Chehab 	if (status < 0)
11639a0bf528SMauro Carvalho Chehab 		goto error;
11649a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
11659a0bf528SMauro Carvalho Chehab 	if (status < 0)
11669a0bf528SMauro Carvalho Chehab 		goto error;
11679a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
11689a0bf528SMauro Carvalho Chehab 	if (status < 0)
11699a0bf528SMauro Carvalho Chehab 		goto error;
11709a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
11719a0bf528SMauro Carvalho Chehab 	if (status < 0)
11729a0bf528SMauro Carvalho Chehab 		goto error;
11739a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
11749a0bf528SMauro Carvalho Chehab 	if (status < 0)
11759a0bf528SMauro Carvalho Chehab 		goto error;
11769a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
11779a0bf528SMauro Carvalho Chehab 	if (status < 0)
11789a0bf528SMauro Carvalho Chehab 		goto error;
11799a0bf528SMauro Carvalho Chehab 	status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
11809a0bf528SMauro Carvalho Chehab 	if (status < 0)
11819a0bf528SMauro Carvalho Chehab 		goto error;
11829a0bf528SMauro Carvalho Chehab 
11839a0bf528SMauro Carvalho Chehab 	state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11849a0bf528SMauro Carvalho Chehab error:
11859a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
11869a0bf528SMauro Carvalho Chehab 	if (status < 0)
11879a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
11889a0bf528SMauro Carvalho Chehab 	return status;
11899a0bf528SMauro Carvalho Chehab }
11909a0bf528SMauro Carvalho Chehab 
11919a0bf528SMauro Carvalho Chehab static int InitHI(struct drxk_state *state)
11929a0bf528SMauro Carvalho Chehab {
11939a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
11949a0bf528SMauro Carvalho Chehab 
11959a0bf528SMauro Carvalho Chehab 	state->m_HICfgWakeUpKey = (state->demod_address << 1);
11969a0bf528SMauro Carvalho Chehab 	state->m_HICfgTimeout = 0x96FF;
11979a0bf528SMauro Carvalho Chehab 	/* port/bridge/power down ctrl */
11989a0bf528SMauro Carvalho Chehab 	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
11999a0bf528SMauro Carvalho Chehab 
12009a0bf528SMauro Carvalho Chehab 	return HI_CfgCommand(state);
12019a0bf528SMauro Carvalho Chehab }
12029a0bf528SMauro Carvalho Chehab 
12039a0bf528SMauro Carvalho Chehab static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
12049a0bf528SMauro Carvalho Chehab {
12059a0bf528SMauro Carvalho Chehab 	int status = -1;
12069a0bf528SMauro Carvalho Chehab 	u16 sioPdrMclkCfg = 0;
12079a0bf528SMauro Carvalho Chehab 	u16 sioPdrMdxCfg = 0;
12089a0bf528SMauro Carvalho Chehab 	u16 err_cfg = 0;
12099a0bf528SMauro Carvalho Chehab 
12109a0bf528SMauro Carvalho Chehab 	dprintk(1, ": mpeg %s, %s mode\n",
12119a0bf528SMauro Carvalho Chehab 		mpegEnable ? "enable" : "disable",
12129a0bf528SMauro Carvalho Chehab 		state->m_enableParallel ? "parallel" : "serial");
12139a0bf528SMauro Carvalho Chehab 
12149a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
12159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
12169a0bf528SMauro Carvalho Chehab 	if (status < 0)
12179a0bf528SMauro Carvalho Chehab 		goto error;
12189a0bf528SMauro Carvalho Chehab 
12199a0bf528SMauro Carvalho Chehab 	/*  MPEG TS pad configuration */
12209a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
12219a0bf528SMauro Carvalho Chehab 	if (status < 0)
12229a0bf528SMauro Carvalho Chehab 		goto error;
12239a0bf528SMauro Carvalho Chehab 
12249a0bf528SMauro Carvalho Chehab 	if (mpegEnable == false) {
12259a0bf528SMauro Carvalho Chehab 		/*  Set MPEG TS pads to inputmode */
12269a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
12279a0bf528SMauro Carvalho Chehab 		if (status < 0)
12289a0bf528SMauro Carvalho Chehab 			goto error;
12299a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
12309a0bf528SMauro Carvalho Chehab 		if (status < 0)
12319a0bf528SMauro Carvalho Chehab 			goto error;
12329a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
12339a0bf528SMauro Carvalho Chehab 		if (status < 0)
12349a0bf528SMauro Carvalho Chehab 			goto error;
12359a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
12369a0bf528SMauro Carvalho Chehab 		if (status < 0)
12379a0bf528SMauro Carvalho Chehab 			goto error;
12389a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
12399a0bf528SMauro Carvalho Chehab 		if (status < 0)
12409a0bf528SMauro Carvalho Chehab 			goto error;
12419a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
12429a0bf528SMauro Carvalho Chehab 		if (status < 0)
12439a0bf528SMauro Carvalho Chehab 			goto error;
12449a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
12459a0bf528SMauro Carvalho Chehab 		if (status < 0)
12469a0bf528SMauro Carvalho Chehab 			goto error;
12479a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
12489a0bf528SMauro Carvalho Chehab 		if (status < 0)
12499a0bf528SMauro Carvalho Chehab 			goto error;
12509a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
12519a0bf528SMauro Carvalho Chehab 		if (status < 0)
12529a0bf528SMauro Carvalho Chehab 			goto error;
12539a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
12549a0bf528SMauro Carvalho Chehab 		if (status < 0)
12559a0bf528SMauro Carvalho Chehab 			goto error;
12569a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
12579a0bf528SMauro Carvalho Chehab 		if (status < 0)
12589a0bf528SMauro Carvalho Chehab 			goto error;
12599a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12609a0bf528SMauro Carvalho Chehab 		if (status < 0)
12619a0bf528SMauro Carvalho Chehab 			goto error;
12629a0bf528SMauro Carvalho Chehab 	} else {
12639a0bf528SMauro Carvalho Chehab 		/* Enable MPEG output */
12649a0bf528SMauro Carvalho Chehab 		sioPdrMdxCfg =
12659a0bf528SMauro Carvalho Chehab 			((state->m_TSDataStrength <<
12669a0bf528SMauro Carvalho Chehab 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
12679a0bf528SMauro Carvalho Chehab 		sioPdrMclkCfg = ((state->m_TSClockkStrength <<
12689a0bf528SMauro Carvalho Chehab 					SIO_PDR_MCLK_CFG_DRIVE__B) |
12699a0bf528SMauro Carvalho Chehab 					0x0003);
12709a0bf528SMauro Carvalho Chehab 
12719a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
12729a0bf528SMauro Carvalho Chehab 		if (status < 0)
12739a0bf528SMauro Carvalho Chehab 			goto error;
12749a0bf528SMauro Carvalho Chehab 
12759a0bf528SMauro Carvalho Chehab 		if (state->enable_merr_cfg)
12769a0bf528SMauro Carvalho Chehab 			err_cfg = sioPdrMdxCfg;
12779a0bf528SMauro Carvalho Chehab 
12789a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
12799a0bf528SMauro Carvalho Chehab 		if (status < 0)
12809a0bf528SMauro Carvalho Chehab 			goto error;
12819a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
12829a0bf528SMauro Carvalho Chehab 		if (status < 0)
12839a0bf528SMauro Carvalho Chehab 			goto error;
12849a0bf528SMauro Carvalho Chehab 
12859a0bf528SMauro Carvalho Chehab 		if (state->m_enableParallel == true) {
12869a0bf528SMauro Carvalho Chehab 			/* paralel -> enable MD1 to MD7 */
12879a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
12889a0bf528SMauro Carvalho Chehab 			if (status < 0)
12899a0bf528SMauro Carvalho Chehab 				goto error;
12909a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
12919a0bf528SMauro Carvalho Chehab 			if (status < 0)
12929a0bf528SMauro Carvalho Chehab 				goto error;
12939a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
12949a0bf528SMauro Carvalho Chehab 			if (status < 0)
12959a0bf528SMauro Carvalho Chehab 				goto error;
12969a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
12979a0bf528SMauro Carvalho Chehab 			if (status < 0)
12989a0bf528SMauro Carvalho Chehab 				goto error;
12999a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
13009a0bf528SMauro Carvalho Chehab 			if (status < 0)
13019a0bf528SMauro Carvalho Chehab 				goto error;
13029a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
13039a0bf528SMauro Carvalho Chehab 			if (status < 0)
13049a0bf528SMauro Carvalho Chehab 				goto error;
13059a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
13069a0bf528SMauro Carvalho Chehab 			if (status < 0)
13079a0bf528SMauro Carvalho Chehab 				goto error;
13089a0bf528SMauro Carvalho Chehab 		} else {
13099a0bf528SMauro Carvalho Chehab 			sioPdrMdxCfg = ((state->m_TSDataStrength <<
13109a0bf528SMauro Carvalho Chehab 						SIO_PDR_MD0_CFG_DRIVE__B)
13119a0bf528SMauro Carvalho Chehab 					| 0x0003);
13129a0bf528SMauro Carvalho Chehab 			/* serial -> disable MD1 to MD7 */
13139a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
13149a0bf528SMauro Carvalho Chehab 			if (status < 0)
13159a0bf528SMauro Carvalho Chehab 				goto error;
13169a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
13179a0bf528SMauro Carvalho Chehab 			if (status < 0)
13189a0bf528SMauro Carvalho Chehab 				goto error;
13199a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
13209a0bf528SMauro Carvalho Chehab 			if (status < 0)
13219a0bf528SMauro Carvalho Chehab 				goto error;
13229a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
13239a0bf528SMauro Carvalho Chehab 			if (status < 0)
13249a0bf528SMauro Carvalho Chehab 				goto error;
13259a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
13269a0bf528SMauro Carvalho Chehab 			if (status < 0)
13279a0bf528SMauro Carvalho Chehab 				goto error;
13289a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
13299a0bf528SMauro Carvalho Chehab 			if (status < 0)
13309a0bf528SMauro Carvalho Chehab 				goto error;
13319a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
13329a0bf528SMauro Carvalho Chehab 			if (status < 0)
13339a0bf528SMauro Carvalho Chehab 				goto error;
13349a0bf528SMauro Carvalho Chehab 		}
13359a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
13369a0bf528SMauro Carvalho Chehab 		if (status < 0)
13379a0bf528SMauro Carvalho Chehab 			goto error;
13389a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
13399a0bf528SMauro Carvalho Chehab 		if (status < 0)
13409a0bf528SMauro Carvalho Chehab 			goto error;
13419a0bf528SMauro Carvalho Chehab 	}
13429a0bf528SMauro Carvalho Chehab 	/*  Enable MB output over MPEG pads and ctl input */
13439a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
13449a0bf528SMauro Carvalho Chehab 	if (status < 0)
13459a0bf528SMauro Carvalho Chehab 		goto error;
13469a0bf528SMauro Carvalho Chehab 	/*  Write nomagic word to enable pdr reg write */
13479a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
13489a0bf528SMauro Carvalho Chehab error:
13499a0bf528SMauro Carvalho Chehab 	if (status < 0)
13509a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
13519a0bf528SMauro Carvalho Chehab 	return status;
13529a0bf528SMauro Carvalho Chehab }
13539a0bf528SMauro Carvalho Chehab 
13549a0bf528SMauro Carvalho Chehab static int MPEGTSDisable(struct drxk_state *state)
13559a0bf528SMauro Carvalho Chehab {
13569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13579a0bf528SMauro Carvalho Chehab 
13589a0bf528SMauro Carvalho Chehab 	return MPEGTSConfigurePins(state, false);
13599a0bf528SMauro Carvalho Chehab }
13609a0bf528SMauro Carvalho Chehab 
13619a0bf528SMauro Carvalho Chehab static int BLChainCmd(struct drxk_state *state,
13629a0bf528SMauro Carvalho Chehab 		      u16 romOffset, u16 nrOfElements, u32 timeOut)
13639a0bf528SMauro Carvalho Chehab {
13649a0bf528SMauro Carvalho Chehab 	u16 blStatus = 0;
13659a0bf528SMauro Carvalho Chehab 	int status;
13669a0bf528SMauro Carvalho Chehab 	unsigned long end;
13679a0bf528SMauro Carvalho Chehab 
13689a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
13699a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
13709a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
13719a0bf528SMauro Carvalho Chehab 	if (status < 0)
13729a0bf528SMauro Carvalho Chehab 		goto error;
13739a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
13749a0bf528SMauro Carvalho Chehab 	if (status < 0)
13759a0bf528SMauro Carvalho Chehab 		goto error;
13769a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
13779a0bf528SMauro Carvalho Chehab 	if (status < 0)
13789a0bf528SMauro Carvalho Chehab 		goto error;
13799a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
13809a0bf528SMauro Carvalho Chehab 	if (status < 0)
13819a0bf528SMauro Carvalho Chehab 		goto error;
13829a0bf528SMauro Carvalho Chehab 
13839a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(timeOut);
13849a0bf528SMauro Carvalho Chehab 	do {
13859a0bf528SMauro Carvalho Chehab 		msleep(1);
13869a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &blStatus);
13879a0bf528SMauro Carvalho Chehab 		if (status < 0)
13889a0bf528SMauro Carvalho Chehab 			goto error;
13899a0bf528SMauro Carvalho Chehab 	} while ((blStatus == 0x1) &&
13909a0bf528SMauro Carvalho Chehab 			((time_is_after_jiffies(end))));
13919a0bf528SMauro Carvalho Chehab 
13929a0bf528SMauro Carvalho Chehab 	if (blStatus == 0x1) {
13939a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: SIO not ready\n");
13949a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
13959a0bf528SMauro Carvalho Chehab 		goto error2;
13969a0bf528SMauro Carvalho Chehab 	}
13979a0bf528SMauro Carvalho Chehab error:
13989a0bf528SMauro Carvalho Chehab 	if (status < 0)
13999a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
14009a0bf528SMauro Carvalho Chehab error2:
14019a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
14029a0bf528SMauro Carvalho Chehab 	return status;
14039a0bf528SMauro Carvalho Chehab }
14049a0bf528SMauro Carvalho Chehab 
14059a0bf528SMauro Carvalho Chehab 
14069a0bf528SMauro Carvalho Chehab static int DownloadMicrocode(struct drxk_state *state,
14079a0bf528SMauro Carvalho Chehab 			     const u8 pMCImage[], u32 Length)
14089a0bf528SMauro Carvalho Chehab {
14099a0bf528SMauro Carvalho Chehab 	const u8 *pSrc = pMCImage;
14109a0bf528SMauro Carvalho Chehab 	u32 Address;
14119a0bf528SMauro Carvalho Chehab 	u16 nBlocks;
14129a0bf528SMauro Carvalho Chehab 	u16 BlockSize;
14139a0bf528SMauro Carvalho Chehab 	u32 offset = 0;
14149a0bf528SMauro Carvalho Chehab 	u32 i;
14159a0bf528SMauro Carvalho Chehab 	int status = 0;
14169a0bf528SMauro Carvalho Chehab 
14179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14189a0bf528SMauro Carvalho Chehab 
14199a0bf528SMauro Carvalho Chehab 	/* down the drain (we don't care about MAGIC_WORD) */
14209a0bf528SMauro Carvalho Chehab #if 0
14219a0bf528SMauro Carvalho Chehab 	/* For future reference */
14229a0bf528SMauro Carvalho Chehab 	Drain = (pSrc[0] << 8) | pSrc[1];
14239a0bf528SMauro Carvalho Chehab #endif
14249a0bf528SMauro Carvalho Chehab 	pSrc += sizeof(u16);
14259a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
14269a0bf528SMauro Carvalho Chehab 	nBlocks = (pSrc[0] << 8) | pSrc[1];
14279a0bf528SMauro Carvalho Chehab 	pSrc += sizeof(u16);
14289a0bf528SMauro Carvalho Chehab 	offset += sizeof(u16);
14299a0bf528SMauro Carvalho Chehab 
14309a0bf528SMauro Carvalho Chehab 	for (i = 0; i < nBlocks; i += 1) {
14319a0bf528SMauro Carvalho Chehab 		Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
14329a0bf528SMauro Carvalho Chehab 		    (pSrc[2] << 8) | pSrc[3];
14339a0bf528SMauro Carvalho Chehab 		pSrc += sizeof(u32);
14349a0bf528SMauro Carvalho Chehab 		offset += sizeof(u32);
14359a0bf528SMauro Carvalho Chehab 
14369a0bf528SMauro Carvalho Chehab 		BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
14379a0bf528SMauro Carvalho Chehab 		pSrc += sizeof(u16);
14389a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
14399a0bf528SMauro Carvalho Chehab 
14409a0bf528SMauro Carvalho Chehab #if 0
14419a0bf528SMauro Carvalho Chehab 		/* For future reference */
14429a0bf528SMauro Carvalho Chehab 		Flags = (pSrc[0] << 8) | pSrc[1];
14439a0bf528SMauro Carvalho Chehab #endif
14449a0bf528SMauro Carvalho Chehab 		pSrc += sizeof(u16);
14459a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
14469a0bf528SMauro Carvalho Chehab 
14479a0bf528SMauro Carvalho Chehab #if 0
14489a0bf528SMauro Carvalho Chehab 		/* For future reference */
14499a0bf528SMauro Carvalho Chehab 		BlockCRC = (pSrc[0] << 8) | pSrc[1];
14509a0bf528SMauro Carvalho Chehab #endif
14519a0bf528SMauro Carvalho Chehab 		pSrc += sizeof(u16);
14529a0bf528SMauro Carvalho Chehab 		offset += sizeof(u16);
14539a0bf528SMauro Carvalho Chehab 
14549a0bf528SMauro Carvalho Chehab 		if (offset + BlockSize > Length) {
14559a0bf528SMauro Carvalho Chehab 			printk(KERN_ERR "drxk: Firmware is corrupted.\n");
14569a0bf528SMauro Carvalho Chehab 			return -EINVAL;
14579a0bf528SMauro Carvalho Chehab 		}
14589a0bf528SMauro Carvalho Chehab 
14599a0bf528SMauro Carvalho Chehab 		status = write_block(state, Address, BlockSize, pSrc);
14609a0bf528SMauro Carvalho Chehab 		if (status < 0) {
14619a0bf528SMauro Carvalho Chehab 			printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
14629a0bf528SMauro Carvalho Chehab 			break;
14639a0bf528SMauro Carvalho Chehab 		}
14649a0bf528SMauro Carvalho Chehab 		pSrc += BlockSize;
14659a0bf528SMauro Carvalho Chehab 		offset += BlockSize;
14669a0bf528SMauro Carvalho Chehab 	}
14679a0bf528SMauro Carvalho Chehab 	return status;
14689a0bf528SMauro Carvalho Chehab }
14699a0bf528SMauro Carvalho Chehab 
14709a0bf528SMauro Carvalho Chehab static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
14719a0bf528SMauro Carvalho Chehab {
14729a0bf528SMauro Carvalho Chehab 	int status;
14739a0bf528SMauro Carvalho Chehab 	u16 data = 0;
14749a0bf528SMauro Carvalho Chehab 	u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
14759a0bf528SMauro Carvalho Chehab 	u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
14769a0bf528SMauro Carvalho Chehab 	unsigned long end;
14779a0bf528SMauro Carvalho Chehab 
14789a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
14799a0bf528SMauro Carvalho Chehab 
14809a0bf528SMauro Carvalho Chehab 	if (enable == false) {
14819a0bf528SMauro Carvalho Chehab 		desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
14829a0bf528SMauro Carvalho Chehab 		desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
14839a0bf528SMauro Carvalho Chehab 	}
14849a0bf528SMauro Carvalho Chehab 
14859a0bf528SMauro Carvalho Chehab 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
14869a0bf528SMauro Carvalho Chehab 	if (status >= 0 && data == desiredStatus) {
14879a0bf528SMauro Carvalho Chehab 		/* tokenring already has correct status */
14889a0bf528SMauro Carvalho Chehab 		return status;
14899a0bf528SMauro Carvalho Chehab 	}
14909a0bf528SMauro Carvalho Chehab 	/* Disable/enable dvbt tokenring bridge   */
14919a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
14929a0bf528SMauro Carvalho Chehab 
14939a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
14949a0bf528SMauro Carvalho Chehab 	do {
14959a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
14969a0bf528SMauro Carvalho Chehab 		if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
14979a0bf528SMauro Carvalho Chehab 			break;
14989a0bf528SMauro Carvalho Chehab 		msleep(1);
14999a0bf528SMauro Carvalho Chehab 	} while (1);
15009a0bf528SMauro Carvalho Chehab 	if (data != desiredStatus) {
15019a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: SIO not ready\n");
15029a0bf528SMauro Carvalho Chehab 		return -EINVAL;
15039a0bf528SMauro Carvalho Chehab 	}
15049a0bf528SMauro Carvalho Chehab 	return status;
15059a0bf528SMauro Carvalho Chehab }
15069a0bf528SMauro Carvalho Chehab 
15079a0bf528SMauro Carvalho Chehab static int MPEGTSStop(struct drxk_state *state)
15089a0bf528SMauro Carvalho Chehab {
15099a0bf528SMauro Carvalho Chehab 	int status = 0;
15109a0bf528SMauro Carvalho Chehab 	u16 fecOcSncMode = 0;
15119a0bf528SMauro Carvalho Chehab 	u16 fecOcIprMode = 0;
15129a0bf528SMauro Carvalho Chehab 
15139a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15149a0bf528SMauro Carvalho Chehab 
15159a0bf528SMauro Carvalho Chehab 	/* Gracefull shutdown (byte boundaries) */
15169a0bf528SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
15179a0bf528SMauro Carvalho Chehab 	if (status < 0)
15189a0bf528SMauro Carvalho Chehab 		goto error;
15199a0bf528SMauro Carvalho Chehab 	fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
15209a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
15219a0bf528SMauro Carvalho Chehab 	if (status < 0)
15229a0bf528SMauro Carvalho Chehab 		goto error;
15239a0bf528SMauro Carvalho Chehab 
15249a0bf528SMauro Carvalho Chehab 	/* Suppress MCLK during absence of data */
15259a0bf528SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
15269a0bf528SMauro Carvalho Chehab 	if (status < 0)
15279a0bf528SMauro Carvalho Chehab 		goto error;
15289a0bf528SMauro Carvalho Chehab 	fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
15299a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
15309a0bf528SMauro Carvalho Chehab 
15319a0bf528SMauro Carvalho Chehab error:
15329a0bf528SMauro Carvalho Chehab 	if (status < 0)
15339a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
15349a0bf528SMauro Carvalho Chehab 
15359a0bf528SMauro Carvalho Chehab 	return status;
15369a0bf528SMauro Carvalho Chehab }
15379a0bf528SMauro Carvalho Chehab 
15389a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
15399a0bf528SMauro Carvalho Chehab 		       u16 cmd, u8 parameterLen,
15409a0bf528SMauro Carvalho Chehab 		       u16 *parameter, u8 resultLen, u16 *result)
15419a0bf528SMauro Carvalho Chehab {
15429a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
15439a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
15449a0bf528SMauro Carvalho Chehab #endif
15459a0bf528SMauro Carvalho Chehab 	u16 curCmd = 0;
15469a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
15479a0bf528SMauro Carvalho Chehab 	unsigned long end;
15489a0bf528SMauro Carvalho Chehab 	u8 buffer[34];
15499a0bf528SMauro Carvalho Chehab 	int cnt = 0, ii;
15509a0bf528SMauro Carvalho Chehab 	const char *p;
15519a0bf528SMauro Carvalho Chehab 	char errname[30];
15529a0bf528SMauro Carvalho Chehab 
15539a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
15549a0bf528SMauro Carvalho Chehab 
15559a0bf528SMauro Carvalho Chehab 	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
15569a0bf528SMauro Carvalho Chehab 	    ((resultLen > 0) && (result == NULL))) {
15579a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
15589a0bf528SMauro Carvalho Chehab 		return status;
15599a0bf528SMauro Carvalho Chehab 	}
15609a0bf528SMauro Carvalho Chehab 
15619a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
15629a0bf528SMauro Carvalho Chehab 
15639a0bf528SMauro Carvalho Chehab 	/* assume that the command register is ready
15649a0bf528SMauro Carvalho Chehab 		since it is checked afterwards */
15659a0bf528SMauro Carvalho Chehab 	for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
15669a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = (parameter[ii] & 0xFF);
15679a0bf528SMauro Carvalho Chehab 		buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
15689a0bf528SMauro Carvalho Chehab 	}
15699a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = (cmd & 0xFF);
15709a0bf528SMauro Carvalho Chehab 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
15719a0bf528SMauro Carvalho Chehab 
15729a0bf528SMauro Carvalho Chehab 	write_block(state, SCU_RAM_PARAM_0__A -
15739a0bf528SMauro Carvalho Chehab 			(parameterLen - 1), cnt, buffer);
15749a0bf528SMauro Carvalho Chehab 	/* Wait until SCU has processed command */
15759a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
15769a0bf528SMauro Carvalho Chehab 	do {
15779a0bf528SMauro Carvalho Chehab 		msleep(1);
15789a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
15799a0bf528SMauro Carvalho Chehab 		if (status < 0)
15809a0bf528SMauro Carvalho Chehab 			goto error;
15819a0bf528SMauro Carvalho Chehab 	} while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
15829a0bf528SMauro Carvalho Chehab 	if (curCmd != DRX_SCU_READY) {
15839a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: SCU not ready\n");
15849a0bf528SMauro Carvalho Chehab 		status = -EIO;
15859a0bf528SMauro Carvalho Chehab 		goto error2;
15869a0bf528SMauro Carvalho Chehab 	}
15879a0bf528SMauro Carvalho Chehab 	/* read results */
15889a0bf528SMauro Carvalho Chehab 	if ((resultLen > 0) && (result != NULL)) {
15899a0bf528SMauro Carvalho Chehab 		s16 err;
15909a0bf528SMauro Carvalho Chehab 		int ii;
15919a0bf528SMauro Carvalho Chehab 
15929a0bf528SMauro Carvalho Chehab 		for (ii = resultLen - 1; ii >= 0; ii -= 1) {
15939a0bf528SMauro Carvalho Chehab 			status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
15949a0bf528SMauro Carvalho Chehab 			if (status < 0)
15959a0bf528SMauro Carvalho Chehab 				goto error;
15969a0bf528SMauro Carvalho Chehab 		}
15979a0bf528SMauro Carvalho Chehab 
15989a0bf528SMauro Carvalho Chehab 		/* Check if an error was reported by SCU */
15999a0bf528SMauro Carvalho Chehab 		err = (s16)result[0];
16009a0bf528SMauro Carvalho Chehab 		if (err >= 0)
16019a0bf528SMauro Carvalho Chehab 			goto error;
16029a0bf528SMauro Carvalho Chehab 
16039a0bf528SMauro Carvalho Chehab 		/* check for the known error codes */
16049a0bf528SMauro Carvalho Chehab 		switch (err) {
16059a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKCMD:
16069a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKCMD";
16079a0bf528SMauro Carvalho Chehab 			break;
16089a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_UNKSTD:
16099a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_UNKSTD";
16109a0bf528SMauro Carvalho Chehab 			break;
16119a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_SIZE:
16129a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_SIZE";
16139a0bf528SMauro Carvalho Chehab 			break;
16149a0bf528SMauro Carvalho Chehab 		case SCU_RESULT_INVPAR:
16159a0bf528SMauro Carvalho Chehab 			p = "SCU_RESULT_INVPAR";
16169a0bf528SMauro Carvalho Chehab 			break;
16179a0bf528SMauro Carvalho Chehab 		default: /* Other negative values are errors */
16189a0bf528SMauro Carvalho Chehab 			sprintf(errname, "ERROR: %d\n", err);
16199a0bf528SMauro Carvalho Chehab 			p = errname;
16209a0bf528SMauro Carvalho Chehab 		}
16219a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
16229a0bf528SMauro Carvalho Chehab 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
16239a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
16249a0bf528SMauro Carvalho Chehab 		goto error2;
16259a0bf528SMauro Carvalho Chehab 	}
16269a0bf528SMauro Carvalho Chehab 
16279a0bf528SMauro Carvalho Chehab error:
16289a0bf528SMauro Carvalho Chehab 	if (status < 0)
16299a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
16309a0bf528SMauro Carvalho Chehab error2:
16319a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
16329a0bf528SMauro Carvalho Chehab 	return status;
16339a0bf528SMauro Carvalho Chehab }
16349a0bf528SMauro Carvalho Chehab 
16359a0bf528SMauro Carvalho Chehab static int SetIqmAf(struct drxk_state *state, bool active)
16369a0bf528SMauro Carvalho Chehab {
16379a0bf528SMauro Carvalho Chehab 	u16 data = 0;
16389a0bf528SMauro Carvalho Chehab 	int status;
16399a0bf528SMauro Carvalho Chehab 
16409a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
16419a0bf528SMauro Carvalho Chehab 
16429a0bf528SMauro Carvalho Chehab 	/* Configure IQM */
16439a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_STDBY__A, &data);
16449a0bf528SMauro Carvalho Chehab 	if (status < 0)
16459a0bf528SMauro Carvalho Chehab 		goto error;
16469a0bf528SMauro Carvalho Chehab 
16479a0bf528SMauro Carvalho Chehab 	if (!active) {
16489a0bf528SMauro Carvalho Chehab 		data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
16499a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_AMP_STANDBY
16509a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_PD_STANDBY
16519a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
16529a0bf528SMauro Carvalho Chehab 				| IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
16539a0bf528SMauro Carvalho Chehab 	} else {
16549a0bf528SMauro Carvalho Chehab 		data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
16559a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
16569a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_PD_STANDBY)
16579a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
16589a0bf528SMauro Carvalho Chehab 				& (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
16599a0bf528SMauro Carvalho Chehab 			);
16609a0bf528SMauro Carvalho Chehab 	}
16619a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_STDBY__A, data);
16629a0bf528SMauro Carvalho Chehab 
16639a0bf528SMauro Carvalho Chehab error:
16649a0bf528SMauro Carvalho Chehab 	if (status < 0)
16659a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
16669a0bf528SMauro Carvalho Chehab 	return status;
16679a0bf528SMauro Carvalho Chehab }
16689a0bf528SMauro Carvalho Chehab 
16699a0bf528SMauro Carvalho Chehab static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
16709a0bf528SMauro Carvalho Chehab {
16719a0bf528SMauro Carvalho Chehab 	int status = 0;
16729a0bf528SMauro Carvalho Chehab 	u16 sioCcPwdMode = 0;
16739a0bf528SMauro Carvalho Chehab 
16749a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
16759a0bf528SMauro Carvalho Chehab 
16769a0bf528SMauro Carvalho Chehab 	/* Check arguments */
16779a0bf528SMauro Carvalho Chehab 	if (mode == NULL)
16789a0bf528SMauro Carvalho Chehab 		return -EINVAL;
16799a0bf528SMauro Carvalho Chehab 
16809a0bf528SMauro Carvalho Chehab 	switch (*mode) {
16819a0bf528SMauro Carvalho Chehab 	case DRX_POWER_UP:
16829a0bf528SMauro Carvalho Chehab 		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
16839a0bf528SMauro Carvalho Chehab 		break;
16849a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_OFDM:
16859a0bf528SMauro Carvalho Chehab 		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
16869a0bf528SMauro Carvalho Chehab 		break;
16879a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_CORE:
16889a0bf528SMauro Carvalho Chehab 		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
16899a0bf528SMauro Carvalho Chehab 		break;
16909a0bf528SMauro Carvalho Chehab 	case DRXK_POWER_DOWN_PLL:
16919a0bf528SMauro Carvalho Chehab 		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
16929a0bf528SMauro Carvalho Chehab 		break;
16939a0bf528SMauro Carvalho Chehab 	case DRX_POWER_DOWN:
16949a0bf528SMauro Carvalho Chehab 		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
16959a0bf528SMauro Carvalho Chehab 		break;
16969a0bf528SMauro Carvalho Chehab 	default:
16979a0bf528SMauro Carvalho Chehab 		/* Unknow sleep mode */
16989a0bf528SMauro Carvalho Chehab 		return -EINVAL;
16999a0bf528SMauro Carvalho Chehab 	}
17009a0bf528SMauro Carvalho Chehab 
17019a0bf528SMauro Carvalho Chehab 	/* If already in requested power mode, do nothing */
17029a0bf528SMauro Carvalho Chehab 	if (state->m_currentPowerMode == *mode)
17039a0bf528SMauro Carvalho Chehab 		return 0;
17049a0bf528SMauro Carvalho Chehab 
17059a0bf528SMauro Carvalho Chehab 	/* For next steps make sure to start from DRX_POWER_UP mode */
17069a0bf528SMauro Carvalho Chehab 	if (state->m_currentPowerMode != DRX_POWER_UP) {
17079a0bf528SMauro Carvalho Chehab 		status = PowerUpDevice(state);
17089a0bf528SMauro Carvalho Chehab 		if (status < 0)
17099a0bf528SMauro Carvalho Chehab 			goto error;
17109a0bf528SMauro Carvalho Chehab 		status = DVBTEnableOFDMTokenRing(state, true);
17119a0bf528SMauro Carvalho Chehab 		if (status < 0)
17129a0bf528SMauro Carvalho Chehab 			goto error;
17139a0bf528SMauro Carvalho Chehab 	}
17149a0bf528SMauro Carvalho Chehab 
17159a0bf528SMauro Carvalho Chehab 	if (*mode == DRX_POWER_UP) {
17169a0bf528SMauro Carvalho Chehab 		/* Restore analog & pin configuartion */
17179a0bf528SMauro Carvalho Chehab 	} else {
17189a0bf528SMauro Carvalho Chehab 		/* Power down to requested mode */
17199a0bf528SMauro Carvalho Chehab 		/* Backup some register settings */
17209a0bf528SMauro Carvalho Chehab 		/* Set pins with possible pull-ups connected
17219a0bf528SMauro Carvalho Chehab 		   to them in input mode */
17229a0bf528SMauro Carvalho Chehab 		/* Analog power down */
17239a0bf528SMauro Carvalho Chehab 		/* ADC power down */
17249a0bf528SMauro Carvalho Chehab 		/* Power down device */
17259a0bf528SMauro Carvalho Chehab 		/* stop all comm_exec */
17269a0bf528SMauro Carvalho Chehab 		/* Stop and power down previous standard */
17279a0bf528SMauro Carvalho Chehab 		switch (state->m_OperationMode) {
17289a0bf528SMauro Carvalho Chehab 		case OM_DVBT:
17299a0bf528SMauro Carvalho Chehab 			status = MPEGTSStop(state);
17309a0bf528SMauro Carvalho Chehab 			if (status < 0)
17319a0bf528SMauro Carvalho Chehab 				goto error;
17329a0bf528SMauro Carvalho Chehab 			status = PowerDownDVBT(state, false);
17339a0bf528SMauro Carvalho Chehab 			if (status < 0)
17349a0bf528SMauro Carvalho Chehab 				goto error;
17359a0bf528SMauro Carvalho Chehab 			break;
17369a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_A:
17379a0bf528SMauro Carvalho Chehab 		case OM_QAM_ITU_C:
17389a0bf528SMauro Carvalho Chehab 			status = MPEGTSStop(state);
17399a0bf528SMauro Carvalho Chehab 			if (status < 0)
17409a0bf528SMauro Carvalho Chehab 				goto error;
17419a0bf528SMauro Carvalho Chehab 			status = PowerDownQAM(state);
17429a0bf528SMauro Carvalho Chehab 			if (status < 0)
17439a0bf528SMauro Carvalho Chehab 				goto error;
17449a0bf528SMauro Carvalho Chehab 			break;
17459a0bf528SMauro Carvalho Chehab 		default:
17469a0bf528SMauro Carvalho Chehab 			break;
17479a0bf528SMauro Carvalho Chehab 		}
17489a0bf528SMauro Carvalho Chehab 		status = DVBTEnableOFDMTokenRing(state, false);
17499a0bf528SMauro Carvalho Chehab 		if (status < 0)
17509a0bf528SMauro Carvalho Chehab 			goto error;
17519a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
17529a0bf528SMauro Carvalho Chehab 		if (status < 0)
17539a0bf528SMauro Carvalho Chehab 			goto error;
17549a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
17559a0bf528SMauro Carvalho Chehab 		if (status < 0)
17569a0bf528SMauro Carvalho Chehab 			goto error;
17579a0bf528SMauro Carvalho Chehab 
17589a0bf528SMauro Carvalho Chehab 		if (*mode != DRXK_POWER_DOWN_OFDM) {
17599a0bf528SMauro Carvalho Chehab 			state->m_HICfgCtrl |=
17609a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
17619a0bf528SMauro Carvalho Chehab 			status = HI_CfgCommand(state);
17629a0bf528SMauro Carvalho Chehab 			if (status < 0)
17639a0bf528SMauro Carvalho Chehab 				goto error;
17649a0bf528SMauro Carvalho Chehab 		}
17659a0bf528SMauro Carvalho Chehab 	}
17669a0bf528SMauro Carvalho Chehab 	state->m_currentPowerMode = *mode;
17679a0bf528SMauro Carvalho Chehab 
17689a0bf528SMauro Carvalho Chehab error:
17699a0bf528SMauro Carvalho Chehab 	if (status < 0)
17709a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
17719a0bf528SMauro Carvalho Chehab 
17729a0bf528SMauro Carvalho Chehab 	return status;
17739a0bf528SMauro Carvalho Chehab }
17749a0bf528SMauro Carvalho Chehab 
17759a0bf528SMauro Carvalho Chehab static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
17769a0bf528SMauro Carvalho Chehab {
17779a0bf528SMauro Carvalho Chehab 	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
17789a0bf528SMauro Carvalho Chehab 	u16 cmdResult = 0;
17799a0bf528SMauro Carvalho Chehab 	u16 data = 0;
17809a0bf528SMauro Carvalho Chehab 	int status;
17819a0bf528SMauro Carvalho Chehab 
17829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
17839a0bf528SMauro Carvalho Chehab 
17849a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
17859a0bf528SMauro Carvalho Chehab 	if (status < 0)
17869a0bf528SMauro Carvalho Chehab 		goto error;
17879a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
17889a0bf528SMauro Carvalho Chehab 		/* Send OFDM stop command */
17899a0bf528SMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
17909a0bf528SMauro Carvalho Chehab 		if (status < 0)
17919a0bf528SMauro Carvalho Chehab 			goto error;
17929a0bf528SMauro Carvalho Chehab 		/* Send OFDM reset command */
17939a0bf528SMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
17949a0bf528SMauro Carvalho Chehab 		if (status < 0)
17959a0bf528SMauro Carvalho Chehab 			goto error;
17969a0bf528SMauro Carvalho Chehab 	}
17979a0bf528SMauro Carvalho Chehab 
17989a0bf528SMauro Carvalho Chehab 	/* Reset datapath for OFDM, processors first */
17999a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
18009a0bf528SMauro Carvalho Chehab 	if (status < 0)
18019a0bf528SMauro Carvalho Chehab 		goto error;
18029a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
18039a0bf528SMauro Carvalho Chehab 	if (status < 0)
18049a0bf528SMauro Carvalho Chehab 		goto error;
18059a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
18069a0bf528SMauro Carvalho Chehab 	if (status < 0)
18079a0bf528SMauro Carvalho Chehab 		goto error;
18089a0bf528SMauro Carvalho Chehab 
18099a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
18109a0bf528SMauro Carvalho Chehab 	status = SetIqmAf(state, false);
18119a0bf528SMauro Carvalho Chehab 	if (status < 0)
18129a0bf528SMauro Carvalho Chehab 		goto error;
18139a0bf528SMauro Carvalho Chehab 
18149a0bf528SMauro Carvalho Chehab 	/* powerdown to OFDM mode          */
18159a0bf528SMauro Carvalho Chehab 	if (setPowerMode) {
18169a0bf528SMauro Carvalho Chehab 		status = CtrlPowerMode(state, &powerMode);
18179a0bf528SMauro Carvalho Chehab 		if (status < 0)
18189a0bf528SMauro Carvalho Chehab 			goto error;
18199a0bf528SMauro Carvalho Chehab 	}
18209a0bf528SMauro Carvalho Chehab error:
18219a0bf528SMauro Carvalho Chehab 	if (status < 0)
18229a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
18239a0bf528SMauro Carvalho Chehab 	return status;
18249a0bf528SMauro Carvalho Chehab }
18259a0bf528SMauro Carvalho Chehab 
18269a0bf528SMauro Carvalho Chehab static int SetOperationMode(struct drxk_state *state,
18279a0bf528SMauro Carvalho Chehab 			    enum OperationMode oMode)
18289a0bf528SMauro Carvalho Chehab {
18299a0bf528SMauro Carvalho Chehab 	int status = 0;
18309a0bf528SMauro Carvalho Chehab 
18319a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
18329a0bf528SMauro Carvalho Chehab 	/*
18339a0bf528SMauro Carvalho Chehab 	   Stop and power down previous standard
18349a0bf528SMauro Carvalho Chehab 	   TODO investigate total power down instead of partial
18359a0bf528SMauro Carvalho Chehab 	   power down depending on "previous" standard.
18369a0bf528SMauro Carvalho Chehab 	 */
18379a0bf528SMauro Carvalho Chehab 
18389a0bf528SMauro Carvalho Chehab 	/* disable HW lock indicator */
18399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
18409a0bf528SMauro Carvalho Chehab 	if (status < 0)
18419a0bf528SMauro Carvalho Chehab 		goto error;
18429a0bf528SMauro Carvalho Chehab 
18439a0bf528SMauro Carvalho Chehab 	/* Device is already at the required mode */
18449a0bf528SMauro Carvalho Chehab 	if (state->m_OperationMode == oMode)
18459a0bf528SMauro Carvalho Chehab 		return 0;
18469a0bf528SMauro Carvalho Chehab 
18479a0bf528SMauro Carvalho Chehab 	switch (state->m_OperationMode) {
18489a0bf528SMauro Carvalho Chehab 		/* OM_NONE was added for start up */
18499a0bf528SMauro Carvalho Chehab 	case OM_NONE:
18509a0bf528SMauro Carvalho Chehab 		break;
18519a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
18529a0bf528SMauro Carvalho Chehab 		status = MPEGTSStop(state);
18539a0bf528SMauro Carvalho Chehab 		if (status < 0)
18549a0bf528SMauro Carvalho Chehab 			goto error;
18559a0bf528SMauro Carvalho Chehab 		status = PowerDownDVBT(state, true);
18569a0bf528SMauro Carvalho Chehab 		if (status < 0)
18579a0bf528SMauro Carvalho Chehab 			goto error;
18589a0bf528SMauro Carvalho Chehab 		state->m_OperationMode = OM_NONE;
18599a0bf528SMauro Carvalho Chehab 		break;
18609a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
18619a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
18629a0bf528SMauro Carvalho Chehab 		status = MPEGTSStop(state);
18639a0bf528SMauro Carvalho Chehab 		if (status < 0)
18649a0bf528SMauro Carvalho Chehab 			goto error;
18659a0bf528SMauro Carvalho Chehab 		status = PowerDownQAM(state);
18669a0bf528SMauro Carvalho Chehab 		if (status < 0)
18679a0bf528SMauro Carvalho Chehab 			goto error;
18689a0bf528SMauro Carvalho Chehab 		state->m_OperationMode = OM_NONE;
18699a0bf528SMauro Carvalho Chehab 		break;
18709a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18719a0bf528SMauro Carvalho Chehab 	default:
18729a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
18739a0bf528SMauro Carvalho Chehab 		goto error;
18749a0bf528SMauro Carvalho Chehab 	}
18759a0bf528SMauro Carvalho Chehab 
18769a0bf528SMauro Carvalho Chehab 	/*
18779a0bf528SMauro Carvalho Chehab 		Power up new standard
18789a0bf528SMauro Carvalho Chehab 		*/
18799a0bf528SMauro Carvalho Chehab 	switch (oMode) {
18809a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
18819a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-T\n");
18829a0bf528SMauro Carvalho Chehab 		state->m_OperationMode = oMode;
18839a0bf528SMauro Carvalho Chehab 		status = SetDVBTStandard(state, oMode);
18849a0bf528SMauro Carvalho Chehab 		if (status < 0)
18859a0bf528SMauro Carvalho Chehab 			goto error;
18869a0bf528SMauro Carvalho Chehab 		break;
18879a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
18889a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
18899a0bf528SMauro Carvalho Chehab 		dprintk(1, ": DVB-C Annex %c\n",
18909a0bf528SMauro Carvalho Chehab 			(state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
18919a0bf528SMauro Carvalho Chehab 		state->m_OperationMode = oMode;
18929a0bf528SMauro Carvalho Chehab 		status = SetQAMStandard(state, oMode);
18939a0bf528SMauro Carvalho Chehab 		if (status < 0)
18949a0bf528SMauro Carvalho Chehab 			goto error;
18959a0bf528SMauro Carvalho Chehab 		break;
18969a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
18979a0bf528SMauro Carvalho Chehab 	default:
18989a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
18999a0bf528SMauro Carvalho Chehab 	}
19009a0bf528SMauro Carvalho Chehab error:
19019a0bf528SMauro Carvalho Chehab 	if (status < 0)
19029a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
19039a0bf528SMauro Carvalho Chehab 	return status;
19049a0bf528SMauro Carvalho Chehab }
19059a0bf528SMauro Carvalho Chehab 
19069a0bf528SMauro Carvalho Chehab static int Start(struct drxk_state *state, s32 offsetFreq,
19079a0bf528SMauro Carvalho Chehab 		 s32 IntermediateFrequency)
19089a0bf528SMauro Carvalho Chehab {
19099a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
19109a0bf528SMauro Carvalho Chehab 
19119a0bf528SMauro Carvalho Chehab 	u16 IFreqkHz;
19129a0bf528SMauro Carvalho Chehab 	s32 OffsetkHz = offsetFreq / 1000;
19139a0bf528SMauro Carvalho Chehab 
19149a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19159a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState != DRXK_STOPPED &&
19169a0bf528SMauro Carvalho Chehab 		state->m_DrxkState != DRXK_DTV_STARTED)
19179a0bf528SMauro Carvalho Chehab 		goto error;
19189a0bf528SMauro Carvalho Chehab 
19199a0bf528SMauro Carvalho Chehab 	state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
19209a0bf528SMauro Carvalho Chehab 
19219a0bf528SMauro Carvalho Chehab 	if (IntermediateFrequency < 0) {
19229a0bf528SMauro Carvalho Chehab 		state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
19239a0bf528SMauro Carvalho Chehab 		IntermediateFrequency = -IntermediateFrequency;
19249a0bf528SMauro Carvalho Chehab 	}
19259a0bf528SMauro Carvalho Chehab 
19269a0bf528SMauro Carvalho Chehab 	switch (state->m_OperationMode) {
19279a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
19289a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
19299a0bf528SMauro Carvalho Chehab 		IFreqkHz = (IntermediateFrequency / 1000);
19309a0bf528SMauro Carvalho Chehab 		status = SetQAM(state, IFreqkHz, OffsetkHz);
19319a0bf528SMauro Carvalho Chehab 		if (status < 0)
19329a0bf528SMauro Carvalho Chehab 			goto error;
19339a0bf528SMauro Carvalho Chehab 		state->m_DrxkState = DRXK_DTV_STARTED;
19349a0bf528SMauro Carvalho Chehab 		break;
19359a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
19369a0bf528SMauro Carvalho Chehab 		IFreqkHz = (IntermediateFrequency / 1000);
19379a0bf528SMauro Carvalho Chehab 		status = MPEGTSStop(state);
19389a0bf528SMauro Carvalho Chehab 		if (status < 0)
19399a0bf528SMauro Carvalho Chehab 			goto error;
19409a0bf528SMauro Carvalho Chehab 		status = SetDVBT(state, IFreqkHz, OffsetkHz);
19419a0bf528SMauro Carvalho Chehab 		if (status < 0)
19429a0bf528SMauro Carvalho Chehab 			goto error;
19439a0bf528SMauro Carvalho Chehab 		status = DVBTStart(state);
19449a0bf528SMauro Carvalho Chehab 		if (status < 0)
19459a0bf528SMauro Carvalho Chehab 			goto error;
19469a0bf528SMauro Carvalho Chehab 		state->m_DrxkState = DRXK_DTV_STARTED;
19479a0bf528SMauro Carvalho Chehab 		break;
19489a0bf528SMauro Carvalho Chehab 	default:
19499a0bf528SMauro Carvalho Chehab 		break;
19509a0bf528SMauro Carvalho Chehab 	}
19519a0bf528SMauro Carvalho Chehab error:
19529a0bf528SMauro Carvalho Chehab 	if (status < 0)
19539a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
19549a0bf528SMauro Carvalho Chehab 	return status;
19559a0bf528SMauro Carvalho Chehab }
19569a0bf528SMauro Carvalho Chehab 
19579a0bf528SMauro Carvalho Chehab static int ShutDown(struct drxk_state *state)
19589a0bf528SMauro Carvalho Chehab {
19599a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19609a0bf528SMauro Carvalho Chehab 
19619a0bf528SMauro Carvalho Chehab 	MPEGTSStop(state);
19629a0bf528SMauro Carvalho Chehab 	return 0;
19639a0bf528SMauro Carvalho Chehab }
19649a0bf528SMauro Carvalho Chehab 
19659a0bf528SMauro Carvalho Chehab static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
19669a0bf528SMauro Carvalho Chehab 			 u32 Time)
19679a0bf528SMauro Carvalho Chehab {
19689a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
19699a0bf528SMauro Carvalho Chehab 
19709a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
19719a0bf528SMauro Carvalho Chehab 
19729a0bf528SMauro Carvalho Chehab 	if (pLockStatus == NULL)
19739a0bf528SMauro Carvalho Chehab 		goto error;
19749a0bf528SMauro Carvalho Chehab 
19759a0bf528SMauro Carvalho Chehab 	*pLockStatus = NOT_LOCKED;
19769a0bf528SMauro Carvalho Chehab 
19779a0bf528SMauro Carvalho Chehab 	/* define the SCU command code */
19789a0bf528SMauro Carvalho Chehab 	switch (state->m_OperationMode) {
19799a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
19809a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_B:
19819a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
19829a0bf528SMauro Carvalho Chehab 		status = GetQAMLockStatus(state, pLockStatus);
19839a0bf528SMauro Carvalho Chehab 		break;
19849a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
19859a0bf528SMauro Carvalho Chehab 		status = GetDVBTLockStatus(state, pLockStatus);
19869a0bf528SMauro Carvalho Chehab 		break;
19879a0bf528SMauro Carvalho Chehab 	default:
19889a0bf528SMauro Carvalho Chehab 		break;
19899a0bf528SMauro Carvalho Chehab 	}
19909a0bf528SMauro Carvalho Chehab error:
19919a0bf528SMauro Carvalho Chehab 	if (status < 0)
19929a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
19939a0bf528SMauro Carvalho Chehab 	return status;
19949a0bf528SMauro Carvalho Chehab }
19959a0bf528SMauro Carvalho Chehab 
19969a0bf528SMauro Carvalho Chehab static int MPEGTSStart(struct drxk_state *state)
19979a0bf528SMauro Carvalho Chehab {
19989a0bf528SMauro Carvalho Chehab 	int status;
19999a0bf528SMauro Carvalho Chehab 
20009a0bf528SMauro Carvalho Chehab 	u16 fecOcSncMode = 0;
20019a0bf528SMauro Carvalho Chehab 
20029a0bf528SMauro Carvalho Chehab 	/* Allow OC to sync again */
20039a0bf528SMauro Carvalho Chehab 	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
20049a0bf528SMauro Carvalho Chehab 	if (status < 0)
20059a0bf528SMauro Carvalho Chehab 		goto error;
20069a0bf528SMauro Carvalho Chehab 	fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
20079a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
20089a0bf528SMauro Carvalho Chehab 	if (status < 0)
20099a0bf528SMauro Carvalho Chehab 		goto error;
20109a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
20119a0bf528SMauro Carvalho Chehab error:
20129a0bf528SMauro Carvalho Chehab 	if (status < 0)
20139a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
20149a0bf528SMauro Carvalho Chehab 	return status;
20159a0bf528SMauro Carvalho Chehab }
20169a0bf528SMauro Carvalho Chehab 
20179a0bf528SMauro Carvalho Chehab static int MPEGTSDtoInit(struct drxk_state *state)
20189a0bf528SMauro Carvalho Chehab {
20199a0bf528SMauro Carvalho Chehab 	int status;
20209a0bf528SMauro Carvalho Chehab 
20219a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
20229a0bf528SMauro Carvalho Chehab 
20239a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
20249a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
20259a0bf528SMauro Carvalho Chehab 	if (status < 0)
20269a0bf528SMauro Carvalho Chehab 		goto error;
20279a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
20289a0bf528SMauro Carvalho Chehab 	if (status < 0)
20299a0bf528SMauro Carvalho Chehab 		goto error;
20309a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
20319a0bf528SMauro Carvalho Chehab 	if (status < 0)
20329a0bf528SMauro Carvalho Chehab 		goto error;
20339a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
20349a0bf528SMauro Carvalho Chehab 	if (status < 0)
20359a0bf528SMauro Carvalho Chehab 		goto error;
20369a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
20379a0bf528SMauro Carvalho Chehab 	if (status < 0)
20389a0bf528SMauro Carvalho Chehab 		goto error;
20399a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
20409a0bf528SMauro Carvalho Chehab 	if (status < 0)
20419a0bf528SMauro Carvalho Chehab 		goto error;
20429a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
20439a0bf528SMauro Carvalho Chehab 	if (status < 0)
20449a0bf528SMauro Carvalho Chehab 		goto error;
20459a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
20469a0bf528SMauro Carvalho Chehab 	if (status < 0)
20479a0bf528SMauro Carvalho Chehab 		goto error;
20489a0bf528SMauro Carvalho Chehab 
20499a0bf528SMauro Carvalho Chehab 	/* Additional configuration */
20509a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_OCR_INVERT__A, 0);
20519a0bf528SMauro Carvalho Chehab 	if (status < 0)
20529a0bf528SMauro Carvalho Chehab 		goto error;
20539a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_LWM__A, 2);
20549a0bf528SMauro Carvalho Chehab 	if (status < 0)
20559a0bf528SMauro Carvalho Chehab 		goto error;
20569a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
20579a0bf528SMauro Carvalho Chehab error:
20589a0bf528SMauro Carvalho Chehab 	if (status < 0)
20599a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
20609a0bf528SMauro Carvalho Chehab 
20619a0bf528SMauro Carvalho Chehab 	return status;
20629a0bf528SMauro Carvalho Chehab }
20639a0bf528SMauro Carvalho Chehab 
20649a0bf528SMauro Carvalho Chehab static int MPEGTSDtoSetup(struct drxk_state *state,
20659a0bf528SMauro Carvalho Chehab 			  enum OperationMode oMode)
20669a0bf528SMauro Carvalho Chehab {
20679a0bf528SMauro Carvalho Chehab 	int status;
20689a0bf528SMauro Carvalho Chehab 
20699a0bf528SMauro Carvalho Chehab 	u16 fecOcRegMode = 0;	/* FEC_OC_MODE       register value */
20709a0bf528SMauro Carvalho Chehab 	u16 fecOcRegIprMode = 0;	/* FEC_OC_IPR_MODE   register value */
20719a0bf528SMauro Carvalho Chehab 	u16 fecOcDtoMode = 0;	/* FEC_OC_IPR_INVERT register value */
20729a0bf528SMauro Carvalho Chehab 	u16 fecOcFctMode = 0;	/* FEC_OC_IPR_INVERT register value */
20739a0bf528SMauro Carvalho Chehab 	u16 fecOcDtoPeriod = 2;	/* FEC_OC_IPR_INVERT register value */
20749a0bf528SMauro Carvalho Chehab 	u16 fecOcDtoBurstLen = 188;	/* FEC_OC_IPR_INVERT register value */
20759a0bf528SMauro Carvalho Chehab 	u32 fecOcRcnCtlRate = 0;	/* FEC_OC_IPR_INVERT register value */
20769a0bf528SMauro Carvalho Chehab 	u16 fecOcTmdMode = 0;
20779a0bf528SMauro Carvalho Chehab 	u16 fecOcTmdIntUpdRate = 0;
20789a0bf528SMauro Carvalho Chehab 	u32 maxBitRate = 0;
20799a0bf528SMauro Carvalho Chehab 	bool staticCLK = false;
20809a0bf528SMauro Carvalho Chehab 
20819a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
20829a0bf528SMauro Carvalho Chehab 
20839a0bf528SMauro Carvalho Chehab 	/* Check insertion of the Reed-Solomon parity bytes */
20849a0bf528SMauro Carvalho Chehab 	status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
20859a0bf528SMauro Carvalho Chehab 	if (status < 0)
20869a0bf528SMauro Carvalho Chehab 		goto error;
20879a0bf528SMauro Carvalho Chehab 	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
20889a0bf528SMauro Carvalho Chehab 	if (status < 0)
20899a0bf528SMauro Carvalho Chehab 		goto error;
20909a0bf528SMauro Carvalho Chehab 	fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
20919a0bf528SMauro Carvalho Chehab 	fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
20929a0bf528SMauro Carvalho Chehab 	if (state->m_insertRSByte == true) {
20939a0bf528SMauro Carvalho Chehab 		/* enable parity symbol forward */
20949a0bf528SMauro Carvalho Chehab 		fecOcRegMode |= FEC_OC_MODE_PARITY__M;
20959a0bf528SMauro Carvalho Chehab 		/* MVAL disable during parity bytes */
20969a0bf528SMauro Carvalho Chehab 		fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
20979a0bf528SMauro Carvalho Chehab 		/* TS burst length to 204 */
20989a0bf528SMauro Carvalho Chehab 		fecOcDtoBurstLen = 204;
20999a0bf528SMauro Carvalho Chehab 	}
21009a0bf528SMauro Carvalho Chehab 
21019a0bf528SMauro Carvalho Chehab 	/* Check serial or parrallel output */
21029a0bf528SMauro Carvalho Chehab 	fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
21039a0bf528SMauro Carvalho Chehab 	if (state->m_enableParallel == false) {
21049a0bf528SMauro Carvalho Chehab 		/* MPEG data output is serial -> set ipr_mode[0] */
21059a0bf528SMauro Carvalho Chehab 		fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
21069a0bf528SMauro Carvalho Chehab 	}
21079a0bf528SMauro Carvalho Chehab 
21089a0bf528SMauro Carvalho Chehab 	switch (oMode) {
21099a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
21109a0bf528SMauro Carvalho Chehab 		maxBitRate = state->m_DVBTBitrate;
21119a0bf528SMauro Carvalho Chehab 		fecOcTmdMode = 3;
21129a0bf528SMauro Carvalho Chehab 		fecOcRcnCtlRate = 0xC00000;
21139a0bf528SMauro Carvalho Chehab 		staticCLK = state->m_DVBTStaticCLK;
21149a0bf528SMauro Carvalho Chehab 		break;
21159a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:	/* fallthrough */
21169a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
21179a0bf528SMauro Carvalho Chehab 		fecOcTmdMode = 0x0004;
21189a0bf528SMauro Carvalho Chehab 		fecOcRcnCtlRate = 0xD2B4EE;	/* good for >63 Mb/s */
21199a0bf528SMauro Carvalho Chehab 		maxBitRate = state->m_DVBCBitrate;
21209a0bf528SMauro Carvalho Chehab 		staticCLK = state->m_DVBCStaticCLK;
21219a0bf528SMauro Carvalho Chehab 		break;
21229a0bf528SMauro Carvalho Chehab 	default:
21239a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
21249a0bf528SMauro Carvalho Chehab 	}		/* switch (standard) */
21259a0bf528SMauro Carvalho Chehab 	if (status < 0)
21269a0bf528SMauro Carvalho Chehab 		goto error;
21279a0bf528SMauro Carvalho Chehab 
21289a0bf528SMauro Carvalho Chehab 	/* Configure DTO's */
21299a0bf528SMauro Carvalho Chehab 	if (staticCLK) {
21309a0bf528SMauro Carvalho Chehab 		u32 bitRate = 0;
21319a0bf528SMauro Carvalho Chehab 
21329a0bf528SMauro Carvalho Chehab 		/* Rational DTO for MCLK source (static MCLK rate),
21339a0bf528SMauro Carvalho Chehab 			Dynamic DTO for optimal grouping
21349a0bf528SMauro Carvalho Chehab 			(avoid intra-packet gaps),
21359a0bf528SMauro Carvalho Chehab 			DTO offset enable to sync TS burst with MSTRT */
21369a0bf528SMauro Carvalho Chehab 		fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
21379a0bf528SMauro Carvalho Chehab 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
21389a0bf528SMauro Carvalho Chehab 		fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
21399a0bf528SMauro Carvalho Chehab 				FEC_OC_FCT_MODE_VIRT_ENA__M);
21409a0bf528SMauro Carvalho Chehab 
21419a0bf528SMauro Carvalho Chehab 		/* Check user defined bitrate */
21429a0bf528SMauro Carvalho Chehab 		bitRate = maxBitRate;
21439a0bf528SMauro Carvalho Chehab 		if (bitRate > 75900000UL) {	/* max is 75.9 Mb/s */
21449a0bf528SMauro Carvalho Chehab 			bitRate = 75900000UL;
21459a0bf528SMauro Carvalho Chehab 		}
21469a0bf528SMauro Carvalho Chehab 		/* Rational DTO period:
21479a0bf528SMauro Carvalho Chehab 			dto_period = (Fsys / bitrate) - 2
21489a0bf528SMauro Carvalho Chehab 
21499a0bf528SMauro Carvalho Chehab 			Result should be floored,
21509a0bf528SMauro Carvalho Chehab 			to make sure >= requested bitrate
21519a0bf528SMauro Carvalho Chehab 			*/
21529a0bf528SMauro Carvalho Chehab 		fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
21539a0bf528SMauro Carvalho Chehab 						* 1000) / bitRate);
21549a0bf528SMauro Carvalho Chehab 		if (fecOcDtoPeriod <= 2)
21559a0bf528SMauro Carvalho Chehab 			fecOcDtoPeriod = 0;
21569a0bf528SMauro Carvalho Chehab 		else
21579a0bf528SMauro Carvalho Chehab 			fecOcDtoPeriod -= 2;
21589a0bf528SMauro Carvalho Chehab 		fecOcTmdIntUpdRate = 8;
21599a0bf528SMauro Carvalho Chehab 	} else {
21609a0bf528SMauro Carvalho Chehab 		/* (commonAttr->staticCLK == false) => dynamic mode */
21619a0bf528SMauro Carvalho Chehab 		fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
21629a0bf528SMauro Carvalho Chehab 		fecOcFctMode = FEC_OC_FCT_MODE__PRE;
21639a0bf528SMauro Carvalho Chehab 		fecOcTmdIntUpdRate = 5;
21649a0bf528SMauro Carvalho Chehab 	}
21659a0bf528SMauro Carvalho Chehab 
21669a0bf528SMauro Carvalho Chehab 	/* Write appropriate registers with requested configuration */
21679a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
21689a0bf528SMauro Carvalho Chehab 	if (status < 0)
21699a0bf528SMauro Carvalho Chehab 		goto error;
21709a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
21719a0bf528SMauro Carvalho Chehab 	if (status < 0)
21729a0bf528SMauro Carvalho Chehab 		goto error;
21739a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
21749a0bf528SMauro Carvalho Chehab 	if (status < 0)
21759a0bf528SMauro Carvalho Chehab 		goto error;
21769a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
21779a0bf528SMauro Carvalho Chehab 	if (status < 0)
21789a0bf528SMauro Carvalho Chehab 		goto error;
21799a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
21809a0bf528SMauro Carvalho Chehab 	if (status < 0)
21819a0bf528SMauro Carvalho Chehab 		goto error;
21829a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
21839a0bf528SMauro Carvalho Chehab 	if (status < 0)
21849a0bf528SMauro Carvalho Chehab 		goto error;
21859a0bf528SMauro Carvalho Chehab 
21869a0bf528SMauro Carvalho Chehab 	/* Rate integration settings */
21879a0bf528SMauro Carvalho Chehab 	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
21889a0bf528SMauro Carvalho Chehab 	if (status < 0)
21899a0bf528SMauro Carvalho Chehab 		goto error;
21909a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
21919a0bf528SMauro Carvalho Chehab 	if (status < 0)
21929a0bf528SMauro Carvalho Chehab 		goto error;
21939a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
21949a0bf528SMauro Carvalho Chehab error:
21959a0bf528SMauro Carvalho Chehab 	if (status < 0)
21969a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
21979a0bf528SMauro Carvalho Chehab 	return status;
21989a0bf528SMauro Carvalho Chehab }
21999a0bf528SMauro Carvalho Chehab 
22009a0bf528SMauro Carvalho Chehab static int MPEGTSConfigurePolarity(struct drxk_state *state)
22019a0bf528SMauro Carvalho Chehab {
22029a0bf528SMauro Carvalho Chehab 	u16 fecOcRegIprInvert = 0;
22039a0bf528SMauro Carvalho Chehab 
22049a0bf528SMauro Carvalho Chehab 	/* Data mask for the output data byte */
22059a0bf528SMauro Carvalho Chehab 	u16 InvertDataMask =
22069a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
22079a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
22089a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
22099a0bf528SMauro Carvalho Chehab 	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
22109a0bf528SMauro Carvalho Chehab 
22119a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
22129a0bf528SMauro Carvalho Chehab 
22139a0bf528SMauro Carvalho Chehab 	/* Control selective inversion of output bits */
22149a0bf528SMauro Carvalho Chehab 	fecOcRegIprInvert &= (~(InvertDataMask));
22159a0bf528SMauro Carvalho Chehab 	if (state->m_invertDATA == true)
22169a0bf528SMauro Carvalho Chehab 		fecOcRegIprInvert |= InvertDataMask;
22179a0bf528SMauro Carvalho Chehab 	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
22189a0bf528SMauro Carvalho Chehab 	if (state->m_invertERR == true)
22199a0bf528SMauro Carvalho Chehab 		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
22209a0bf528SMauro Carvalho Chehab 	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
22219a0bf528SMauro Carvalho Chehab 	if (state->m_invertSTR == true)
22229a0bf528SMauro Carvalho Chehab 		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
22239a0bf528SMauro Carvalho Chehab 	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
22249a0bf528SMauro Carvalho Chehab 	if (state->m_invertVAL == true)
22259a0bf528SMauro Carvalho Chehab 		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
22269a0bf528SMauro Carvalho Chehab 	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
22279a0bf528SMauro Carvalho Chehab 	if (state->m_invertCLK == true)
22289a0bf528SMauro Carvalho Chehab 		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
22299a0bf528SMauro Carvalho Chehab 
22309a0bf528SMauro Carvalho Chehab 	return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
22319a0bf528SMauro Carvalho Chehab }
22329a0bf528SMauro Carvalho Chehab 
22339a0bf528SMauro Carvalho Chehab #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
22349a0bf528SMauro Carvalho Chehab 
22359a0bf528SMauro Carvalho Chehab static int SetAgcRf(struct drxk_state *state,
22369a0bf528SMauro Carvalho Chehab 		    struct SCfgAgc *pAgcCfg, bool isDTV)
22379a0bf528SMauro Carvalho Chehab {
22389a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
22399a0bf528SMauro Carvalho Chehab 	u16 data = 0;
22409a0bf528SMauro Carvalho Chehab 	struct SCfgAgc *pIfAgcSettings;
22419a0bf528SMauro Carvalho Chehab 
22429a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
22439a0bf528SMauro Carvalho Chehab 
22449a0bf528SMauro Carvalho Chehab 	if (pAgcCfg == NULL)
22459a0bf528SMauro Carvalho Chehab 		goto error;
22469a0bf528SMauro Carvalho Chehab 
22479a0bf528SMauro Carvalho Chehab 	switch (pAgcCfg->ctrlMode) {
22489a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
22499a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
22509a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
22519a0bf528SMauro Carvalho Chehab 		if (status < 0)
22529a0bf528SMauro Carvalho Chehab 			goto error;
22539a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22549a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
22559a0bf528SMauro Carvalho Chehab 		if (status < 0)
22569a0bf528SMauro Carvalho Chehab 			goto error;
22579a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22589a0bf528SMauro Carvalho Chehab 		if (status < 0)
22599a0bf528SMauro Carvalho Chehab 			goto error;
22609a0bf528SMauro Carvalho Chehab 
22619a0bf528SMauro Carvalho Chehab 		/* Enable SCU RF AGC loop */
22629a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22639a0bf528SMauro Carvalho Chehab 
22649a0bf528SMauro Carvalho Chehab 		/* Polarity */
22659a0bf528SMauro Carvalho Chehab 		if (state->m_RfAgcPol)
22669a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22679a0bf528SMauro Carvalho Chehab 		else
22689a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22699a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22709a0bf528SMauro Carvalho Chehab 		if (status < 0)
22719a0bf528SMauro Carvalho Chehab 			goto error;
22729a0bf528SMauro Carvalho Chehab 
22739a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
22749a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
22759a0bf528SMauro Carvalho Chehab 		if (status < 0)
22769a0bf528SMauro Carvalho Chehab 			goto error;
22779a0bf528SMauro Carvalho Chehab 
22789a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
22799a0bf528SMauro Carvalho Chehab 		data |= (~(pAgcCfg->speed <<
22809a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
22819a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
22829a0bf528SMauro Carvalho Chehab 
22839a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
22849a0bf528SMauro Carvalho Chehab 		if (status < 0)
22859a0bf528SMauro Carvalho Chehab 			goto error;
22869a0bf528SMauro Carvalho Chehab 
22879a0bf528SMauro Carvalho Chehab 		if (IsDVBT(state))
22889a0bf528SMauro Carvalho Chehab 			pIfAgcSettings = &state->m_dvbtIfAgcCfg;
22899a0bf528SMauro Carvalho Chehab 		else if (IsQAM(state))
22909a0bf528SMauro Carvalho Chehab 			pIfAgcSettings = &state->m_qamIfAgcCfg;
22919a0bf528SMauro Carvalho Chehab 		else
22929a0bf528SMauro Carvalho Chehab 			pIfAgcSettings = &state->m_atvIfAgcCfg;
22939a0bf528SMauro Carvalho Chehab 		if (pIfAgcSettings == NULL) {
22949a0bf528SMauro Carvalho Chehab 			status = -EINVAL;
22959a0bf528SMauro Carvalho Chehab 			goto error;
22969a0bf528SMauro Carvalho Chehab 		}
22979a0bf528SMauro Carvalho Chehab 
22989a0bf528SMauro Carvalho Chehab 		/* Set TOP, only if IF-AGC is in AUTO mode */
22999a0bf528SMauro Carvalho Chehab 		if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
23009a0bf528SMauro Carvalho Chehab 			status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
23019a0bf528SMauro Carvalho Chehab 			if (status < 0)
23029a0bf528SMauro Carvalho Chehab 				goto error;
23039a0bf528SMauro Carvalho Chehab 
23049a0bf528SMauro Carvalho Chehab 		/* Cut-Off current */
23059a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
23069a0bf528SMauro Carvalho Chehab 		if (status < 0)
23079a0bf528SMauro Carvalho Chehab 			goto error;
23089a0bf528SMauro Carvalho Chehab 
23099a0bf528SMauro Carvalho Chehab 		/* Max. output level */
23109a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
23119a0bf528SMauro Carvalho Chehab 		if (status < 0)
23129a0bf528SMauro Carvalho Chehab 			goto error;
23139a0bf528SMauro Carvalho Chehab 
23149a0bf528SMauro Carvalho Chehab 		break;
23159a0bf528SMauro Carvalho Chehab 
23169a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
23179a0bf528SMauro Carvalho Chehab 		/* Enable RF AGC DAC */
23189a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23199a0bf528SMauro Carvalho Chehab 		if (status < 0)
23209a0bf528SMauro Carvalho Chehab 			goto error;
23219a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
23229a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23239a0bf528SMauro Carvalho Chehab 		if (status < 0)
23249a0bf528SMauro Carvalho Chehab 			goto error;
23259a0bf528SMauro Carvalho Chehab 
23269a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
23279a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23289a0bf528SMauro Carvalho Chehab 		if (status < 0)
23299a0bf528SMauro Carvalho Chehab 			goto error;
23309a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
23319a0bf528SMauro Carvalho Chehab 		if (state->m_RfAgcPol)
23329a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
23339a0bf528SMauro Carvalho Chehab 		else
23349a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
23359a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23369a0bf528SMauro Carvalho Chehab 		if (status < 0)
23379a0bf528SMauro Carvalho Chehab 			goto error;
23389a0bf528SMauro Carvalho Chehab 
23399a0bf528SMauro Carvalho Chehab 		/* SCU c.o.c. to 0, enabling full control range */
23409a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
23419a0bf528SMauro Carvalho Chehab 		if (status < 0)
23429a0bf528SMauro Carvalho Chehab 			goto error;
23439a0bf528SMauro Carvalho Chehab 
23449a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
23459a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
23469a0bf528SMauro Carvalho Chehab 		if (status < 0)
23479a0bf528SMauro Carvalho Chehab 			goto error;
23489a0bf528SMauro Carvalho Chehab 		break;
23499a0bf528SMauro Carvalho Chehab 
23509a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
23519a0bf528SMauro Carvalho Chehab 		/* Disable RF AGC DAC */
23529a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23539a0bf528SMauro Carvalho Chehab 		if (status < 0)
23549a0bf528SMauro Carvalho Chehab 			goto error;
23559a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
23569a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
23579a0bf528SMauro Carvalho Chehab 		if (status < 0)
23589a0bf528SMauro Carvalho Chehab 			goto error;
23599a0bf528SMauro Carvalho Chehab 
23609a0bf528SMauro Carvalho Chehab 		/* Disable SCU RF AGC loop */
23619a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23629a0bf528SMauro Carvalho Chehab 		if (status < 0)
23639a0bf528SMauro Carvalho Chehab 			goto error;
23649a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
23659a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23669a0bf528SMauro Carvalho Chehab 		if (status < 0)
23679a0bf528SMauro Carvalho Chehab 			goto error;
23689a0bf528SMauro Carvalho Chehab 		break;
23699a0bf528SMauro Carvalho Chehab 
23709a0bf528SMauro Carvalho Chehab 	default:
23719a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
23729a0bf528SMauro Carvalho Chehab 
23739a0bf528SMauro Carvalho Chehab 	}
23749a0bf528SMauro Carvalho Chehab error:
23759a0bf528SMauro Carvalho Chehab 	if (status < 0)
23769a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
23779a0bf528SMauro Carvalho Chehab 	return status;
23789a0bf528SMauro Carvalho Chehab }
23799a0bf528SMauro Carvalho Chehab 
23809a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
23819a0bf528SMauro Carvalho Chehab 
23829a0bf528SMauro Carvalho Chehab static int SetAgcIf(struct drxk_state *state,
23839a0bf528SMauro Carvalho Chehab 		    struct SCfgAgc *pAgcCfg, bool isDTV)
23849a0bf528SMauro Carvalho Chehab {
23859a0bf528SMauro Carvalho Chehab 	u16 data = 0;
23869a0bf528SMauro Carvalho Chehab 	int status = 0;
23879a0bf528SMauro Carvalho Chehab 	struct SCfgAgc *pRfAgcSettings;
23889a0bf528SMauro Carvalho Chehab 
23899a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
23909a0bf528SMauro Carvalho Chehab 
23919a0bf528SMauro Carvalho Chehab 	switch (pAgcCfg->ctrlMode) {
23929a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_AUTO:
23939a0bf528SMauro Carvalho Chehab 
23949a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
23959a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
23969a0bf528SMauro Carvalho Chehab 		if (status < 0)
23979a0bf528SMauro Carvalho Chehab 			goto error;
23989a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23999a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
24009a0bf528SMauro Carvalho Chehab 		if (status < 0)
24019a0bf528SMauro Carvalho Chehab 			goto error;
24029a0bf528SMauro Carvalho Chehab 
24039a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
24049a0bf528SMauro Carvalho Chehab 		if (status < 0)
24059a0bf528SMauro Carvalho Chehab 			goto error;
24069a0bf528SMauro Carvalho Chehab 
24079a0bf528SMauro Carvalho Chehab 		/* Enable SCU IF AGC loop */
24089a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24099a0bf528SMauro Carvalho Chehab 
24109a0bf528SMauro Carvalho Chehab 		/* Polarity */
24119a0bf528SMauro Carvalho Chehab 		if (state->m_IfAgcPol)
24129a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
24139a0bf528SMauro Carvalho Chehab 		else
24149a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
24159a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24169a0bf528SMauro Carvalho Chehab 		if (status < 0)
24179a0bf528SMauro Carvalho Chehab 			goto error;
24189a0bf528SMauro Carvalho Chehab 
24199a0bf528SMauro Carvalho Chehab 		/* Set speed (using complementary reduction value) */
24209a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
24219a0bf528SMauro Carvalho Chehab 		if (status < 0)
24229a0bf528SMauro Carvalho Chehab 			goto error;
24239a0bf528SMauro Carvalho Chehab 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
24249a0bf528SMauro Carvalho Chehab 		data |= (~(pAgcCfg->speed <<
24259a0bf528SMauro Carvalho Chehab 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
24269a0bf528SMauro Carvalho Chehab 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
24279a0bf528SMauro Carvalho Chehab 
24289a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
24299a0bf528SMauro Carvalho Chehab 		if (status < 0)
24309a0bf528SMauro Carvalho Chehab 			goto error;
24319a0bf528SMauro Carvalho Chehab 
24329a0bf528SMauro Carvalho Chehab 		if (IsQAM(state))
24339a0bf528SMauro Carvalho Chehab 			pRfAgcSettings = &state->m_qamRfAgcCfg;
24349a0bf528SMauro Carvalho Chehab 		else
24359a0bf528SMauro Carvalho Chehab 			pRfAgcSettings = &state->m_atvRfAgcCfg;
24369a0bf528SMauro Carvalho Chehab 		if (pRfAgcSettings == NULL)
24379a0bf528SMauro Carvalho Chehab 			return -1;
24389a0bf528SMauro Carvalho Chehab 		/* Restore TOP */
24399a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
24409a0bf528SMauro Carvalho Chehab 		if (status < 0)
24419a0bf528SMauro Carvalho Chehab 			goto error;
24429a0bf528SMauro Carvalho Chehab 		break;
24439a0bf528SMauro Carvalho Chehab 
24449a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_USER:
24459a0bf528SMauro Carvalho Chehab 
24469a0bf528SMauro Carvalho Chehab 		/* Enable IF AGC DAC */
24479a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
24489a0bf528SMauro Carvalho Chehab 		if (status < 0)
24499a0bf528SMauro Carvalho Chehab 			goto error;
24509a0bf528SMauro Carvalho Chehab 		data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
24519a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
24529a0bf528SMauro Carvalho Chehab 		if (status < 0)
24539a0bf528SMauro Carvalho Chehab 			goto error;
24549a0bf528SMauro Carvalho Chehab 
24559a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
24569a0bf528SMauro Carvalho Chehab 		if (status < 0)
24579a0bf528SMauro Carvalho Chehab 			goto error;
24589a0bf528SMauro Carvalho Chehab 
24599a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
24609a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24619a0bf528SMauro Carvalho Chehab 
24629a0bf528SMauro Carvalho Chehab 		/* Polarity */
24639a0bf528SMauro Carvalho Chehab 		if (state->m_IfAgcPol)
24649a0bf528SMauro Carvalho Chehab 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
24659a0bf528SMauro Carvalho Chehab 		else
24669a0bf528SMauro Carvalho Chehab 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
24679a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24689a0bf528SMauro Carvalho Chehab 		if (status < 0)
24699a0bf528SMauro Carvalho Chehab 			goto error;
24709a0bf528SMauro Carvalho Chehab 
24719a0bf528SMauro Carvalho Chehab 		/* Write value to output pin */
24729a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
24739a0bf528SMauro Carvalho Chehab 		if (status < 0)
24749a0bf528SMauro Carvalho Chehab 			goto error;
24759a0bf528SMauro Carvalho Chehab 		break;
24769a0bf528SMauro Carvalho Chehab 
24779a0bf528SMauro Carvalho Chehab 	case DRXK_AGC_CTRL_OFF:
24789a0bf528SMauro Carvalho Chehab 
24799a0bf528SMauro Carvalho Chehab 		/* Disable If AGC DAC */
24809a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_STDBY__A, &data);
24819a0bf528SMauro Carvalho Chehab 		if (status < 0)
24829a0bf528SMauro Carvalho Chehab 			goto error;
24839a0bf528SMauro Carvalho Chehab 		data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
24849a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_STDBY__A, data);
24859a0bf528SMauro Carvalho Chehab 		if (status < 0)
24869a0bf528SMauro Carvalho Chehab 			goto error;
24879a0bf528SMauro Carvalho Chehab 
24889a0bf528SMauro Carvalho Chehab 		/* Disable SCU IF AGC loop */
24899a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
24909a0bf528SMauro Carvalho Chehab 		if (status < 0)
24919a0bf528SMauro Carvalho Chehab 			goto error;
24929a0bf528SMauro Carvalho Chehab 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
24939a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
24949a0bf528SMauro Carvalho Chehab 		if (status < 0)
24959a0bf528SMauro Carvalho Chehab 			goto error;
24969a0bf528SMauro Carvalho Chehab 		break;
24979a0bf528SMauro Carvalho Chehab 	}		/* switch (agcSettingsIf->ctrlMode) */
24989a0bf528SMauro Carvalho Chehab 
24999a0bf528SMauro Carvalho Chehab 	/* always set the top to support
25009a0bf528SMauro Carvalho Chehab 		configurations without if-loop */
25019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
25029a0bf528SMauro Carvalho Chehab error:
25039a0bf528SMauro Carvalho Chehab 	if (status < 0)
25049a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
25059a0bf528SMauro Carvalho Chehab 	return status;
25069a0bf528SMauro Carvalho Chehab }
25079a0bf528SMauro Carvalho Chehab 
25089a0bf528SMauro Carvalho Chehab static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
25099a0bf528SMauro Carvalho Chehab {
25109a0bf528SMauro Carvalho Chehab 	u16 agcDacLvl;
25119a0bf528SMauro Carvalho Chehab 	int status;
25129a0bf528SMauro Carvalho Chehab 	u16 Level = 0;
25139a0bf528SMauro Carvalho Chehab 
25149a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25159a0bf528SMauro Carvalho Chehab 
25169a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
25179a0bf528SMauro Carvalho Chehab 	if (status < 0) {
25189a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
25199a0bf528SMauro Carvalho Chehab 		return status;
25209a0bf528SMauro Carvalho Chehab 	}
25219a0bf528SMauro Carvalho Chehab 
25229a0bf528SMauro Carvalho Chehab 	*pValue = 0;
25239a0bf528SMauro Carvalho Chehab 
25249a0bf528SMauro Carvalho Chehab 	if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
25259a0bf528SMauro Carvalho Chehab 		Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
25269a0bf528SMauro Carvalho Chehab 	if (Level < 14000)
25279a0bf528SMauro Carvalho Chehab 		*pValue = (14000 - Level) / 4;
25289a0bf528SMauro Carvalho Chehab 	else
25299a0bf528SMauro Carvalho Chehab 		*pValue = 0;
25309a0bf528SMauro Carvalho Chehab 
25319a0bf528SMauro Carvalho Chehab 	return status;
25329a0bf528SMauro Carvalho Chehab }
25339a0bf528SMauro Carvalho Chehab 
25349a0bf528SMauro Carvalho Chehab static int GetQAMSignalToNoise(struct drxk_state *state,
25359a0bf528SMauro Carvalho Chehab 			       s32 *pSignalToNoise)
25369a0bf528SMauro Carvalho Chehab {
25379a0bf528SMauro Carvalho Chehab 	int status = 0;
25389a0bf528SMauro Carvalho Chehab 	u16 qamSlErrPower = 0;	/* accum. error between
25399a0bf528SMauro Carvalho Chehab 					raw and sliced symbols */
25409a0bf528SMauro Carvalho Chehab 	u32 qamSlSigPower = 0;	/* used for MER, depends of
25419a0bf528SMauro Carvalho Chehab 					QAM modulation */
25429a0bf528SMauro Carvalho Chehab 	u32 qamSlMer = 0;	/* QAM MER */
25439a0bf528SMauro Carvalho Chehab 
25449a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
25459a0bf528SMauro Carvalho Chehab 
25469a0bf528SMauro Carvalho Chehab 	/* MER calculation */
25479a0bf528SMauro Carvalho Chehab 
25489a0bf528SMauro Carvalho Chehab 	/* get the register value needed for MER */
25499a0bf528SMauro Carvalho Chehab 	status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
25509a0bf528SMauro Carvalho Chehab 	if (status < 0) {
25519a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
25529a0bf528SMauro Carvalho Chehab 		return -EINVAL;
25539a0bf528SMauro Carvalho Chehab 	}
25549a0bf528SMauro Carvalho Chehab 
25559a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
25569a0bf528SMauro Carvalho Chehab 	case QAM_16:
25579a0bf528SMauro Carvalho Chehab 		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
25589a0bf528SMauro Carvalho Chehab 		break;
25599a0bf528SMauro Carvalho Chehab 	case QAM_32:
25609a0bf528SMauro Carvalho Chehab 		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
25619a0bf528SMauro Carvalho Chehab 		break;
25629a0bf528SMauro Carvalho Chehab 	case QAM_64:
25639a0bf528SMauro Carvalho Chehab 		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
25649a0bf528SMauro Carvalho Chehab 		break;
25659a0bf528SMauro Carvalho Chehab 	case QAM_128:
25669a0bf528SMauro Carvalho Chehab 		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
25679a0bf528SMauro Carvalho Chehab 		break;
25689a0bf528SMauro Carvalho Chehab 	default:
25699a0bf528SMauro Carvalho Chehab 	case QAM_256:
25709a0bf528SMauro Carvalho Chehab 		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
25719a0bf528SMauro Carvalho Chehab 		break;
25729a0bf528SMauro Carvalho Chehab 	}
25739a0bf528SMauro Carvalho Chehab 
25749a0bf528SMauro Carvalho Chehab 	if (qamSlErrPower > 0) {
25759a0bf528SMauro Carvalho Chehab 		qamSlMer = Log10Times100(qamSlSigPower) -
25769a0bf528SMauro Carvalho Chehab 			Log10Times100((u32) qamSlErrPower);
25779a0bf528SMauro Carvalho Chehab 	}
25789a0bf528SMauro Carvalho Chehab 	*pSignalToNoise = qamSlMer;
25799a0bf528SMauro Carvalho Chehab 
25809a0bf528SMauro Carvalho Chehab 	return status;
25819a0bf528SMauro Carvalho Chehab }
25829a0bf528SMauro Carvalho Chehab 
25839a0bf528SMauro Carvalho Chehab static int GetDVBTSignalToNoise(struct drxk_state *state,
25849a0bf528SMauro Carvalho Chehab 				s32 *pSignalToNoise)
25859a0bf528SMauro Carvalho Chehab {
25869a0bf528SMauro Carvalho Chehab 	int status;
25879a0bf528SMauro Carvalho Chehab 	u16 regData = 0;
25889a0bf528SMauro Carvalho Chehab 	u32 EqRegTdSqrErrI = 0;
25899a0bf528SMauro Carvalho Chehab 	u32 EqRegTdSqrErrQ = 0;
25909a0bf528SMauro Carvalho Chehab 	u16 EqRegTdSqrErrExp = 0;
25919a0bf528SMauro Carvalho Chehab 	u16 EqRegTdTpsPwrOfs = 0;
25929a0bf528SMauro Carvalho Chehab 	u16 EqRegTdReqSmbCnt = 0;
25939a0bf528SMauro Carvalho Chehab 	u32 tpsCnt = 0;
25949a0bf528SMauro Carvalho Chehab 	u32 SqrErrIQ = 0;
25959a0bf528SMauro Carvalho Chehab 	u32 a = 0;
25969a0bf528SMauro Carvalho Chehab 	u32 b = 0;
25979a0bf528SMauro Carvalho Chehab 	u32 c = 0;
25989a0bf528SMauro Carvalho Chehab 	u32 iMER = 0;
25999a0bf528SMauro Carvalho Chehab 	u16 transmissionParams = 0;
26009a0bf528SMauro Carvalho Chehab 
26019a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26029a0bf528SMauro Carvalho Chehab 
26039a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
26049a0bf528SMauro Carvalho Chehab 	if (status < 0)
26059a0bf528SMauro Carvalho Chehab 		goto error;
26069a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
26079a0bf528SMauro Carvalho Chehab 	if (status < 0)
26089a0bf528SMauro Carvalho Chehab 		goto error;
26099a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
26109a0bf528SMauro Carvalho Chehab 	if (status < 0)
26119a0bf528SMauro Carvalho Chehab 		goto error;
26129a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
26139a0bf528SMauro Carvalho Chehab 	if (status < 0)
26149a0bf528SMauro Carvalho Chehab 		goto error;
26159a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_I operational range */
26169a0bf528SMauro Carvalho Chehab 	EqRegTdSqrErrI = (u32) regData;
26179a0bf528SMauro Carvalho Chehab 	if ((EqRegTdSqrErrExp > 11) &&
26189a0bf528SMauro Carvalho Chehab 		(EqRegTdSqrErrI < 0x00000FFFUL)) {
26199a0bf528SMauro Carvalho Chehab 		EqRegTdSqrErrI += 0x00010000UL;
26209a0bf528SMauro Carvalho Chehab 	}
26219a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
26229a0bf528SMauro Carvalho Chehab 	if (status < 0)
26239a0bf528SMauro Carvalho Chehab 		goto error;
26249a0bf528SMauro Carvalho Chehab 	/* Extend SQR_ERR_Q operational range */
26259a0bf528SMauro Carvalho Chehab 	EqRegTdSqrErrQ = (u32) regData;
26269a0bf528SMauro Carvalho Chehab 	if ((EqRegTdSqrErrExp > 11) &&
26279a0bf528SMauro Carvalho Chehab 		(EqRegTdSqrErrQ < 0x00000FFFUL))
26289a0bf528SMauro Carvalho Chehab 		EqRegTdSqrErrQ += 0x00010000UL;
26299a0bf528SMauro Carvalho Chehab 
26309a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
26319a0bf528SMauro Carvalho Chehab 	if (status < 0)
26329a0bf528SMauro Carvalho Chehab 		goto error;
26339a0bf528SMauro Carvalho Chehab 
26349a0bf528SMauro Carvalho Chehab 	/* Check input data for MER */
26359a0bf528SMauro Carvalho Chehab 
26369a0bf528SMauro Carvalho Chehab 	/* MER calculation (in 0.1 dB) without math.h */
26379a0bf528SMauro Carvalho Chehab 	if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
26389a0bf528SMauro Carvalho Chehab 		iMER = 0;
26399a0bf528SMauro Carvalho Chehab 	else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
26409a0bf528SMauro Carvalho Chehab 		/* No error at all, this must be the HW reset value
26419a0bf528SMauro Carvalho Chehab 			* Apparently no first measurement yet
26429a0bf528SMauro Carvalho Chehab 			* Set MER to 0.0 */
26439a0bf528SMauro Carvalho Chehab 		iMER = 0;
26449a0bf528SMauro Carvalho Chehab 	} else {
26459a0bf528SMauro Carvalho Chehab 		SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
26469a0bf528SMauro Carvalho Chehab 			EqRegTdSqrErrExp;
26479a0bf528SMauro Carvalho Chehab 		if ((transmissionParams &
26489a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
26499a0bf528SMauro Carvalho Chehab 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
26509a0bf528SMauro Carvalho Chehab 			tpsCnt = 17;
26519a0bf528SMauro Carvalho Chehab 		else
26529a0bf528SMauro Carvalho Chehab 			tpsCnt = 68;
26539a0bf528SMauro Carvalho Chehab 
26549a0bf528SMauro Carvalho Chehab 		/* IMER = 100 * log10 (x)
26559a0bf528SMauro Carvalho Chehab 			where x = (EqRegTdTpsPwrOfs^2 *
26569a0bf528SMauro Carvalho Chehab 			EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
26579a0bf528SMauro Carvalho Chehab 
26589a0bf528SMauro Carvalho Chehab 			=> IMER = a + b -c
26599a0bf528SMauro Carvalho Chehab 			where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
26609a0bf528SMauro Carvalho Chehab 			b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
26619a0bf528SMauro Carvalho Chehab 			c = 100 * log10 (SqrErrIQ)
26629a0bf528SMauro Carvalho Chehab 			*/
26639a0bf528SMauro Carvalho Chehab 
26649a0bf528SMauro Carvalho Chehab 		/* log(x) x = 9bits * 9bits->18 bits  */
26659a0bf528SMauro Carvalho Chehab 		a = Log10Times100(EqRegTdTpsPwrOfs *
26669a0bf528SMauro Carvalho Chehab 					EqRegTdTpsPwrOfs);
26679a0bf528SMauro Carvalho Chehab 		/* log(x) x = 16bits * 7bits->23 bits  */
26689a0bf528SMauro Carvalho Chehab 		b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
26699a0bf528SMauro Carvalho Chehab 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
26709a0bf528SMauro Carvalho Chehab 		c = Log10Times100(SqrErrIQ);
26719a0bf528SMauro Carvalho Chehab 
26729a0bf528SMauro Carvalho Chehab 		iMER = a + b;
26739a0bf528SMauro Carvalho Chehab 		/* No negative MER, clip to zero */
26749a0bf528SMauro Carvalho Chehab 		if (iMER > c)
26759a0bf528SMauro Carvalho Chehab 			iMER -= c;
26769a0bf528SMauro Carvalho Chehab 		else
26779a0bf528SMauro Carvalho Chehab 			iMER = 0;
26789a0bf528SMauro Carvalho Chehab 	}
26799a0bf528SMauro Carvalho Chehab 	*pSignalToNoise = iMER;
26809a0bf528SMauro Carvalho Chehab 
26819a0bf528SMauro Carvalho Chehab error:
26829a0bf528SMauro Carvalho Chehab 	if (status < 0)
26839a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
26849a0bf528SMauro Carvalho Chehab 	return status;
26859a0bf528SMauro Carvalho Chehab }
26869a0bf528SMauro Carvalho Chehab 
26879a0bf528SMauro Carvalho Chehab static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
26889a0bf528SMauro Carvalho Chehab {
26899a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
26909a0bf528SMauro Carvalho Chehab 
26919a0bf528SMauro Carvalho Chehab 	*pSignalToNoise = 0;
26929a0bf528SMauro Carvalho Chehab 	switch (state->m_OperationMode) {
26939a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
26949a0bf528SMauro Carvalho Chehab 		return GetDVBTSignalToNoise(state, pSignalToNoise);
26959a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
26969a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
26979a0bf528SMauro Carvalho Chehab 		return GetQAMSignalToNoise(state, pSignalToNoise);
26989a0bf528SMauro Carvalho Chehab 	default:
26999a0bf528SMauro Carvalho Chehab 		break;
27009a0bf528SMauro Carvalho Chehab 	}
27019a0bf528SMauro Carvalho Chehab 	return 0;
27029a0bf528SMauro Carvalho Chehab }
27039a0bf528SMauro Carvalho Chehab 
27049a0bf528SMauro Carvalho Chehab #if 0
27059a0bf528SMauro Carvalho Chehab static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
27069a0bf528SMauro Carvalho Chehab {
27079a0bf528SMauro Carvalho Chehab 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
27089a0bf528SMauro Carvalho Chehab 	int status = 0;
27099a0bf528SMauro Carvalho Chehab 
27109a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27119a0bf528SMauro Carvalho Chehab 
27129a0bf528SMauro Carvalho Chehab 	static s32 QE_SN[] = {
27139a0bf528SMauro Carvalho Chehab 		51,		/* QPSK 1/2 */
27149a0bf528SMauro Carvalho Chehab 		69,		/* QPSK 2/3 */
27159a0bf528SMauro Carvalho Chehab 		79,		/* QPSK 3/4 */
27169a0bf528SMauro Carvalho Chehab 		89,		/* QPSK 5/6 */
27179a0bf528SMauro Carvalho Chehab 		97,		/* QPSK 7/8 */
27189a0bf528SMauro Carvalho Chehab 		108,		/* 16-QAM 1/2 */
27199a0bf528SMauro Carvalho Chehab 		131,		/* 16-QAM 2/3 */
27209a0bf528SMauro Carvalho Chehab 		146,		/* 16-QAM 3/4 */
27219a0bf528SMauro Carvalho Chehab 		156,		/* 16-QAM 5/6 */
27229a0bf528SMauro Carvalho Chehab 		160,		/* 16-QAM 7/8 */
27239a0bf528SMauro Carvalho Chehab 		165,		/* 64-QAM 1/2 */
27249a0bf528SMauro Carvalho Chehab 		187,		/* 64-QAM 2/3 */
27259a0bf528SMauro Carvalho Chehab 		202,		/* 64-QAM 3/4 */
27269a0bf528SMauro Carvalho Chehab 		216,		/* 64-QAM 5/6 */
27279a0bf528SMauro Carvalho Chehab 		225,		/* 64-QAM 7/8 */
27289a0bf528SMauro Carvalho Chehab 	};
27299a0bf528SMauro Carvalho Chehab 
27309a0bf528SMauro Carvalho Chehab 	*pQuality = 0;
27319a0bf528SMauro Carvalho Chehab 
27329a0bf528SMauro Carvalho Chehab 	do {
27339a0bf528SMauro Carvalho Chehab 		s32 SignalToNoise = 0;
27349a0bf528SMauro Carvalho Chehab 		u16 Constellation = 0;
27359a0bf528SMauro Carvalho Chehab 		u16 CodeRate = 0;
27369a0bf528SMauro Carvalho Chehab 		u32 SignalToNoiseRel;
27379a0bf528SMauro Carvalho Chehab 		u32 BERQuality;
27389a0bf528SMauro Carvalho Chehab 
27399a0bf528SMauro Carvalho Chehab 		status = GetDVBTSignalToNoise(state, &SignalToNoise);
27409a0bf528SMauro Carvalho Chehab 		if (status < 0)
27419a0bf528SMauro Carvalho Chehab 			break;
27429a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
27439a0bf528SMauro Carvalho Chehab 		if (status < 0)
27449a0bf528SMauro Carvalho Chehab 			break;
27459a0bf528SMauro Carvalho Chehab 		Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
27469a0bf528SMauro Carvalho Chehab 
27479a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
27489a0bf528SMauro Carvalho Chehab 		if (status < 0)
27499a0bf528SMauro Carvalho Chehab 			break;
27509a0bf528SMauro Carvalho Chehab 		CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
27519a0bf528SMauro Carvalho Chehab 
27529a0bf528SMauro Carvalho Chehab 		if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
27539a0bf528SMauro Carvalho Chehab 		    CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
27549a0bf528SMauro Carvalho Chehab 			break;
27559a0bf528SMauro Carvalho Chehab 		SignalToNoiseRel = SignalToNoise -
27569a0bf528SMauro Carvalho Chehab 		    QE_SN[Constellation * 5 + CodeRate];
27579a0bf528SMauro Carvalho Chehab 		BERQuality = 100;
27589a0bf528SMauro Carvalho Chehab 
27599a0bf528SMauro Carvalho Chehab 		if (SignalToNoiseRel < -70)
27609a0bf528SMauro Carvalho Chehab 			*pQuality = 0;
27619a0bf528SMauro Carvalho Chehab 		else if (SignalToNoiseRel < 30)
27629a0bf528SMauro Carvalho Chehab 			*pQuality = ((SignalToNoiseRel + 70) *
27639a0bf528SMauro Carvalho Chehab 				     BERQuality) / 100;
27649a0bf528SMauro Carvalho Chehab 		else
27659a0bf528SMauro Carvalho Chehab 			*pQuality = BERQuality;
27669a0bf528SMauro Carvalho Chehab 	} while (0);
27679a0bf528SMauro Carvalho Chehab 	return 0;
27689a0bf528SMauro Carvalho Chehab };
27699a0bf528SMauro Carvalho Chehab 
27709a0bf528SMauro Carvalho Chehab static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
27719a0bf528SMauro Carvalho Chehab {
27729a0bf528SMauro Carvalho Chehab 	int status = 0;
27739a0bf528SMauro Carvalho Chehab 	*pQuality = 0;
27749a0bf528SMauro Carvalho Chehab 
27759a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
27769a0bf528SMauro Carvalho Chehab 
27779a0bf528SMauro Carvalho Chehab 	do {
27789a0bf528SMauro Carvalho Chehab 		u32 SignalToNoise = 0;
27799a0bf528SMauro Carvalho Chehab 		u32 BERQuality = 100;
27809a0bf528SMauro Carvalho Chehab 		u32 SignalToNoiseRel = 0;
27819a0bf528SMauro Carvalho Chehab 
27829a0bf528SMauro Carvalho Chehab 		status = GetQAMSignalToNoise(state, &SignalToNoise);
27839a0bf528SMauro Carvalho Chehab 		if (status < 0)
27849a0bf528SMauro Carvalho Chehab 			break;
27859a0bf528SMauro Carvalho Chehab 
27869a0bf528SMauro Carvalho Chehab 		switch (state->props.modulation) {
27879a0bf528SMauro Carvalho Chehab 		case QAM_16:
27889a0bf528SMauro Carvalho Chehab 			SignalToNoiseRel = SignalToNoise - 200;
27899a0bf528SMauro Carvalho Chehab 			break;
27909a0bf528SMauro Carvalho Chehab 		case QAM_32:
27919a0bf528SMauro Carvalho Chehab 			SignalToNoiseRel = SignalToNoise - 230;
27929a0bf528SMauro Carvalho Chehab 			break;	/* Not in NorDig */
27939a0bf528SMauro Carvalho Chehab 		case QAM_64:
27949a0bf528SMauro Carvalho Chehab 			SignalToNoiseRel = SignalToNoise - 260;
27959a0bf528SMauro Carvalho Chehab 			break;
27969a0bf528SMauro Carvalho Chehab 		case QAM_128:
27979a0bf528SMauro Carvalho Chehab 			SignalToNoiseRel = SignalToNoise - 290;
27989a0bf528SMauro Carvalho Chehab 			break;
27999a0bf528SMauro Carvalho Chehab 		default:
28009a0bf528SMauro Carvalho Chehab 		case QAM_256:
28019a0bf528SMauro Carvalho Chehab 			SignalToNoiseRel = SignalToNoise - 320;
28029a0bf528SMauro Carvalho Chehab 			break;
28039a0bf528SMauro Carvalho Chehab 		}
28049a0bf528SMauro Carvalho Chehab 
28059a0bf528SMauro Carvalho Chehab 		if (SignalToNoiseRel < -70)
28069a0bf528SMauro Carvalho Chehab 			*pQuality = 0;
28079a0bf528SMauro Carvalho Chehab 		else if (SignalToNoiseRel < 30)
28089a0bf528SMauro Carvalho Chehab 			*pQuality = ((SignalToNoiseRel + 70) *
28099a0bf528SMauro Carvalho Chehab 				     BERQuality) / 100;
28109a0bf528SMauro Carvalho Chehab 		else
28119a0bf528SMauro Carvalho Chehab 			*pQuality = BERQuality;
28129a0bf528SMauro Carvalho Chehab 	} while (0);
28139a0bf528SMauro Carvalho Chehab 
28149a0bf528SMauro Carvalho Chehab 	return status;
28159a0bf528SMauro Carvalho Chehab }
28169a0bf528SMauro Carvalho Chehab 
28179a0bf528SMauro Carvalho Chehab static int GetQuality(struct drxk_state *state, s32 *pQuality)
28189a0bf528SMauro Carvalho Chehab {
28199a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28209a0bf528SMauro Carvalho Chehab 
28219a0bf528SMauro Carvalho Chehab 	switch (state->m_OperationMode) {
28229a0bf528SMauro Carvalho Chehab 	case OM_DVBT:
28239a0bf528SMauro Carvalho Chehab 		return GetDVBTQuality(state, pQuality);
28249a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
28259a0bf528SMauro Carvalho Chehab 		return GetDVBCQuality(state, pQuality);
28269a0bf528SMauro Carvalho Chehab 	default:
28279a0bf528SMauro Carvalho Chehab 		break;
28289a0bf528SMauro Carvalho Chehab 	}
28299a0bf528SMauro Carvalho Chehab 
28309a0bf528SMauro Carvalho Chehab 	return 0;
28319a0bf528SMauro Carvalho Chehab }
28329a0bf528SMauro Carvalho Chehab #endif
28339a0bf528SMauro Carvalho Chehab 
28349a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
28359a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
28369a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A   0x420060
28379a0bf528SMauro Carvalho Chehab 
28389a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
28399a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
28409a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
28419a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
28429a0bf528SMauro Carvalho Chehab 
28439a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
28449a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
28459a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
28469a0bf528SMauro Carvalho Chehab 
28479a0bf528SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
28489a0bf528SMauro Carvalho Chehab {
28499a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
28509a0bf528SMauro Carvalho Chehab 
28519a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28529a0bf528SMauro Carvalho Chehab 
28539a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
28549a0bf528SMauro Carvalho Chehab 		return 0;
28559a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_POWERED_DOWN)
28569a0bf528SMauro Carvalho Chehab 		goto error;
28579a0bf528SMauro Carvalho Chehab 
28589a0bf528SMauro Carvalho Chehab 	if (state->no_i2c_bridge)
28599a0bf528SMauro Carvalho Chehab 		return 0;
28609a0bf528SMauro Carvalho Chehab 
28619a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
28629a0bf528SMauro Carvalho Chehab 	if (status < 0)
28639a0bf528SMauro Carvalho Chehab 		goto error;
28649a0bf528SMauro Carvalho Chehab 	if (bEnableBridge) {
28659a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
28669a0bf528SMauro Carvalho Chehab 		if (status < 0)
28679a0bf528SMauro Carvalho Chehab 			goto error;
28689a0bf528SMauro Carvalho Chehab 	} else {
28699a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
28709a0bf528SMauro Carvalho Chehab 		if (status < 0)
28719a0bf528SMauro Carvalho Chehab 			goto error;
28729a0bf528SMauro Carvalho Chehab 	}
28739a0bf528SMauro Carvalho Chehab 
28749a0bf528SMauro Carvalho Chehab 	status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
28759a0bf528SMauro Carvalho Chehab 
28769a0bf528SMauro Carvalho Chehab error:
28779a0bf528SMauro Carvalho Chehab 	if (status < 0)
28789a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
28799a0bf528SMauro Carvalho Chehab 	return status;
28809a0bf528SMauro Carvalho Chehab }
28819a0bf528SMauro Carvalho Chehab 
28829a0bf528SMauro Carvalho Chehab static int SetPreSaw(struct drxk_state *state,
28839a0bf528SMauro Carvalho Chehab 		     struct SCfgPreSaw *pPreSawCfg)
28849a0bf528SMauro Carvalho Chehab {
28859a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
28869a0bf528SMauro Carvalho Chehab 
28879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
28889a0bf528SMauro Carvalho Chehab 
28899a0bf528SMauro Carvalho Chehab 	if ((pPreSawCfg == NULL)
28909a0bf528SMauro Carvalho Chehab 	    || (pPreSawCfg->reference > IQM_AF_PDREF__M))
28919a0bf528SMauro Carvalho Chehab 		goto error;
28929a0bf528SMauro Carvalho Chehab 
28939a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
28949a0bf528SMauro Carvalho Chehab error:
28959a0bf528SMauro Carvalho Chehab 	if (status < 0)
28969a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
28979a0bf528SMauro Carvalho Chehab 	return status;
28989a0bf528SMauro Carvalho Chehab }
28999a0bf528SMauro Carvalho Chehab 
29009a0bf528SMauro Carvalho Chehab static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
29019a0bf528SMauro Carvalho Chehab 		       u16 romOffset, u16 nrOfElements, u32 timeOut)
29029a0bf528SMauro Carvalho Chehab {
29039a0bf528SMauro Carvalho Chehab 	u16 blStatus = 0;
29049a0bf528SMauro Carvalho Chehab 	u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
29059a0bf528SMauro Carvalho Chehab 	u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
29069a0bf528SMauro Carvalho Chehab 	int status;
29079a0bf528SMauro Carvalho Chehab 	unsigned long end;
29089a0bf528SMauro Carvalho Chehab 
29099a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29109a0bf528SMauro Carvalho Chehab 
29119a0bf528SMauro Carvalho Chehab 	mutex_lock(&state->mutex);
29129a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
29139a0bf528SMauro Carvalho Chehab 	if (status < 0)
29149a0bf528SMauro Carvalho Chehab 		goto error;
29159a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
29169a0bf528SMauro Carvalho Chehab 	if (status < 0)
29179a0bf528SMauro Carvalho Chehab 		goto error;
29189a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
29199a0bf528SMauro Carvalho Chehab 	if (status < 0)
29209a0bf528SMauro Carvalho Chehab 		goto error;
29219a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
29229a0bf528SMauro Carvalho Chehab 	if (status < 0)
29239a0bf528SMauro Carvalho Chehab 		goto error;
29249a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
29259a0bf528SMauro Carvalho Chehab 	if (status < 0)
29269a0bf528SMauro Carvalho Chehab 		goto error;
29279a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
29289a0bf528SMauro Carvalho Chehab 	if (status < 0)
29299a0bf528SMauro Carvalho Chehab 		goto error;
29309a0bf528SMauro Carvalho Chehab 
29319a0bf528SMauro Carvalho Chehab 	end = jiffies + msecs_to_jiffies(timeOut);
29329a0bf528SMauro Carvalho Chehab 	do {
29339a0bf528SMauro Carvalho Chehab 		status = read16(state, SIO_BL_STATUS__A, &blStatus);
29349a0bf528SMauro Carvalho Chehab 		if (status < 0)
29359a0bf528SMauro Carvalho Chehab 			goto error;
29369a0bf528SMauro Carvalho Chehab 	} while ((blStatus == 0x1) && time_is_after_jiffies(end));
29379a0bf528SMauro Carvalho Chehab 	if (blStatus == 0x1) {
29389a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: SIO not ready\n");
29399a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
29409a0bf528SMauro Carvalho Chehab 		goto error2;
29419a0bf528SMauro Carvalho Chehab 	}
29429a0bf528SMauro Carvalho Chehab error:
29439a0bf528SMauro Carvalho Chehab 	if (status < 0)
29449a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
29459a0bf528SMauro Carvalho Chehab error2:
29469a0bf528SMauro Carvalho Chehab 	mutex_unlock(&state->mutex);
29479a0bf528SMauro Carvalho Chehab 	return status;
29489a0bf528SMauro Carvalho Chehab 
29499a0bf528SMauro Carvalho Chehab }
29509a0bf528SMauro Carvalho Chehab 
29519a0bf528SMauro Carvalho Chehab static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
29529a0bf528SMauro Carvalho Chehab {
29539a0bf528SMauro Carvalho Chehab 	u16 data = 0;
29549a0bf528SMauro Carvalho Chehab 	int status;
29559a0bf528SMauro Carvalho Chehab 
29569a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29579a0bf528SMauro Carvalho Chehab 
29589a0bf528SMauro Carvalho Chehab 	/* Start measurement */
29599a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
29609a0bf528SMauro Carvalho Chehab 	if (status < 0)
29619a0bf528SMauro Carvalho Chehab 		goto error;
29629a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 1);
29639a0bf528SMauro Carvalho Chehab 	if (status < 0)
29649a0bf528SMauro Carvalho Chehab 		goto error;
29659a0bf528SMauro Carvalho Chehab 
29669a0bf528SMauro Carvalho Chehab 	*count = 0;
29679a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE0__A, &data);
29689a0bf528SMauro Carvalho Chehab 	if (status < 0)
29699a0bf528SMauro Carvalho Chehab 		goto error;
29709a0bf528SMauro Carvalho Chehab 	if (data == 127)
29719a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
29729a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE1__A, &data);
29739a0bf528SMauro Carvalho Chehab 	if (status < 0)
29749a0bf528SMauro Carvalho Chehab 		goto error;
29759a0bf528SMauro Carvalho Chehab 	if (data == 127)
29769a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
29779a0bf528SMauro Carvalho Chehab 	status = read16(state, IQM_AF_PHASE2__A, &data);
29789a0bf528SMauro Carvalho Chehab 	if (status < 0)
29799a0bf528SMauro Carvalho Chehab 		goto error;
29809a0bf528SMauro Carvalho Chehab 	if (data == 127)
29819a0bf528SMauro Carvalho Chehab 		*count = *count + 1;
29829a0bf528SMauro Carvalho Chehab 
29839a0bf528SMauro Carvalho Chehab error:
29849a0bf528SMauro Carvalho Chehab 	if (status < 0)
29859a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
29869a0bf528SMauro Carvalho Chehab 	return status;
29879a0bf528SMauro Carvalho Chehab }
29889a0bf528SMauro Carvalho Chehab 
29899a0bf528SMauro Carvalho Chehab static int ADCSynchronization(struct drxk_state *state)
29909a0bf528SMauro Carvalho Chehab {
29919a0bf528SMauro Carvalho Chehab 	u16 count = 0;
29929a0bf528SMauro Carvalho Chehab 	int status;
29939a0bf528SMauro Carvalho Chehab 
29949a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
29959a0bf528SMauro Carvalho Chehab 
29969a0bf528SMauro Carvalho Chehab 	status = ADCSyncMeasurement(state, &count);
29979a0bf528SMauro Carvalho Chehab 	if (status < 0)
29989a0bf528SMauro Carvalho Chehab 		goto error;
29999a0bf528SMauro Carvalho Chehab 
30009a0bf528SMauro Carvalho Chehab 	if (count == 1) {
30019a0bf528SMauro Carvalho Chehab 		/* Try sampling on a diffrent edge */
30029a0bf528SMauro Carvalho Chehab 		u16 clkNeg = 0;
30039a0bf528SMauro Carvalho Chehab 
30049a0bf528SMauro Carvalho Chehab 		status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
30059a0bf528SMauro Carvalho Chehab 		if (status < 0)
30069a0bf528SMauro Carvalho Chehab 			goto error;
30079a0bf528SMauro Carvalho Chehab 		if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
30089a0bf528SMauro Carvalho Chehab 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
30099a0bf528SMauro Carvalho Chehab 			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
30109a0bf528SMauro Carvalho Chehab 			clkNeg |=
30119a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
30129a0bf528SMauro Carvalho Chehab 		} else {
30139a0bf528SMauro Carvalho Chehab 			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
30149a0bf528SMauro Carvalho Chehab 			clkNeg |=
30159a0bf528SMauro Carvalho Chehab 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
30169a0bf528SMauro Carvalho Chehab 		}
30179a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
30189a0bf528SMauro Carvalho Chehab 		if (status < 0)
30199a0bf528SMauro Carvalho Chehab 			goto error;
30209a0bf528SMauro Carvalho Chehab 		status = ADCSyncMeasurement(state, &count);
30219a0bf528SMauro Carvalho Chehab 		if (status < 0)
30229a0bf528SMauro Carvalho Chehab 			goto error;
30239a0bf528SMauro Carvalho Chehab 	}
30249a0bf528SMauro Carvalho Chehab 
30259a0bf528SMauro Carvalho Chehab 	if (count < 2)
30269a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
30279a0bf528SMauro Carvalho Chehab error:
30289a0bf528SMauro Carvalho Chehab 	if (status < 0)
30299a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
30309a0bf528SMauro Carvalho Chehab 	return status;
30319a0bf528SMauro Carvalho Chehab }
30329a0bf528SMauro Carvalho Chehab 
30339a0bf528SMauro Carvalho Chehab static int SetFrequencyShifter(struct drxk_state *state,
30349a0bf528SMauro Carvalho Chehab 			       u16 intermediateFreqkHz,
30359a0bf528SMauro Carvalho Chehab 			       s32 tunerFreqOffset, bool isDTV)
30369a0bf528SMauro Carvalho Chehab {
30379a0bf528SMauro Carvalho Chehab 	bool selectPosImage = false;
30389a0bf528SMauro Carvalho Chehab 	u32 rfFreqResidual = tunerFreqOffset;
30399a0bf528SMauro Carvalho Chehab 	u32 fmFrequencyShift = 0;
30409a0bf528SMauro Carvalho Chehab 	bool tunerMirror = !state->m_bMirrorFreqSpect;
30419a0bf528SMauro Carvalho Chehab 	u32 adcFreq;
30429a0bf528SMauro Carvalho Chehab 	bool adcFlip;
30439a0bf528SMauro Carvalho Chehab 	int status;
30449a0bf528SMauro Carvalho Chehab 	u32 ifFreqActual;
30459a0bf528SMauro Carvalho Chehab 	u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
30469a0bf528SMauro Carvalho Chehab 	u32 frequencyShift;
30479a0bf528SMauro Carvalho Chehab 	bool imageToSelect;
30489a0bf528SMauro Carvalho Chehab 
30499a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
30509a0bf528SMauro Carvalho Chehab 
30519a0bf528SMauro Carvalho Chehab 	/*
30529a0bf528SMauro Carvalho Chehab 	   Program frequency shifter
30539a0bf528SMauro Carvalho Chehab 	   No need to account for mirroring on RF
30549a0bf528SMauro Carvalho Chehab 	 */
30559a0bf528SMauro Carvalho Chehab 	if (isDTV) {
30569a0bf528SMauro Carvalho Chehab 		if ((state->m_OperationMode == OM_QAM_ITU_A) ||
30579a0bf528SMauro Carvalho Chehab 		    (state->m_OperationMode == OM_QAM_ITU_C) ||
30589a0bf528SMauro Carvalho Chehab 		    (state->m_OperationMode == OM_DVBT))
30599a0bf528SMauro Carvalho Chehab 			selectPosImage = true;
30609a0bf528SMauro Carvalho Chehab 		else
30619a0bf528SMauro Carvalho Chehab 			selectPosImage = false;
30629a0bf528SMauro Carvalho Chehab 	}
30639a0bf528SMauro Carvalho Chehab 	if (tunerMirror)
30649a0bf528SMauro Carvalho Chehab 		/* tuner doesn't mirror */
30659a0bf528SMauro Carvalho Chehab 		ifFreqActual = intermediateFreqkHz +
30669a0bf528SMauro Carvalho Chehab 		    rfFreqResidual + fmFrequencyShift;
30679a0bf528SMauro Carvalho Chehab 	else
30689a0bf528SMauro Carvalho Chehab 		/* tuner mirrors */
30699a0bf528SMauro Carvalho Chehab 		ifFreqActual = intermediateFreqkHz -
30709a0bf528SMauro Carvalho Chehab 		    rfFreqResidual - fmFrequencyShift;
30719a0bf528SMauro Carvalho Chehab 	if (ifFreqActual > samplingFrequency / 2) {
30729a0bf528SMauro Carvalho Chehab 		/* adc mirrors */
30739a0bf528SMauro Carvalho Chehab 		adcFreq = samplingFrequency - ifFreqActual;
30749a0bf528SMauro Carvalho Chehab 		adcFlip = true;
30759a0bf528SMauro Carvalho Chehab 	} else {
30769a0bf528SMauro Carvalho Chehab 		/* adc doesn't mirror */
30779a0bf528SMauro Carvalho Chehab 		adcFreq = ifFreqActual;
30789a0bf528SMauro Carvalho Chehab 		adcFlip = false;
30799a0bf528SMauro Carvalho Chehab 	}
30809a0bf528SMauro Carvalho Chehab 
30819a0bf528SMauro Carvalho Chehab 	frequencyShift = adcFreq;
30829a0bf528SMauro Carvalho Chehab 	imageToSelect = state->m_rfmirror ^ tunerMirror ^
30839a0bf528SMauro Carvalho Chehab 	    adcFlip ^ selectPosImage;
30849a0bf528SMauro Carvalho Chehab 	state->m_IqmFsRateOfs =
30859a0bf528SMauro Carvalho Chehab 	    Frac28a((frequencyShift), samplingFrequency);
30869a0bf528SMauro Carvalho Chehab 
30879a0bf528SMauro Carvalho Chehab 	if (imageToSelect)
30889a0bf528SMauro Carvalho Chehab 		state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
30899a0bf528SMauro Carvalho Chehab 
30909a0bf528SMauro Carvalho Chehab 	/* Program frequency shifter with tuner offset compensation */
30919a0bf528SMauro Carvalho Chehab 	/* frequencyShift += tunerFreqOffset; TODO */
30929a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
30939a0bf528SMauro Carvalho Chehab 			 state->m_IqmFsRateOfs);
30949a0bf528SMauro Carvalho Chehab 	if (status < 0)
30959a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
30969a0bf528SMauro Carvalho Chehab 	return status;
30979a0bf528SMauro Carvalho Chehab }
30989a0bf528SMauro Carvalho Chehab 
30999a0bf528SMauro Carvalho Chehab static int InitAGC(struct drxk_state *state, bool isDTV)
31009a0bf528SMauro Carvalho Chehab {
31019a0bf528SMauro Carvalho Chehab 	u16 ingainTgt = 0;
31029a0bf528SMauro Carvalho Chehab 	u16 ingainTgtMin = 0;
31039a0bf528SMauro Carvalho Chehab 	u16 ingainTgtMax = 0;
31049a0bf528SMauro Carvalho Chehab 	u16 clpCyclen = 0;
31059a0bf528SMauro Carvalho Chehab 	u16 clpSumMin = 0;
31069a0bf528SMauro Carvalho Chehab 	u16 clpDirTo = 0;
31079a0bf528SMauro Carvalho Chehab 	u16 snsSumMin = 0;
31089a0bf528SMauro Carvalho Chehab 	u16 snsSumMax = 0;
31099a0bf528SMauro Carvalho Chehab 	u16 clpSumMax = 0;
31109a0bf528SMauro Carvalho Chehab 	u16 snsDirTo = 0;
31119a0bf528SMauro Carvalho Chehab 	u16 kiInnergainMin = 0;
31129a0bf528SMauro Carvalho Chehab 	u16 ifIaccuHiTgt = 0;
31139a0bf528SMauro Carvalho Chehab 	u16 ifIaccuHiTgtMin = 0;
31149a0bf528SMauro Carvalho Chehab 	u16 ifIaccuHiTgtMax = 0;
31159a0bf528SMauro Carvalho Chehab 	u16 data = 0;
31169a0bf528SMauro Carvalho Chehab 	u16 fastClpCtrlDelay = 0;
31179a0bf528SMauro Carvalho Chehab 	u16 clpCtrlMode = 0;
31189a0bf528SMauro Carvalho Chehab 	int status = 0;
31199a0bf528SMauro Carvalho Chehab 
31209a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
31219a0bf528SMauro Carvalho Chehab 
31229a0bf528SMauro Carvalho Chehab 	/* Common settings */
31239a0bf528SMauro Carvalho Chehab 	snsSumMax = 1023;
31249a0bf528SMauro Carvalho Chehab 	ifIaccuHiTgtMin = 2047;
31259a0bf528SMauro Carvalho Chehab 	clpCyclen = 500;
31269a0bf528SMauro Carvalho Chehab 	clpSumMax = 1023;
31279a0bf528SMauro Carvalho Chehab 
31289a0bf528SMauro Carvalho Chehab 	/* AGCInit() not available for DVBT; init done in microcode */
31299a0bf528SMauro Carvalho Chehab 	if (!IsQAM(state)) {
31309a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
31319a0bf528SMauro Carvalho Chehab 		return -EINVAL;
31329a0bf528SMauro Carvalho Chehab 	}
31339a0bf528SMauro Carvalho Chehab 
31349a0bf528SMauro Carvalho Chehab 	/* FIXME: Analog TV AGC require different settings */
31359a0bf528SMauro Carvalho Chehab 
31369a0bf528SMauro Carvalho Chehab 	/* Standard specific settings */
31379a0bf528SMauro Carvalho Chehab 	clpSumMin = 8;
31389a0bf528SMauro Carvalho Chehab 	clpDirTo = (u16) -9;
31399a0bf528SMauro Carvalho Chehab 	clpCtrlMode = 0;
31409a0bf528SMauro Carvalho Chehab 	snsSumMin = 8;
31419a0bf528SMauro Carvalho Chehab 	snsDirTo = (u16) -9;
31429a0bf528SMauro Carvalho Chehab 	kiInnergainMin = (u16) -1030;
31439a0bf528SMauro Carvalho Chehab 	ifIaccuHiTgtMax = 0x2380;
31449a0bf528SMauro Carvalho Chehab 	ifIaccuHiTgt = 0x2380;
31459a0bf528SMauro Carvalho Chehab 	ingainTgtMin = 0x0511;
31469a0bf528SMauro Carvalho Chehab 	ingainTgt = 0x0511;
31479a0bf528SMauro Carvalho Chehab 	ingainTgtMax = 5119;
31489a0bf528SMauro Carvalho Chehab 	fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
31499a0bf528SMauro Carvalho Chehab 
31509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
31519a0bf528SMauro Carvalho Chehab 	if (status < 0)
31529a0bf528SMauro Carvalho Chehab 		goto error;
31539a0bf528SMauro Carvalho Chehab 
31549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
31559a0bf528SMauro Carvalho Chehab 	if (status < 0)
31569a0bf528SMauro Carvalho Chehab 		goto error;
31579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
31589a0bf528SMauro Carvalho Chehab 	if (status < 0)
31599a0bf528SMauro Carvalho Chehab 		goto error;
31609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
31619a0bf528SMauro Carvalho Chehab 	if (status < 0)
31629a0bf528SMauro Carvalho Chehab 		goto error;
31639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
31649a0bf528SMauro Carvalho Chehab 	if (status < 0)
31659a0bf528SMauro Carvalho Chehab 		goto error;
31669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
31679a0bf528SMauro Carvalho Chehab 	if (status < 0)
31689a0bf528SMauro Carvalho Chehab 		goto error;
31699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
31709a0bf528SMauro Carvalho Chehab 	if (status < 0)
31719a0bf528SMauro Carvalho Chehab 		goto error;
31729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
31739a0bf528SMauro Carvalho Chehab 	if (status < 0)
31749a0bf528SMauro Carvalho Chehab 		goto error;
31759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
31769a0bf528SMauro Carvalho Chehab 	if (status < 0)
31779a0bf528SMauro Carvalho Chehab 		goto error;
31789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
31799a0bf528SMauro Carvalho Chehab 	if (status < 0)
31809a0bf528SMauro Carvalho Chehab 		goto error;
31819a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
31829a0bf528SMauro Carvalho Chehab 	if (status < 0)
31839a0bf528SMauro Carvalho Chehab 		goto error;
31849a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
31859a0bf528SMauro Carvalho Chehab 	if (status < 0)
31869a0bf528SMauro Carvalho Chehab 		goto error;
31879a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
31889a0bf528SMauro Carvalho Chehab 	if (status < 0)
31899a0bf528SMauro Carvalho Chehab 		goto error;
31909a0bf528SMauro Carvalho Chehab 
31919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
31929a0bf528SMauro Carvalho Chehab 	if (status < 0)
31939a0bf528SMauro Carvalho Chehab 		goto error;
31949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
31959a0bf528SMauro Carvalho Chehab 	if (status < 0)
31969a0bf528SMauro Carvalho Chehab 		goto error;
31979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
31989a0bf528SMauro Carvalho Chehab 	if (status < 0)
31999a0bf528SMauro Carvalho Chehab 		goto error;
32009a0bf528SMauro Carvalho Chehab 
32019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
32029a0bf528SMauro Carvalho Chehab 	if (status < 0)
32039a0bf528SMauro Carvalho Chehab 		goto error;
32049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
32059a0bf528SMauro Carvalho Chehab 	if (status < 0)
32069a0bf528SMauro Carvalho Chehab 		goto error;
32079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
32089a0bf528SMauro Carvalho Chehab 	if (status < 0)
32099a0bf528SMauro Carvalho Chehab 		goto error;
32109a0bf528SMauro Carvalho Chehab 
32119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
32129a0bf528SMauro Carvalho Chehab 	if (status < 0)
32139a0bf528SMauro Carvalho Chehab 		goto error;
32149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
32159a0bf528SMauro Carvalho Chehab 	if (status < 0)
32169a0bf528SMauro Carvalho Chehab 		goto error;
32179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
32189a0bf528SMauro Carvalho Chehab 	if (status < 0)
32199a0bf528SMauro Carvalho Chehab 		goto error;
32209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
32219a0bf528SMauro Carvalho Chehab 	if (status < 0)
32229a0bf528SMauro Carvalho Chehab 		goto error;
32239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
32249a0bf528SMauro Carvalho Chehab 	if (status < 0)
32259a0bf528SMauro Carvalho Chehab 		goto error;
32269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
32279a0bf528SMauro Carvalho Chehab 	if (status < 0)
32289a0bf528SMauro Carvalho Chehab 		goto error;
32299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
32309a0bf528SMauro Carvalho Chehab 	if (status < 0)
32319a0bf528SMauro Carvalho Chehab 		goto error;
32329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
32339a0bf528SMauro Carvalho Chehab 	if (status < 0)
32349a0bf528SMauro Carvalho Chehab 		goto error;
32359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
32369a0bf528SMauro Carvalho Chehab 	if (status < 0)
32379a0bf528SMauro Carvalho Chehab 		goto error;
32389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
32399a0bf528SMauro Carvalho Chehab 	if (status < 0)
32409a0bf528SMauro Carvalho Chehab 		goto error;
32419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
32429a0bf528SMauro Carvalho Chehab 	if (status < 0)
32439a0bf528SMauro Carvalho Chehab 		goto error;
32449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
32459a0bf528SMauro Carvalho Chehab 	if (status < 0)
32469a0bf528SMauro Carvalho Chehab 		goto error;
32479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
32489a0bf528SMauro Carvalho Chehab 	if (status < 0)
32499a0bf528SMauro Carvalho Chehab 		goto error;
32509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
32519a0bf528SMauro Carvalho Chehab 	if (status < 0)
32529a0bf528SMauro Carvalho Chehab 		goto error;
32539a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
32549a0bf528SMauro Carvalho Chehab 	if (status < 0)
32559a0bf528SMauro Carvalho Chehab 		goto error;
32569a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
32579a0bf528SMauro Carvalho Chehab 	if (status < 0)
32589a0bf528SMauro Carvalho Chehab 		goto error;
32599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
32609a0bf528SMauro Carvalho Chehab 	if (status < 0)
32619a0bf528SMauro Carvalho Chehab 		goto error;
32629a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
32639a0bf528SMauro Carvalho Chehab 	if (status < 0)
32649a0bf528SMauro Carvalho Chehab 		goto error;
32659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
32669a0bf528SMauro Carvalho Chehab 	if (status < 0)
32679a0bf528SMauro Carvalho Chehab 		goto error;
32689a0bf528SMauro Carvalho Chehab 
32699a0bf528SMauro Carvalho Chehab 	/* Initialize inner-loop KI gain factors */
32709a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_RAM_AGC_KI__A, &data);
32719a0bf528SMauro Carvalho Chehab 	if (status < 0)
32729a0bf528SMauro Carvalho Chehab 		goto error;
32739a0bf528SMauro Carvalho Chehab 
32749a0bf528SMauro Carvalho Chehab 	data = 0x0657;
32759a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_RF__M;
32769a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
32779a0bf528SMauro Carvalho Chehab 	data &= ~SCU_RAM_AGC_KI_IF__M;
32789a0bf528SMauro Carvalho Chehab 	data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
32799a0bf528SMauro Carvalho Chehab 
32809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_KI__A, data);
32819a0bf528SMauro Carvalho Chehab error:
32829a0bf528SMauro Carvalho Chehab 	if (status < 0)
32839a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
32849a0bf528SMauro Carvalho Chehab 	return status;
32859a0bf528SMauro Carvalho Chehab }
32869a0bf528SMauro Carvalho Chehab 
32879a0bf528SMauro Carvalho Chehab static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
32889a0bf528SMauro Carvalho Chehab {
32899a0bf528SMauro Carvalho Chehab 	int status;
32909a0bf528SMauro Carvalho Chehab 
32919a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
32929a0bf528SMauro Carvalho Chehab 	if (packetErr == NULL)
32939a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
32949a0bf528SMauro Carvalho Chehab 	else
32959a0bf528SMauro Carvalho Chehab 		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
32969a0bf528SMauro Carvalho Chehab 	if (status < 0)
32979a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
32989a0bf528SMauro Carvalho Chehab 	return status;
32999a0bf528SMauro Carvalho Chehab }
33009a0bf528SMauro Carvalho Chehab 
33019a0bf528SMauro Carvalho Chehab static int DVBTScCommand(struct drxk_state *state,
33029a0bf528SMauro Carvalho Chehab 			 u16 cmd, u16 subcmd,
33039a0bf528SMauro Carvalho Chehab 			 u16 param0, u16 param1, u16 param2,
33049a0bf528SMauro Carvalho Chehab 			 u16 param3, u16 param4)
33059a0bf528SMauro Carvalho Chehab {
33069a0bf528SMauro Carvalho Chehab 	u16 curCmd = 0;
33079a0bf528SMauro Carvalho Chehab 	u16 errCode = 0;
33089a0bf528SMauro Carvalho Chehab 	u16 retryCnt = 0;
33099a0bf528SMauro Carvalho Chehab 	u16 scExec = 0;
33109a0bf528SMauro Carvalho Chehab 	int status;
33119a0bf528SMauro Carvalho Chehab 
33129a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
33139a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
33149a0bf528SMauro Carvalho Chehab 	if (scExec != 1) {
33159a0bf528SMauro Carvalho Chehab 		/* SC is not running */
33169a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33179a0bf528SMauro Carvalho Chehab 	}
33189a0bf528SMauro Carvalho Chehab 	if (status < 0)
33199a0bf528SMauro Carvalho Chehab 		goto error;
33209a0bf528SMauro Carvalho Chehab 
33219a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready to receive command */
33229a0bf528SMauro Carvalho Chehab 	retryCnt = 0;
33239a0bf528SMauro Carvalho Chehab 	do {
33249a0bf528SMauro Carvalho Chehab 		msleep(1);
33259a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
33269a0bf528SMauro Carvalho Chehab 		retryCnt++;
33279a0bf528SMauro Carvalho Chehab 	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
33289a0bf528SMauro Carvalho Chehab 	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
33299a0bf528SMauro Carvalho Chehab 		goto error;
33309a0bf528SMauro Carvalho Chehab 
33319a0bf528SMauro Carvalho Chehab 	/* Write sub-command */
33329a0bf528SMauro Carvalho Chehab 	switch (cmd) {
33339a0bf528SMauro Carvalho Chehab 		/* All commands using sub-cmd */
33349a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
33359a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
33369a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
33379a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
33389a0bf528SMauro Carvalho Chehab 		if (status < 0)
33399a0bf528SMauro Carvalho Chehab 			goto error;
33409a0bf528SMauro Carvalho Chehab 		break;
33419a0bf528SMauro Carvalho Chehab 	default:
33429a0bf528SMauro Carvalho Chehab 		/* Do nothing */
33439a0bf528SMauro Carvalho Chehab 		break;
33449a0bf528SMauro Carvalho Chehab 	}
33459a0bf528SMauro Carvalho Chehab 
33469a0bf528SMauro Carvalho Chehab 	/* Write needed parameters and the command */
33479a0bf528SMauro Carvalho Chehab 	switch (cmd) {
33489a0bf528SMauro Carvalho Chehab 		/* All commands using 5 parameters */
33499a0bf528SMauro Carvalho Chehab 		/* All commands using 4 parameters */
33509a0bf528SMauro Carvalho Chehab 		/* All commands using 3 parameters */
33519a0bf528SMauro Carvalho Chehab 		/* All commands using 2 parameters */
33529a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
33539a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
33549a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
33559a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
33569a0bf528SMauro Carvalho Chehab 		/* All commands using 1 parameters */
33579a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
33589a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
33599a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
33609a0bf528SMauro Carvalho Chehab 		/* All commands using 0 parameters */
33619a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
33629a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
33639a0bf528SMauro Carvalho Chehab 		/* Write command */
33649a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
33659a0bf528SMauro Carvalho Chehab 		break;
33669a0bf528SMauro Carvalho Chehab 	default:
33679a0bf528SMauro Carvalho Chehab 		/* Unknown command */
33689a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33699a0bf528SMauro Carvalho Chehab 	}
33709a0bf528SMauro Carvalho Chehab 	if (status < 0)
33719a0bf528SMauro Carvalho Chehab 		goto error;
33729a0bf528SMauro Carvalho Chehab 
33739a0bf528SMauro Carvalho Chehab 	/* Wait until sc is ready processing command */
33749a0bf528SMauro Carvalho Chehab 	retryCnt = 0;
33759a0bf528SMauro Carvalho Chehab 	do {
33769a0bf528SMauro Carvalho Chehab 		msleep(1);
33779a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
33789a0bf528SMauro Carvalho Chehab 		retryCnt++;
33799a0bf528SMauro Carvalho Chehab 	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
33809a0bf528SMauro Carvalho Chehab 	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
33819a0bf528SMauro Carvalho Chehab 		goto error;
33829a0bf528SMauro Carvalho Chehab 
33839a0bf528SMauro Carvalho Chehab 	/* Check for illegal cmd */
33849a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
33859a0bf528SMauro Carvalho Chehab 	if (errCode == 0xFFFF) {
33869a0bf528SMauro Carvalho Chehab 		/* illegal command */
33879a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
33889a0bf528SMauro Carvalho Chehab 	}
33899a0bf528SMauro Carvalho Chehab 	if (status < 0)
33909a0bf528SMauro Carvalho Chehab 		goto error;
33919a0bf528SMauro Carvalho Chehab 
33929a0bf528SMauro Carvalho Chehab 	/* Retreive results parameters from SC */
33939a0bf528SMauro Carvalho Chehab 	switch (cmd) {
33949a0bf528SMauro Carvalho Chehab 		/* All commands yielding 5 results */
33959a0bf528SMauro Carvalho Chehab 		/* All commands yielding 4 results */
33969a0bf528SMauro Carvalho Chehab 		/* All commands yielding 3 results */
33979a0bf528SMauro Carvalho Chehab 		/* All commands yielding 2 results */
33989a0bf528SMauro Carvalho Chehab 		/* All commands yielding 1 result */
33999a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_USER_IO:
34009a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
34019a0bf528SMauro Carvalho Chehab 		status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
34029a0bf528SMauro Carvalho Chehab 		/* All commands yielding 0 results */
34039a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
34049a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_TIMER:
34059a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROC_START:
34069a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
34079a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
34089a0bf528SMauro Carvalho Chehab 	case OFDM_SC_RA_RAM_CMD_NULL:
34099a0bf528SMauro Carvalho Chehab 		break;
34109a0bf528SMauro Carvalho Chehab 	default:
34119a0bf528SMauro Carvalho Chehab 		/* Unknown command */
34129a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
34139a0bf528SMauro Carvalho Chehab 		break;
34149a0bf528SMauro Carvalho Chehab 	}			/* switch (cmd->cmd) */
34159a0bf528SMauro Carvalho Chehab error:
34169a0bf528SMauro Carvalho Chehab 	if (status < 0)
34179a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
34189a0bf528SMauro Carvalho Chehab 	return status;
34199a0bf528SMauro Carvalho Chehab }
34209a0bf528SMauro Carvalho Chehab 
34219a0bf528SMauro Carvalho Chehab static int PowerUpDVBT(struct drxk_state *state)
34229a0bf528SMauro Carvalho Chehab {
34239a0bf528SMauro Carvalho Chehab 	enum DRXPowerMode powerMode = DRX_POWER_UP;
34249a0bf528SMauro Carvalho Chehab 	int status;
34259a0bf528SMauro Carvalho Chehab 
34269a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34279a0bf528SMauro Carvalho Chehab 	status = CtrlPowerMode(state, &powerMode);
34289a0bf528SMauro Carvalho Chehab 	if (status < 0)
34299a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
34309a0bf528SMauro Carvalho Chehab 	return status;
34319a0bf528SMauro Carvalho Chehab }
34329a0bf528SMauro Carvalho Chehab 
34339a0bf528SMauro Carvalho Chehab static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
34349a0bf528SMauro Carvalho Chehab {
34359a0bf528SMauro Carvalho Chehab 	int status;
34369a0bf528SMauro Carvalho Chehab 
34379a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34389a0bf528SMauro Carvalho Chehab 	if (*enabled == true)
34399a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
34409a0bf528SMauro Carvalho Chehab 	else
34419a0bf528SMauro Carvalho Chehab 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
34429a0bf528SMauro Carvalho Chehab 	if (status < 0)
34439a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
34449a0bf528SMauro Carvalho Chehab 	return status;
34459a0bf528SMauro Carvalho Chehab }
34469a0bf528SMauro Carvalho Chehab 
34479a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K     4000
34489a0bf528SMauro Carvalho Chehab static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
34499a0bf528SMauro Carvalho Chehab {
34509a0bf528SMauro Carvalho Chehab 
34519a0bf528SMauro Carvalho Chehab 	int status;
34529a0bf528SMauro Carvalho Chehab 
34539a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34549a0bf528SMauro Carvalho Chehab 	if (*enabled == true) {
34559a0bf528SMauro Carvalho Chehab 		/* write mask to 1 */
34569a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
34579a0bf528SMauro Carvalho Chehab 				   DEFAULT_FR_THRES_8K);
34589a0bf528SMauro Carvalho Chehab 	} else {
34599a0bf528SMauro Carvalho Chehab 		/* write mask to 0 */
34609a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
34619a0bf528SMauro Carvalho Chehab 	}
34629a0bf528SMauro Carvalho Chehab 	if (status < 0)
34639a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
34649a0bf528SMauro Carvalho Chehab 
34659a0bf528SMauro Carvalho Chehab 	return status;
34669a0bf528SMauro Carvalho Chehab }
34679a0bf528SMauro Carvalho Chehab 
34689a0bf528SMauro Carvalho Chehab static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
34699a0bf528SMauro Carvalho Chehab 				    struct DRXKCfgDvbtEchoThres_t *echoThres)
34709a0bf528SMauro Carvalho Chehab {
34719a0bf528SMauro Carvalho Chehab 	u16 data = 0;
34729a0bf528SMauro Carvalho Chehab 	int status;
34739a0bf528SMauro Carvalho Chehab 
34749a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
34759a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
34769a0bf528SMauro Carvalho Chehab 	if (status < 0)
34779a0bf528SMauro Carvalho Chehab 		goto error;
34789a0bf528SMauro Carvalho Chehab 
34799a0bf528SMauro Carvalho Chehab 	switch (echoThres->fftMode) {
34809a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_2K:
34819a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
34829a0bf528SMauro Carvalho Chehab 		data |= ((echoThres->threshold <<
34839a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
34849a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
34859a0bf528SMauro Carvalho Chehab 		break;
34869a0bf528SMauro Carvalho Chehab 	case DRX_FFTMODE_8K:
34879a0bf528SMauro Carvalho Chehab 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
34889a0bf528SMauro Carvalho Chehab 		data |= ((echoThres->threshold <<
34899a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
34909a0bf528SMauro Carvalho Chehab 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
34919a0bf528SMauro Carvalho Chehab 		break;
34929a0bf528SMauro Carvalho Chehab 	default:
34939a0bf528SMauro Carvalho Chehab 		return -EINVAL;
34949a0bf528SMauro Carvalho Chehab 	}
34959a0bf528SMauro Carvalho Chehab 
34969a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
34979a0bf528SMauro Carvalho Chehab error:
34989a0bf528SMauro Carvalho Chehab 	if (status < 0)
34999a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
35009a0bf528SMauro Carvalho Chehab 	return status;
35019a0bf528SMauro Carvalho Chehab }
35029a0bf528SMauro Carvalho Chehab 
35039a0bf528SMauro Carvalho Chehab static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
35049a0bf528SMauro Carvalho Chehab 			       enum DRXKCfgDvbtSqiSpeed *speed)
35059a0bf528SMauro Carvalho Chehab {
35069a0bf528SMauro Carvalho Chehab 	int status = -EINVAL;
35079a0bf528SMauro Carvalho Chehab 
35089a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
35099a0bf528SMauro Carvalho Chehab 
35109a0bf528SMauro Carvalho Chehab 	switch (*speed) {
35119a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_FAST:
35129a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_MEDIUM:
35139a0bf528SMauro Carvalho Chehab 	case DRXK_DVBT_SQI_SPEED_SLOW:
35149a0bf528SMauro Carvalho Chehab 		break;
35159a0bf528SMauro Carvalho Chehab 	default:
35169a0bf528SMauro Carvalho Chehab 		goto error;
35179a0bf528SMauro Carvalho Chehab 	}
35189a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
35199a0bf528SMauro Carvalho Chehab 			   (u16) *speed);
35209a0bf528SMauro Carvalho Chehab error:
35219a0bf528SMauro Carvalho Chehab 	if (status < 0)
35229a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
35239a0bf528SMauro Carvalho Chehab 	return status;
35249a0bf528SMauro Carvalho Chehab }
35259a0bf528SMauro Carvalho Chehab 
35269a0bf528SMauro Carvalho Chehab /*============================================================================*/
35279a0bf528SMauro Carvalho Chehab 
35289a0bf528SMauro Carvalho Chehab /**
35299a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
35309a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
35319a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
35329a0bf528SMauro Carvalho Chehab *
35339a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
35349a0bf528SMauro Carvalho Chehab *
35359a0bf528SMauro Carvalho Chehab */
35369a0bf528SMauro Carvalho Chehab static int DVBTActivatePresets(struct drxk_state *state)
35379a0bf528SMauro Carvalho Chehab {
35389a0bf528SMauro Carvalho Chehab 	int status;
35399a0bf528SMauro Carvalho Chehab 	bool setincenable = false;
35409a0bf528SMauro Carvalho Chehab 	bool setfrenable = true;
35419a0bf528SMauro Carvalho Chehab 
35429a0bf528SMauro Carvalho Chehab 	struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
35439a0bf528SMauro Carvalho Chehab 	struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
35449a0bf528SMauro Carvalho Chehab 
35459a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
35469a0bf528SMauro Carvalho Chehab 	status = DVBTCtrlSetIncEnable(state, &setincenable);
35479a0bf528SMauro Carvalho Chehab 	if (status < 0)
35489a0bf528SMauro Carvalho Chehab 		goto error;
35499a0bf528SMauro Carvalho Chehab 	status = DVBTCtrlSetFrEnable(state, &setfrenable);
35509a0bf528SMauro Carvalho Chehab 	if (status < 0)
35519a0bf528SMauro Carvalho Chehab 		goto error;
35529a0bf528SMauro Carvalho Chehab 	status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
35539a0bf528SMauro Carvalho Chehab 	if (status < 0)
35549a0bf528SMauro Carvalho Chehab 		goto error;
35559a0bf528SMauro Carvalho Chehab 	status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
35569a0bf528SMauro Carvalho Chehab 	if (status < 0)
35579a0bf528SMauro Carvalho Chehab 		goto error;
35589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
35599a0bf528SMauro Carvalho Chehab error:
35609a0bf528SMauro Carvalho Chehab 	if (status < 0)
35619a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
35629a0bf528SMauro Carvalho Chehab 	return status;
35639a0bf528SMauro Carvalho Chehab }
35649a0bf528SMauro Carvalho Chehab 
35659a0bf528SMauro Carvalho Chehab /*============================================================================*/
35669a0bf528SMauro Carvalho Chehab 
35679a0bf528SMauro Carvalho Chehab /**
35689a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
35699a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
35709a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
35719a0bf528SMauro Carvalho Chehab *
35729a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
35739a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
35749a0bf528SMauro Carvalho Chehab */
35759a0bf528SMauro Carvalho Chehab static int SetDVBTStandard(struct drxk_state *state,
35769a0bf528SMauro Carvalho Chehab 			   enum OperationMode oMode)
35779a0bf528SMauro Carvalho Chehab {
35789a0bf528SMauro Carvalho Chehab 	u16 cmdResult = 0;
35799a0bf528SMauro Carvalho Chehab 	u16 data = 0;
35809a0bf528SMauro Carvalho Chehab 	int status;
35819a0bf528SMauro Carvalho Chehab 
35829a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
35839a0bf528SMauro Carvalho Chehab 
35849a0bf528SMauro Carvalho Chehab 	PowerUpDVBT(state);
35859a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
35869a0bf528SMauro Carvalho Chehab 	SwitchAntennaToDVBT(state);
35879a0bf528SMauro Carvalho Chehab 	/* send OFDM reset command */
35889a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
35899a0bf528SMauro Carvalho Chehab 	if (status < 0)
35909a0bf528SMauro Carvalho Chehab 		goto error;
35919a0bf528SMauro Carvalho Chehab 
35929a0bf528SMauro Carvalho Chehab 	/* send OFDM setenv command */
35939a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
35949a0bf528SMauro Carvalho Chehab 	if (status < 0)
35959a0bf528SMauro Carvalho Chehab 		goto error;
35969a0bf528SMauro Carvalho Chehab 
35979a0bf528SMauro Carvalho Chehab 	/* reset datapath for OFDM, processors first */
35989a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
35999a0bf528SMauro Carvalho Chehab 	if (status < 0)
36009a0bf528SMauro Carvalho Chehab 		goto error;
36019a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
36029a0bf528SMauro Carvalho Chehab 	if (status < 0)
36039a0bf528SMauro Carvalho Chehab 		goto error;
36049a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
36059a0bf528SMauro Carvalho Chehab 	if (status < 0)
36069a0bf528SMauro Carvalho Chehab 		goto error;
36079a0bf528SMauro Carvalho Chehab 
36089a0bf528SMauro Carvalho Chehab 	/* IQM setup */
36099a0bf528SMauro Carvalho Chehab 	/* synchronize on ofdstate->m_festart */
36109a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 1);
36119a0bf528SMauro Carvalho Chehab 	if (status < 0)
36129a0bf528SMauro Carvalho Chehab 		goto error;
36139a0bf528SMauro Carvalho Chehab 	/* window size for clipping ADC detection */
36149a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
36159a0bf528SMauro Carvalho Chehab 	if (status < 0)
36169a0bf528SMauro Carvalho Chehab 		goto error;
36179a0bf528SMauro Carvalho Chehab 	/* window size for for sense pre-SAW detection */
36189a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
36199a0bf528SMauro Carvalho Chehab 	if (status < 0)
36209a0bf528SMauro Carvalho Chehab 		goto error;
36219a0bf528SMauro Carvalho Chehab 	/* sense threshold for sense pre-SAW detection */
36229a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
36239a0bf528SMauro Carvalho Chehab 	if (status < 0)
36249a0bf528SMauro Carvalho Chehab 		goto error;
36259a0bf528SMauro Carvalho Chehab 	status = SetIqmAf(state, true);
36269a0bf528SMauro Carvalho Chehab 	if (status < 0)
36279a0bf528SMauro Carvalho Chehab 		goto error;
36289a0bf528SMauro Carvalho Chehab 
36299a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AGC_RF__A, 0);
36309a0bf528SMauro Carvalho Chehab 	if (status < 0)
36319a0bf528SMauro Carvalho Chehab 		goto error;
36329a0bf528SMauro Carvalho Chehab 
36339a0bf528SMauro Carvalho Chehab 	/* Impulse noise cruncher setup */
36349a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_LCT__A, 0);	/* crunch in IQM_CF */
36359a0bf528SMauro Carvalho Chehab 	if (status < 0)
36369a0bf528SMauro Carvalho Chehab 		goto error;
36379a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);	/* detect in IQM_CF */
36389a0bf528SMauro Carvalho Chehab 	if (status < 0)
36399a0bf528SMauro Carvalho Chehab 		goto error;
36409a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 3);	/* peak detector window length */
36419a0bf528SMauro Carvalho Chehab 	if (status < 0)
36429a0bf528SMauro Carvalho Chehab 		goto error;
36439a0bf528SMauro Carvalho Chehab 
36449a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 16);
36459a0bf528SMauro Carvalho Chehab 	if (status < 0)
36469a0bf528SMauro Carvalho Chehab 		goto error;
36479a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, 0x4);	/* enable output 2 */
36489a0bf528SMauro Carvalho Chehab 	if (status < 0)
36499a0bf528SMauro Carvalho Chehab 		goto error;
36509a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
36519a0bf528SMauro Carvalho Chehab 	if (status < 0)
36529a0bf528SMauro Carvalho Chehab 		goto error;
36539a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE__A, 1600);
36549a0bf528SMauro Carvalho Chehab 	if (status < 0)
36559a0bf528SMauro Carvalho Chehab 		goto error;
36569a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, 0);
36579a0bf528SMauro Carvalho Chehab 	if (status < 0)
36589a0bf528SMauro Carvalho Chehab 		goto error;
36599a0bf528SMauro Carvalho Chehab 
36609a0bf528SMauro Carvalho Chehab 	/* virtual clipping threshold for clipping ADC detection */
36619a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
36629a0bf528SMauro Carvalho Chehab 	if (status < 0)
36639a0bf528SMauro Carvalho Chehab 		goto error;
36649a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 495);	/* crunching threshold */
36659a0bf528SMauro Carvalho Chehab 	if (status < 0)
36669a0bf528SMauro Carvalho Chehab 		goto error;
36679a0bf528SMauro Carvalho Chehab 
36689a0bf528SMauro Carvalho Chehab 	status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
36699a0bf528SMauro Carvalho Chehab 	if (status < 0)
36709a0bf528SMauro Carvalho Chehab 		goto error;
36719a0bf528SMauro Carvalho Chehab 
36729a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 2);	/* peak detector threshold */
36739a0bf528SMauro Carvalho Chehab 	if (status < 0)
36749a0bf528SMauro Carvalho Chehab 		goto error;
36759a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
36769a0bf528SMauro Carvalho Chehab 	if (status < 0)
36779a0bf528SMauro Carvalho Chehab 		goto error;
36789a0bf528SMauro Carvalho Chehab 	/* enable power measurement interrupt */
36799a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
36809a0bf528SMauro Carvalho Chehab 	if (status < 0)
36819a0bf528SMauro Carvalho Chehab 		goto error;
36829a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
36839a0bf528SMauro Carvalho Chehab 	if (status < 0)
36849a0bf528SMauro Carvalho Chehab 		goto error;
36859a0bf528SMauro Carvalho Chehab 
36869a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
36879a0bf528SMauro Carvalho Chehab 	status = ADCSynchronization(state);
36889a0bf528SMauro Carvalho Chehab 	if (status < 0)
36899a0bf528SMauro Carvalho Chehab 		goto error;
36909a0bf528SMauro Carvalho Chehab 	status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
36919a0bf528SMauro Carvalho Chehab 	if (status < 0)
36929a0bf528SMauro Carvalho Chehab 		goto error;
36939a0bf528SMauro Carvalho Chehab 
36949a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
36959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
36969a0bf528SMauro Carvalho Chehab 	if (status < 0)
36979a0bf528SMauro Carvalho Chehab 		goto error;
36989a0bf528SMauro Carvalho Chehab 
36999a0bf528SMauro Carvalho Chehab 	status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
37009a0bf528SMauro Carvalho Chehab 	if (status < 0)
37019a0bf528SMauro Carvalho Chehab 		goto error;
37029a0bf528SMauro Carvalho Chehab 	status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
37039a0bf528SMauro Carvalho Chehab 	if (status < 0)
37049a0bf528SMauro Carvalho Chehab 		goto error;
37059a0bf528SMauro Carvalho Chehab 
37069a0bf528SMauro Carvalho Chehab 	/* Set Noise Estimation notch width and enable DC fix */
37079a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
37089a0bf528SMauro Carvalho Chehab 	if (status < 0)
37099a0bf528SMauro Carvalho Chehab 		goto error;
37109a0bf528SMauro Carvalho Chehab 	data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
37119a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
37129a0bf528SMauro Carvalho Chehab 	if (status < 0)
37139a0bf528SMauro Carvalho Chehab 		goto error;
37149a0bf528SMauro Carvalho Chehab 
37159a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
37169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
37179a0bf528SMauro Carvalho Chehab 	if (status < 0)
37189a0bf528SMauro Carvalho Chehab 		goto error;
37199a0bf528SMauro Carvalho Chehab 
37209a0bf528SMauro Carvalho Chehab 	if (!state->m_DRXK_A3_ROM_CODE) {
37219a0bf528SMauro Carvalho Chehab 		/* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay  */
37229a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
37239a0bf528SMauro Carvalho Chehab 		if (status < 0)
37249a0bf528SMauro Carvalho Chehab 			goto error;
37259a0bf528SMauro Carvalho Chehab 	}
37269a0bf528SMauro Carvalho Chehab 
37279a0bf528SMauro Carvalho Chehab 	/* OFDM_SC setup */
37289a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
37299a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
37309a0bf528SMauro Carvalho Chehab 	if (status < 0)
37319a0bf528SMauro Carvalho Chehab 		goto error;
37329a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
37339a0bf528SMauro Carvalho Chehab 	if (status < 0)
37349a0bf528SMauro Carvalho Chehab 		goto error;
37359a0bf528SMauro Carvalho Chehab #endif
37369a0bf528SMauro Carvalho Chehab 
37379a0bf528SMauro Carvalho Chehab 	/* FEC setup */
37389a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_INPUT_CTL__A, 1);	/* OFDM input */
37399a0bf528SMauro Carvalho Chehab 	if (status < 0)
37409a0bf528SMauro Carvalho Chehab 		goto error;
37419a0bf528SMauro Carvalho Chehab 
37429a0bf528SMauro Carvalho Chehab 
37439a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
37449a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
37459a0bf528SMauro Carvalho Chehab 	if (status < 0)
37469a0bf528SMauro Carvalho Chehab 		goto error;
37479a0bf528SMauro Carvalho Chehab #else
37489a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
37499a0bf528SMauro Carvalho Chehab 	if (status < 0)
37509a0bf528SMauro Carvalho Chehab 		goto error;
37519a0bf528SMauro Carvalho Chehab #endif
37529a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
37539a0bf528SMauro Carvalho Chehab 	if (status < 0)
37549a0bf528SMauro Carvalho Chehab 		goto error;
37559a0bf528SMauro Carvalho Chehab 
37569a0bf528SMauro Carvalho Chehab 	/* Setup MPEG bus */
37579a0bf528SMauro Carvalho Chehab 	status = MPEGTSDtoSetup(state, OM_DVBT);
37589a0bf528SMauro Carvalho Chehab 	if (status < 0)
37599a0bf528SMauro Carvalho Chehab 		goto error;
37609a0bf528SMauro Carvalho Chehab 	/* Set DVBT Presets */
37619a0bf528SMauro Carvalho Chehab 	status = DVBTActivatePresets(state);
37629a0bf528SMauro Carvalho Chehab 	if (status < 0)
37639a0bf528SMauro Carvalho Chehab 		goto error;
37649a0bf528SMauro Carvalho Chehab 
37659a0bf528SMauro Carvalho Chehab error:
37669a0bf528SMauro Carvalho Chehab 	if (status < 0)
37679a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
37689a0bf528SMauro Carvalho Chehab 	return status;
37699a0bf528SMauro Carvalho Chehab }
37709a0bf528SMauro Carvalho Chehab 
37719a0bf528SMauro Carvalho Chehab /*============================================================================*/
37729a0bf528SMauro Carvalho Chehab /**
37739a0bf528SMauro Carvalho Chehab * \brief Start dvbt demodulating for channel.
37749a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
37759a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
37769a0bf528SMauro Carvalho Chehab */
37779a0bf528SMauro Carvalho Chehab static int DVBTStart(struct drxk_state *state)
37789a0bf528SMauro Carvalho Chehab {
37799a0bf528SMauro Carvalho Chehab 	u16 param1;
37809a0bf528SMauro Carvalho Chehab 	int status;
37819a0bf528SMauro Carvalho Chehab 	/* DRXKOfdmScCmd_t scCmd; */
37829a0bf528SMauro Carvalho Chehab 
37839a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
37849a0bf528SMauro Carvalho Chehab 	/* Start correct processes to get in lock */
37859a0bf528SMauro Carvalho Chehab 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
37869a0bf528SMauro Carvalho Chehab 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
37879a0bf528SMauro Carvalho Chehab 	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
37889a0bf528SMauro Carvalho Chehab 	if (status < 0)
37899a0bf528SMauro Carvalho Chehab 		goto error;
37909a0bf528SMauro Carvalho Chehab 	/* Start FEC OC */
37919a0bf528SMauro Carvalho Chehab 	status = MPEGTSStart(state);
37929a0bf528SMauro Carvalho Chehab 	if (status < 0)
37939a0bf528SMauro Carvalho Chehab 		goto error;
37949a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
37959a0bf528SMauro Carvalho Chehab 	if (status < 0)
37969a0bf528SMauro Carvalho Chehab 		goto error;
37979a0bf528SMauro Carvalho Chehab error:
37989a0bf528SMauro Carvalho Chehab 	if (status < 0)
37999a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
38009a0bf528SMauro Carvalho Chehab 	return status;
38019a0bf528SMauro Carvalho Chehab }
38029a0bf528SMauro Carvalho Chehab 
38039a0bf528SMauro Carvalho Chehab 
38049a0bf528SMauro Carvalho Chehab /*============================================================================*/
38059a0bf528SMauro Carvalho Chehab 
38069a0bf528SMauro Carvalho Chehab /**
38079a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
38089a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
38099a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
38109a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
38119a0bf528SMauro Carvalho Chehab */
38129a0bf528SMauro Carvalho Chehab static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
38139a0bf528SMauro Carvalho Chehab 		   s32 tunerFreqOffset)
38149a0bf528SMauro Carvalho Chehab {
38159a0bf528SMauro Carvalho Chehab 	u16 cmdResult = 0;
38169a0bf528SMauro Carvalho Chehab 	u16 transmissionParams = 0;
38179a0bf528SMauro Carvalho Chehab 	u16 operationMode = 0;
38189a0bf528SMauro Carvalho Chehab 	u32 iqmRcRateOfs = 0;
38199a0bf528SMauro Carvalho Chehab 	u32 bandwidth = 0;
38209a0bf528SMauro Carvalho Chehab 	u16 param1;
38219a0bf528SMauro Carvalho Chehab 	int status;
38229a0bf528SMauro Carvalho Chehab 
38239a0bf528SMauro Carvalho Chehab 	dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
38249a0bf528SMauro Carvalho Chehab 
38259a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
38269a0bf528SMauro Carvalho Chehab 	if (status < 0)
38279a0bf528SMauro Carvalho Chehab 		goto error;
38289a0bf528SMauro Carvalho Chehab 
38299a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
38309a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
38319a0bf528SMauro Carvalho Chehab 	if (status < 0)
38329a0bf528SMauro Carvalho Chehab 		goto error;
38339a0bf528SMauro Carvalho Chehab 
38349a0bf528SMauro Carvalho Chehab 	/* Stop processors */
38359a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
38369a0bf528SMauro Carvalho Chehab 	if (status < 0)
38379a0bf528SMauro Carvalho Chehab 		goto error;
38389a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
38399a0bf528SMauro Carvalho Chehab 	if (status < 0)
38409a0bf528SMauro Carvalho Chehab 		goto error;
38419a0bf528SMauro Carvalho Chehab 
38429a0bf528SMauro Carvalho Chehab 	/* Mandatory fix, always stop CP, required to set spl offset back to
38439a0bf528SMauro Carvalho Chehab 		hardware default (is set to 0 by ucode during pilot detection */
38449a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
38459a0bf528SMauro Carvalho Chehab 	if (status < 0)
38469a0bf528SMauro Carvalho Chehab 		goto error;
38479a0bf528SMauro Carvalho Chehab 
38489a0bf528SMauro Carvalho Chehab 	/*== Write channel settings to device =====================================*/
38499a0bf528SMauro Carvalho Chehab 
38509a0bf528SMauro Carvalho Chehab 	/* mode */
38519a0bf528SMauro Carvalho Chehab 	switch (state->props.transmission_mode) {
38529a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_AUTO:
38539a0bf528SMauro Carvalho Chehab 	default:
38549a0bf528SMauro Carvalho Chehab 		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
38559a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_FFTMODE_8K */
38569a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_8K:
38579a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
38589a0bf528SMauro Carvalho Chehab 		break;
38599a0bf528SMauro Carvalho Chehab 	case TRANSMISSION_MODE_2K:
38609a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
38619a0bf528SMauro Carvalho Chehab 		break;
38629a0bf528SMauro Carvalho Chehab 	}
38639a0bf528SMauro Carvalho Chehab 
38649a0bf528SMauro Carvalho Chehab 	/* guard */
38659a0bf528SMauro Carvalho Chehab 	switch (state->props.guard_interval) {
38669a0bf528SMauro Carvalho Chehab 	default:
38679a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_AUTO:
38689a0bf528SMauro Carvalho Chehab 		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
38699a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_GUARD_1DIV4 */
38709a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_4:
38719a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
38729a0bf528SMauro Carvalho Chehab 		break;
38739a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_32:
38749a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
38759a0bf528SMauro Carvalho Chehab 		break;
38769a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_16:
38779a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
38789a0bf528SMauro Carvalho Chehab 		break;
38799a0bf528SMauro Carvalho Chehab 	case GUARD_INTERVAL_1_8:
38809a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
38819a0bf528SMauro Carvalho Chehab 		break;
38829a0bf528SMauro Carvalho Chehab 	}
38839a0bf528SMauro Carvalho Chehab 
38849a0bf528SMauro Carvalho Chehab 	/* hierarchy */
38859a0bf528SMauro Carvalho Chehab 	switch (state->props.hierarchy) {
38869a0bf528SMauro Carvalho Chehab 	case HIERARCHY_AUTO:
38879a0bf528SMauro Carvalho Chehab 	case HIERARCHY_NONE:
38889a0bf528SMauro Carvalho Chehab 	default:
38899a0bf528SMauro Carvalho Chehab 		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
38909a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
38919a0bf528SMauro Carvalho Chehab 		/* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
38929a0bf528SMauro Carvalho Chehab 		/* break; */
38939a0bf528SMauro Carvalho Chehab 	case HIERARCHY_1:
38949a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
38959a0bf528SMauro Carvalho Chehab 		break;
38969a0bf528SMauro Carvalho Chehab 	case HIERARCHY_2:
38979a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
38989a0bf528SMauro Carvalho Chehab 		break;
38999a0bf528SMauro Carvalho Chehab 	case HIERARCHY_4:
39009a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
39019a0bf528SMauro Carvalho Chehab 		break;
39029a0bf528SMauro Carvalho Chehab 	}
39039a0bf528SMauro Carvalho Chehab 
39049a0bf528SMauro Carvalho Chehab 
39059a0bf528SMauro Carvalho Chehab 	/* modulation */
39069a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
39079a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
39089a0bf528SMauro Carvalho Chehab 	default:
39099a0bf528SMauro Carvalho Chehab 		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
39109a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
39119a0bf528SMauro Carvalho Chehab 	case QAM_64:
39129a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
39139a0bf528SMauro Carvalho Chehab 		break;
39149a0bf528SMauro Carvalho Chehab 	case QPSK:
39159a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
39169a0bf528SMauro Carvalho Chehab 		break;
39179a0bf528SMauro Carvalho Chehab 	case QAM_16:
39189a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
39199a0bf528SMauro Carvalho Chehab 		break;
39209a0bf528SMauro Carvalho Chehab 	}
39219a0bf528SMauro Carvalho Chehab #if 0
39229a0bf528SMauro Carvalho Chehab 	/* No hierachical channels support in BDA */
39239a0bf528SMauro Carvalho Chehab 	/* Priority (only for hierarchical channels) */
39249a0bf528SMauro Carvalho Chehab 	switch (channel->priority) {
39259a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_LOW:
39269a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
39279a0bf528SMauro Carvalho Chehab 		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
39289a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_LO);
39299a0bf528SMauro Carvalho Chehab 		break;
39309a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_HIGH:
39319a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
39329a0bf528SMauro Carvalho Chehab 		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
39339a0bf528SMauro Carvalho Chehab 			OFDM_EC_SB_PRIOR_HI));
39349a0bf528SMauro Carvalho Chehab 		break;
39359a0bf528SMauro Carvalho Chehab 	case DRX_PRIORITY_UNKNOWN:	/* fall through */
39369a0bf528SMauro Carvalho Chehab 	default:
39379a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
39389a0bf528SMauro Carvalho Chehab 		goto error;
39399a0bf528SMauro Carvalho Chehab 	}
39409a0bf528SMauro Carvalho Chehab #else
39419a0bf528SMauro Carvalho Chehab 	/* Set Priorty high */
39429a0bf528SMauro Carvalho Chehab 	transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
39439a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
39449a0bf528SMauro Carvalho Chehab 	if (status < 0)
39459a0bf528SMauro Carvalho Chehab 		goto error;
39469a0bf528SMauro Carvalho Chehab #endif
39479a0bf528SMauro Carvalho Chehab 
39489a0bf528SMauro Carvalho Chehab 	/* coderate */
39499a0bf528SMauro Carvalho Chehab 	switch (state->props.code_rate_HP) {
39509a0bf528SMauro Carvalho Chehab 	case FEC_AUTO:
39519a0bf528SMauro Carvalho Chehab 	default:
39529a0bf528SMauro Carvalho Chehab 		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
39539a0bf528SMauro Carvalho Chehab 		/* fall through , try first guess DRX_CODERATE_2DIV3 */
39549a0bf528SMauro Carvalho Chehab 	case FEC_2_3:
39559a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
39569a0bf528SMauro Carvalho Chehab 		break;
39579a0bf528SMauro Carvalho Chehab 	case FEC_1_2:
39589a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
39599a0bf528SMauro Carvalho Chehab 		break;
39609a0bf528SMauro Carvalho Chehab 	case FEC_3_4:
39619a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
39629a0bf528SMauro Carvalho Chehab 		break;
39639a0bf528SMauro Carvalho Chehab 	case FEC_5_6:
39649a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
39659a0bf528SMauro Carvalho Chehab 		break;
39669a0bf528SMauro Carvalho Chehab 	case FEC_7_8:
39679a0bf528SMauro Carvalho Chehab 		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
39689a0bf528SMauro Carvalho Chehab 		break;
39699a0bf528SMauro Carvalho Chehab 	}
39709a0bf528SMauro Carvalho Chehab 
39719a0bf528SMauro Carvalho Chehab 	/* SAW filter selection: normaly not necesarry, but if wanted
39729a0bf528SMauro Carvalho Chehab 		the application can select a SAW filter via the driver by using UIOs */
39739a0bf528SMauro Carvalho Chehab 	/* First determine real bandwidth (Hz) */
39749a0bf528SMauro Carvalho Chehab 	/* Also set delay for impulse noise cruncher */
39759a0bf528SMauro Carvalho Chehab 	/* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
39769a0bf528SMauro Carvalho Chehab 		by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
39779a0bf528SMauro Carvalho Chehab 		functions */
39789a0bf528SMauro Carvalho Chehab 	switch (state->props.bandwidth_hz) {
39799a0bf528SMauro Carvalho Chehab 	case 0:
39809a0bf528SMauro Carvalho Chehab 		state->props.bandwidth_hz = 8000000;
39819a0bf528SMauro Carvalho Chehab 		/* fall though */
39829a0bf528SMauro Carvalho Chehab 	case 8000000:
39839a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
39849a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
39859a0bf528SMauro Carvalho Chehab 		if (status < 0)
39869a0bf528SMauro Carvalho Chehab 			goto error;
39879a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 8 MHz */
39889a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
39899a0bf528SMauro Carvalho Chehab 		if (status < 0)
39909a0bf528SMauro Carvalho Chehab 			goto error;
39919a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
39929a0bf528SMauro Carvalho Chehab 		if (status < 0)
39939a0bf528SMauro Carvalho Chehab 			goto error;
39949a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
39959a0bf528SMauro Carvalho Chehab 		if (status < 0)
39969a0bf528SMauro Carvalho Chehab 			goto error;
39979a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
39989a0bf528SMauro Carvalho Chehab 		if (status < 0)
39999a0bf528SMauro Carvalho Chehab 			goto error;
40009a0bf528SMauro Carvalho Chehab 		break;
40019a0bf528SMauro Carvalho Chehab 	case 7000000:
40029a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
40039a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
40049a0bf528SMauro Carvalho Chehab 		if (status < 0)
40059a0bf528SMauro Carvalho Chehab 			goto error;
40069a0bf528SMauro Carvalho Chehab 		/* cochannel protection for PAL 7 MHz */
40079a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
40089a0bf528SMauro Carvalho Chehab 		if (status < 0)
40099a0bf528SMauro Carvalho Chehab 			goto error;
40109a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
40119a0bf528SMauro Carvalho Chehab 		if (status < 0)
40129a0bf528SMauro Carvalho Chehab 			goto error;
40139a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
40149a0bf528SMauro Carvalho Chehab 		if (status < 0)
40159a0bf528SMauro Carvalho Chehab 			goto error;
40169a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
40179a0bf528SMauro Carvalho Chehab 		if (status < 0)
40189a0bf528SMauro Carvalho Chehab 			goto error;
40199a0bf528SMauro Carvalho Chehab 		break;
40209a0bf528SMauro Carvalho Chehab 	case 6000000:
40219a0bf528SMauro Carvalho Chehab 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
40229a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
40239a0bf528SMauro Carvalho Chehab 		if (status < 0)
40249a0bf528SMauro Carvalho Chehab 			goto error;
40259a0bf528SMauro Carvalho Chehab 		/* cochannel protection for NTSC 6 MHz */
40269a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
40279a0bf528SMauro Carvalho Chehab 		if (status < 0)
40289a0bf528SMauro Carvalho Chehab 			goto error;
40299a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
40309a0bf528SMauro Carvalho Chehab 		if (status < 0)
40319a0bf528SMauro Carvalho Chehab 			goto error;
40329a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
40339a0bf528SMauro Carvalho Chehab 		if (status < 0)
40349a0bf528SMauro Carvalho Chehab 			goto error;
40359a0bf528SMauro Carvalho Chehab 		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
40369a0bf528SMauro Carvalho Chehab 		if (status < 0)
40379a0bf528SMauro Carvalho Chehab 			goto error;
40389a0bf528SMauro Carvalho Chehab 		break;
40399a0bf528SMauro Carvalho Chehab 	default:
40409a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
40419a0bf528SMauro Carvalho Chehab 		goto error;
40429a0bf528SMauro Carvalho Chehab 	}
40439a0bf528SMauro Carvalho Chehab 
40449a0bf528SMauro Carvalho Chehab 	if (iqmRcRateOfs == 0) {
40459a0bf528SMauro Carvalho Chehab 		/* Now compute IQM_RC_RATE_OFS
40469a0bf528SMauro Carvalho Chehab 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
40479a0bf528SMauro Carvalho Chehab 			=>
40489a0bf528SMauro Carvalho Chehab 			((SysFreq / BandWidth) * (2^21)) - (2^23)
40499a0bf528SMauro Carvalho Chehab 			*/
40509a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^28)  */
40519a0bf528SMauro Carvalho Chehab 		/* assert (MAX(sysClk)/MIN(bandwidth) < 16)
40529a0bf528SMauro Carvalho Chehab 			=> assert(MAX(sysClk) < 16*MIN(bandwidth))
40539a0bf528SMauro Carvalho Chehab 			=> assert(109714272 > 48000000) = true so Frac 28 can be used  */
40549a0bf528SMauro Carvalho Chehab 		iqmRcRateOfs = Frac28a((u32)
40559a0bf528SMauro Carvalho Chehab 					((state->m_sysClockFreq *
40569a0bf528SMauro Carvalho Chehab 						1000) / 3), bandwidth);
40579a0bf528SMauro Carvalho Chehab 		/* (SysFreq / BandWidth) * (2^21), rounding before truncating  */
40589a0bf528SMauro Carvalho Chehab 		if ((iqmRcRateOfs & 0x7fL) >= 0x40)
40599a0bf528SMauro Carvalho Chehab 			iqmRcRateOfs += 0x80L;
40609a0bf528SMauro Carvalho Chehab 		iqmRcRateOfs = iqmRcRateOfs >> 7;
40619a0bf528SMauro Carvalho Chehab 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
40629a0bf528SMauro Carvalho Chehab 		iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
40639a0bf528SMauro Carvalho Chehab 	}
40649a0bf528SMauro Carvalho Chehab 
40659a0bf528SMauro Carvalho Chehab 	iqmRcRateOfs &=
40669a0bf528SMauro Carvalho Chehab 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
40679a0bf528SMauro Carvalho Chehab 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
40689a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
40699a0bf528SMauro Carvalho Chehab 	if (status < 0)
40709a0bf528SMauro Carvalho Chehab 		goto error;
40719a0bf528SMauro Carvalho Chehab 
40729a0bf528SMauro Carvalho Chehab 	/* Bandwidth setting done */
40739a0bf528SMauro Carvalho Chehab 
40749a0bf528SMauro Carvalho Chehab #if 0
40759a0bf528SMauro Carvalho Chehab 	status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
40769a0bf528SMauro Carvalho Chehab 	if (status < 0)
40779a0bf528SMauro Carvalho Chehab 		goto error;
40789a0bf528SMauro Carvalho Chehab #endif
40799a0bf528SMauro Carvalho Chehab 	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
40809a0bf528SMauro Carvalho Chehab 	if (status < 0)
40819a0bf528SMauro Carvalho Chehab 		goto error;
40829a0bf528SMauro Carvalho Chehab 
40839a0bf528SMauro Carvalho Chehab 	/*== Start SC, write channel settings to SC ===============================*/
40849a0bf528SMauro Carvalho Chehab 
40859a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
40869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
40879a0bf528SMauro Carvalho Chehab 	if (status < 0)
40889a0bf528SMauro Carvalho Chehab 		goto error;
40899a0bf528SMauro Carvalho Chehab 
40909a0bf528SMauro Carvalho Chehab 	/* Enable SC after setting all other parameters */
40919a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_STATE__A, 0);
40929a0bf528SMauro Carvalho Chehab 	if (status < 0)
40939a0bf528SMauro Carvalho Chehab 		goto error;
40949a0bf528SMauro Carvalho Chehab 	status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
40959a0bf528SMauro Carvalho Chehab 	if (status < 0)
40969a0bf528SMauro Carvalho Chehab 		goto error;
40979a0bf528SMauro Carvalho Chehab 
40989a0bf528SMauro Carvalho Chehab 
40999a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
41009a0bf528SMauro Carvalho Chehab 	if (status < 0)
41019a0bf528SMauro Carvalho Chehab 		goto error;
41029a0bf528SMauro Carvalho Chehab 
41039a0bf528SMauro Carvalho Chehab 	/* Write SC parameter registers, set all AUTO flags in operation mode */
41049a0bf528SMauro Carvalho Chehab 	param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
41059a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
41069a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
41079a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
41089a0bf528SMauro Carvalho Chehab 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
41099a0bf528SMauro Carvalho Chehab 	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
41109a0bf528SMauro Carvalho Chehab 				0, transmissionParams, param1, 0, 0, 0);
41119a0bf528SMauro Carvalho Chehab 	if (status < 0)
41129a0bf528SMauro Carvalho Chehab 		goto error;
41139a0bf528SMauro Carvalho Chehab 
41149a0bf528SMauro Carvalho Chehab 	if (!state->m_DRXK_A3_ROM_CODE)
41159a0bf528SMauro Carvalho Chehab 		status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
41169a0bf528SMauro Carvalho Chehab error:
41179a0bf528SMauro Carvalho Chehab 	if (status < 0)
41189a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
41199a0bf528SMauro Carvalho Chehab 
41209a0bf528SMauro Carvalho Chehab 	return status;
41219a0bf528SMauro Carvalho Chehab }
41229a0bf528SMauro Carvalho Chehab 
41239a0bf528SMauro Carvalho Chehab 
41249a0bf528SMauro Carvalho Chehab /*============================================================================*/
41259a0bf528SMauro Carvalho Chehab 
41269a0bf528SMauro Carvalho Chehab /**
41279a0bf528SMauro Carvalho Chehab * \brief Retreive lock status .
41289a0bf528SMauro Carvalho Chehab * \param demod    Pointer to demodulator instance.
41299a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
41309a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41319a0bf528SMauro Carvalho Chehab *
41329a0bf528SMauro Carvalho Chehab */
41339a0bf528SMauro Carvalho Chehab static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
41349a0bf528SMauro Carvalho Chehab {
41359a0bf528SMauro Carvalho Chehab 	int status;
41369a0bf528SMauro Carvalho Chehab 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
41379a0bf528SMauro Carvalho Chehab 				    OFDM_SC_RA_RAM_LOCK_FEC__M);
41389a0bf528SMauro Carvalho Chehab 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
41399a0bf528SMauro Carvalho Chehab 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
41409a0bf528SMauro Carvalho Chehab 
41419a0bf528SMauro Carvalho Chehab 	u16 ScRaRamLock = 0;
41429a0bf528SMauro Carvalho Chehab 	u16 ScCommExec = 0;
41439a0bf528SMauro Carvalho Chehab 
41449a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41459a0bf528SMauro Carvalho Chehab 
41469a0bf528SMauro Carvalho Chehab 	*pLockStatus = NOT_LOCKED;
41479a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
41489a0bf528SMauro Carvalho Chehab 	/* Check if SC is running */
41499a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
41509a0bf528SMauro Carvalho Chehab 	if (status < 0)
41519a0bf528SMauro Carvalho Chehab 		goto end;
41529a0bf528SMauro Carvalho Chehab 	if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
41539a0bf528SMauro Carvalho Chehab 		goto end;
41549a0bf528SMauro Carvalho Chehab 
41559a0bf528SMauro Carvalho Chehab 	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
41569a0bf528SMauro Carvalho Chehab 	if (status < 0)
41579a0bf528SMauro Carvalho Chehab 		goto end;
41589a0bf528SMauro Carvalho Chehab 
41599a0bf528SMauro Carvalho Chehab 	if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
41609a0bf528SMauro Carvalho Chehab 		*pLockStatus = MPEG_LOCK;
41619a0bf528SMauro Carvalho Chehab 	else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
41629a0bf528SMauro Carvalho Chehab 		*pLockStatus = FEC_LOCK;
41639a0bf528SMauro Carvalho Chehab 	else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
41649a0bf528SMauro Carvalho Chehab 		*pLockStatus = DEMOD_LOCK;
41659a0bf528SMauro Carvalho Chehab 	else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
41669a0bf528SMauro Carvalho Chehab 		*pLockStatus = NEVER_LOCK;
41679a0bf528SMauro Carvalho Chehab end:
41689a0bf528SMauro Carvalho Chehab 	if (status < 0)
41699a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
41709a0bf528SMauro Carvalho Chehab 
41719a0bf528SMauro Carvalho Chehab 	return status;
41729a0bf528SMauro Carvalho Chehab }
41739a0bf528SMauro Carvalho Chehab 
41749a0bf528SMauro Carvalho Chehab static int PowerUpQAM(struct drxk_state *state)
41759a0bf528SMauro Carvalho Chehab {
41769a0bf528SMauro Carvalho Chehab 	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
41779a0bf528SMauro Carvalho Chehab 	int status;
41789a0bf528SMauro Carvalho Chehab 
41799a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41809a0bf528SMauro Carvalho Chehab 	status = CtrlPowerMode(state, &powerMode);
41819a0bf528SMauro Carvalho Chehab 	if (status < 0)
41829a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: 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 /** Power Down QAM */
41899a0bf528SMauro Carvalho Chehab static int PowerDownQAM(struct drxk_state *state)
41909a0bf528SMauro Carvalho Chehab {
41919a0bf528SMauro Carvalho Chehab 	u16 data = 0;
41929a0bf528SMauro Carvalho Chehab 	u16 cmdResult;
41939a0bf528SMauro Carvalho Chehab 	int status = 0;
41949a0bf528SMauro Carvalho Chehab 
41959a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
41969a0bf528SMauro Carvalho Chehab 	status = read16(state, SCU_COMM_EXEC__A, &data);
41979a0bf528SMauro Carvalho Chehab 	if (status < 0)
41989a0bf528SMauro Carvalho Chehab 		goto error;
41999a0bf528SMauro Carvalho Chehab 	if (data == SCU_COMM_EXEC_ACTIVE) {
42009a0bf528SMauro Carvalho Chehab 		/*
42019a0bf528SMauro Carvalho Chehab 			STOP demodulator
42029a0bf528SMauro Carvalho Chehab 			QAM and HW blocks
42039a0bf528SMauro Carvalho Chehab 			*/
42049a0bf528SMauro Carvalho Chehab 		/* stop all comstate->m_exec */
42059a0bf528SMauro Carvalho Chehab 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
42069a0bf528SMauro Carvalho Chehab 		if (status < 0)
42079a0bf528SMauro Carvalho Chehab 			goto error;
42089a0bf528SMauro Carvalho Chehab 		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
42099a0bf528SMauro Carvalho Chehab 		if (status < 0)
42109a0bf528SMauro Carvalho Chehab 			goto error;
42119a0bf528SMauro Carvalho Chehab 	}
42129a0bf528SMauro Carvalho Chehab 	/* powerdown AFE                   */
42139a0bf528SMauro Carvalho Chehab 	status = SetIqmAf(state, false);
42149a0bf528SMauro Carvalho Chehab 
42159a0bf528SMauro Carvalho Chehab error:
42169a0bf528SMauro Carvalho Chehab 	if (status < 0)
42179a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
42189a0bf528SMauro Carvalho Chehab 
42199a0bf528SMauro Carvalho Chehab 	return status;
42209a0bf528SMauro Carvalho Chehab }
42219a0bf528SMauro Carvalho Chehab 
42229a0bf528SMauro Carvalho Chehab /*============================================================================*/
42239a0bf528SMauro Carvalho Chehab 
42249a0bf528SMauro Carvalho Chehab /**
42259a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
42269a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
42279a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
42289a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
42299a0bf528SMauro Carvalho Chehab *
42309a0bf528SMauro Carvalho Chehab *  NOTE:
42319a0bf528SMauro Carvalho Chehab *  Take into account that for certain settings the errorcounters can overflow.
42329a0bf528SMauro Carvalho Chehab *  The implementation does not check this.
42339a0bf528SMauro Carvalho Chehab *
42349a0bf528SMauro Carvalho Chehab */
42359a0bf528SMauro Carvalho Chehab static int SetQAMMeasurement(struct drxk_state *state,
42369a0bf528SMauro Carvalho Chehab 			     enum EDrxkConstellation modulation,
42379a0bf528SMauro Carvalho Chehab 			     u32 symbolRate)
42389a0bf528SMauro Carvalho Chehab {
42399a0bf528SMauro Carvalho Chehab 	u32 fecBitsDesired = 0;	/* BER accounting period */
42409a0bf528SMauro Carvalho Chehab 	u32 fecRsPeriodTotal = 0;	/* Total period */
42419a0bf528SMauro Carvalho Chehab 	u16 fecRsPrescale = 0;	/* ReedSolomon Measurement Prescale */
42429a0bf528SMauro Carvalho Chehab 	u16 fecRsPeriod = 0;	/* Value for corresponding I2C register */
42439a0bf528SMauro Carvalho Chehab 	int status = 0;
42449a0bf528SMauro Carvalho Chehab 
42459a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
42469a0bf528SMauro Carvalho Chehab 
42479a0bf528SMauro Carvalho Chehab 	fecRsPrescale = 1;
42489a0bf528SMauro Carvalho Chehab 	/* fecBitsDesired = symbolRate [kHz] *
42499a0bf528SMauro Carvalho Chehab 		FrameLenght [ms] *
42509a0bf528SMauro Carvalho Chehab 		(modulation + 1) *
42519a0bf528SMauro Carvalho Chehab 		SyncLoss (== 1) *
42529a0bf528SMauro Carvalho Chehab 		ViterbiLoss (==1)
42539a0bf528SMauro Carvalho Chehab 		*/
42549a0bf528SMauro Carvalho Chehab 	switch (modulation) {
42559a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM16:
42569a0bf528SMauro Carvalho Chehab 		fecBitsDesired = 4 * symbolRate;
42579a0bf528SMauro Carvalho Chehab 		break;
42589a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM32:
42599a0bf528SMauro Carvalho Chehab 		fecBitsDesired = 5 * symbolRate;
42609a0bf528SMauro Carvalho Chehab 		break;
42619a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM64:
42629a0bf528SMauro Carvalho Chehab 		fecBitsDesired = 6 * symbolRate;
42639a0bf528SMauro Carvalho Chehab 		break;
42649a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM128:
42659a0bf528SMauro Carvalho Chehab 		fecBitsDesired = 7 * symbolRate;
42669a0bf528SMauro Carvalho Chehab 		break;
42679a0bf528SMauro Carvalho Chehab 	case DRX_CONSTELLATION_QAM256:
42689a0bf528SMauro Carvalho Chehab 		fecBitsDesired = 8 * symbolRate;
42699a0bf528SMauro Carvalho Chehab 		break;
42709a0bf528SMauro Carvalho Chehab 	default:
42719a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42729a0bf528SMauro Carvalho Chehab 	}
42739a0bf528SMauro Carvalho Chehab 	if (status < 0)
42749a0bf528SMauro Carvalho Chehab 		goto error;
42759a0bf528SMauro Carvalho Chehab 
42769a0bf528SMauro Carvalho Chehab 	fecBitsDesired /= 1000;	/* symbolRate [Hz] -> symbolRate [kHz]  */
42779a0bf528SMauro Carvalho Chehab 	fecBitsDesired *= 500;	/* meas. period [ms] */
42789a0bf528SMauro Carvalho Chehab 
42799a0bf528SMauro Carvalho Chehab 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
42809a0bf528SMauro Carvalho Chehab 	/* fecRsPeriodTotal = fecBitsDesired / 1632 */
42819a0bf528SMauro Carvalho Chehab 	fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1;	/* roughly ceil */
42829a0bf528SMauro Carvalho Chehab 
42839a0bf528SMauro Carvalho Chehab 	/* fecRsPeriodTotal =  fecRsPrescale * fecRsPeriod  */
42849a0bf528SMauro Carvalho Chehab 	fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
42859a0bf528SMauro Carvalho Chehab 	if (fecRsPrescale == 0) {
42869a0bf528SMauro Carvalho Chehab 		/* Divide by zero (though impossible) */
42879a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
42889a0bf528SMauro Carvalho Chehab 		if (status < 0)
42899a0bf528SMauro Carvalho Chehab 			goto error;
42909a0bf528SMauro Carvalho Chehab 	}
42919a0bf528SMauro Carvalho Chehab 	fecRsPeriod =
42929a0bf528SMauro Carvalho Chehab 		((u16) fecRsPeriodTotal +
42939a0bf528SMauro Carvalho Chehab 		(fecRsPrescale >> 1)) / fecRsPrescale;
42949a0bf528SMauro Carvalho Chehab 
42959a0bf528SMauro Carvalho Chehab 	/* write corresponding registers */
42969a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
42979a0bf528SMauro Carvalho Chehab 	if (status < 0)
42989a0bf528SMauro Carvalho Chehab 		goto error;
42999a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
43009a0bf528SMauro Carvalho Chehab 	if (status < 0)
43019a0bf528SMauro Carvalho Chehab 		goto error;
43029a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
43039a0bf528SMauro Carvalho Chehab error:
43049a0bf528SMauro Carvalho Chehab 	if (status < 0)
43059a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
43069a0bf528SMauro Carvalho Chehab 	return status;
43079a0bf528SMauro Carvalho Chehab }
43089a0bf528SMauro Carvalho Chehab 
43099a0bf528SMauro Carvalho Chehab static int SetQAM16(struct drxk_state *state)
43109a0bf528SMauro Carvalho Chehab {
43119a0bf528SMauro Carvalho Chehab 	int status = 0;
43129a0bf528SMauro Carvalho Chehab 
43139a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
43149a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
43159a0bf528SMauro Carvalho Chehab 	/* Equalizer */
43169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
43179a0bf528SMauro Carvalho Chehab 	if (status < 0)
43189a0bf528SMauro Carvalho Chehab 		goto error;
43199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
43209a0bf528SMauro Carvalho Chehab 	if (status < 0)
43219a0bf528SMauro Carvalho Chehab 		goto error;
43229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
43239a0bf528SMauro Carvalho Chehab 	if (status < 0)
43249a0bf528SMauro Carvalho Chehab 		goto error;
43259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
43269a0bf528SMauro Carvalho Chehab 	if (status < 0)
43279a0bf528SMauro Carvalho Chehab 		goto error;
43289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
43299a0bf528SMauro Carvalho Chehab 	if (status < 0)
43309a0bf528SMauro Carvalho Chehab 		goto error;
43319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
43329a0bf528SMauro Carvalho Chehab 	if (status < 0)
43339a0bf528SMauro Carvalho Chehab 		goto error;
43349a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
43359a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
43369a0bf528SMauro Carvalho Chehab 	if (status < 0)
43379a0bf528SMauro Carvalho Chehab 		goto error;
43389a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
43399a0bf528SMauro Carvalho Chehab 	if (status < 0)
43409a0bf528SMauro Carvalho Chehab 		goto error;
43419a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
43429a0bf528SMauro Carvalho Chehab 	if (status < 0)
43439a0bf528SMauro Carvalho Chehab 		goto error;
43449a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
43459a0bf528SMauro Carvalho Chehab 	if (status < 0)
43469a0bf528SMauro Carvalho Chehab 		goto error;
43479a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
43489a0bf528SMauro Carvalho Chehab 	if (status < 0)
43499a0bf528SMauro Carvalho Chehab 		goto error;
43509a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
43519a0bf528SMauro Carvalho Chehab 	if (status < 0)
43529a0bf528SMauro Carvalho Chehab 		goto error;
43539a0bf528SMauro Carvalho Chehab 
43549a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
43559a0bf528SMauro Carvalho Chehab 	if (status < 0)
43569a0bf528SMauro Carvalho Chehab 		goto error;
43579a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
43589a0bf528SMauro Carvalho Chehab 	if (status < 0)
43599a0bf528SMauro Carvalho Chehab 		goto error;
43609a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
43619a0bf528SMauro Carvalho Chehab 	if (status < 0)
43629a0bf528SMauro Carvalho Chehab 		goto error;
43639a0bf528SMauro Carvalho Chehab 
43649a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
43659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
43669a0bf528SMauro Carvalho Chehab 	if (status < 0)
43679a0bf528SMauro Carvalho Chehab 		goto error;
43689a0bf528SMauro Carvalho Chehab 
43699a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
43709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
43719a0bf528SMauro Carvalho Chehab 	if (status < 0)
43729a0bf528SMauro Carvalho Chehab 		goto error;
43739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
43749a0bf528SMauro Carvalho Chehab 	if (status < 0)
43759a0bf528SMauro Carvalho Chehab 		goto error;
43769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
43779a0bf528SMauro Carvalho Chehab 	if (status < 0)
43789a0bf528SMauro Carvalho Chehab 		goto error;
43799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
43809a0bf528SMauro Carvalho Chehab 	if (status < 0)
43819a0bf528SMauro Carvalho Chehab 		goto error;
43829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
43839a0bf528SMauro Carvalho Chehab 	if (status < 0)
43849a0bf528SMauro Carvalho Chehab 		goto error;
43859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
43869a0bf528SMauro Carvalho Chehab 	if (status < 0)
43879a0bf528SMauro Carvalho Chehab 		goto error;
43889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
43899a0bf528SMauro Carvalho Chehab 	if (status < 0)
43909a0bf528SMauro Carvalho Chehab 		goto error;
43919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43929a0bf528SMauro Carvalho Chehab 	if (status < 0)
43939a0bf528SMauro Carvalho Chehab 		goto error;
43949a0bf528SMauro Carvalho Chehab 
43959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43969a0bf528SMauro Carvalho Chehab 	if (status < 0)
43979a0bf528SMauro Carvalho Chehab 		goto error;
43989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43999a0bf528SMauro Carvalho Chehab 	if (status < 0)
44009a0bf528SMauro Carvalho Chehab 		goto error;
44019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
44029a0bf528SMauro Carvalho Chehab 	if (status < 0)
44039a0bf528SMauro Carvalho Chehab 		goto error;
44049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
44059a0bf528SMauro Carvalho Chehab 	if (status < 0)
44069a0bf528SMauro Carvalho Chehab 		goto error;
44079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
44089a0bf528SMauro Carvalho Chehab 	if (status < 0)
44099a0bf528SMauro Carvalho Chehab 		goto error;
44109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
44119a0bf528SMauro Carvalho Chehab 	if (status < 0)
44129a0bf528SMauro Carvalho Chehab 		goto error;
44139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
44149a0bf528SMauro Carvalho Chehab 	if (status < 0)
44159a0bf528SMauro Carvalho Chehab 		goto error;
44169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
44179a0bf528SMauro Carvalho Chehab 	if (status < 0)
44189a0bf528SMauro Carvalho Chehab 		goto error;
44199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
44209a0bf528SMauro Carvalho Chehab 	if (status < 0)
44219a0bf528SMauro Carvalho Chehab 		goto error;
44229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
44239a0bf528SMauro Carvalho Chehab 	if (status < 0)
44249a0bf528SMauro Carvalho Chehab 		goto error;
44259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
44269a0bf528SMauro Carvalho Chehab 	if (status < 0)
44279a0bf528SMauro Carvalho Chehab 		goto error;
44289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
44299a0bf528SMauro Carvalho Chehab 	if (status < 0)
44309a0bf528SMauro Carvalho Chehab 		goto error;
44319a0bf528SMauro Carvalho Chehab 
44329a0bf528SMauro Carvalho Chehab 
44339a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
44349a0bf528SMauro Carvalho Chehab 
44359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
44369a0bf528SMauro Carvalho Chehab 	if (status < 0)
44379a0bf528SMauro Carvalho Chehab 		goto error;
44389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
44399a0bf528SMauro Carvalho Chehab 	if (status < 0)
44409a0bf528SMauro Carvalho Chehab 		goto error;
44419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
44429a0bf528SMauro Carvalho Chehab 	if (status < 0)
44439a0bf528SMauro Carvalho Chehab 		goto error;
44449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
44459a0bf528SMauro Carvalho Chehab 	if (status < 0)
44469a0bf528SMauro Carvalho Chehab 		goto error;
44479a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
44489a0bf528SMauro Carvalho Chehab 	if (status < 0)
44499a0bf528SMauro Carvalho Chehab 		goto error;
44509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
44519a0bf528SMauro Carvalho Chehab 	if (status < 0)
44529a0bf528SMauro Carvalho Chehab 		goto error;
44539a0bf528SMauro Carvalho Chehab 
44549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
44559a0bf528SMauro Carvalho Chehab 	if (status < 0)
44569a0bf528SMauro Carvalho Chehab 		goto error;
44579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
44589a0bf528SMauro Carvalho Chehab 	if (status < 0)
44599a0bf528SMauro Carvalho Chehab 		goto error;
44609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
44619a0bf528SMauro Carvalho Chehab 	if (status < 0)
44629a0bf528SMauro Carvalho Chehab 		goto error;
44639a0bf528SMauro Carvalho Chehab 
44649a0bf528SMauro Carvalho Chehab 
44659a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
44669a0bf528SMauro Carvalho Chehab 
44679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
44689a0bf528SMauro Carvalho Chehab 	if (status < 0)
44699a0bf528SMauro Carvalho Chehab 		goto error;
44709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
44719a0bf528SMauro Carvalho Chehab 	if (status < 0)
44729a0bf528SMauro Carvalho Chehab 		goto error;
44739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
44749a0bf528SMauro Carvalho Chehab 	if (status < 0)
44759a0bf528SMauro Carvalho Chehab 		goto error;
44769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
44779a0bf528SMauro Carvalho Chehab 	if (status < 0)
44789a0bf528SMauro Carvalho Chehab 		goto error;
44799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
44809a0bf528SMauro Carvalho Chehab 	if (status < 0)
44819a0bf528SMauro Carvalho Chehab 		goto error;
44829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
44839a0bf528SMauro Carvalho Chehab 	if (status < 0)
44849a0bf528SMauro Carvalho Chehab 		goto error;
44859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
44869a0bf528SMauro Carvalho Chehab 	if (status < 0)
44879a0bf528SMauro Carvalho Chehab 		goto error;
44889a0bf528SMauro Carvalho Chehab 
44899a0bf528SMauro Carvalho Chehab error:
44909a0bf528SMauro Carvalho Chehab 	if (status < 0)
44919a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
44929a0bf528SMauro Carvalho Chehab 	return status;
44939a0bf528SMauro Carvalho Chehab }
44949a0bf528SMauro Carvalho Chehab 
44959a0bf528SMauro Carvalho Chehab /*============================================================================*/
44969a0bf528SMauro Carvalho Chehab 
44979a0bf528SMauro Carvalho Chehab /**
44989a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44999a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
45009a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
45019a0bf528SMauro Carvalho Chehab */
45029a0bf528SMauro Carvalho Chehab static int SetQAM32(struct drxk_state *state)
45039a0bf528SMauro Carvalho Chehab {
45049a0bf528SMauro Carvalho Chehab 	int status = 0;
45059a0bf528SMauro Carvalho Chehab 
45069a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
45079a0bf528SMauro Carvalho Chehab 
45089a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
45099a0bf528SMauro Carvalho Chehab 	/* Equalizer */
45109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
45119a0bf528SMauro Carvalho Chehab 	if (status < 0)
45129a0bf528SMauro Carvalho Chehab 		goto error;
45139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
45149a0bf528SMauro Carvalho Chehab 	if (status < 0)
45159a0bf528SMauro Carvalho Chehab 		goto error;
45169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
45179a0bf528SMauro Carvalho Chehab 	if (status < 0)
45189a0bf528SMauro Carvalho Chehab 		goto error;
45199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
45209a0bf528SMauro Carvalho Chehab 	if (status < 0)
45219a0bf528SMauro Carvalho Chehab 		goto error;
45229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
45239a0bf528SMauro Carvalho Chehab 	if (status < 0)
45249a0bf528SMauro Carvalho Chehab 		goto error;
45259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
45269a0bf528SMauro Carvalho Chehab 	if (status < 0)
45279a0bf528SMauro Carvalho Chehab 		goto error;
45289a0bf528SMauro Carvalho Chehab 
45299a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
45309a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
45319a0bf528SMauro Carvalho Chehab 	if (status < 0)
45329a0bf528SMauro Carvalho Chehab 		goto error;
45339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
45349a0bf528SMauro Carvalho Chehab 	if (status < 0)
45359a0bf528SMauro Carvalho Chehab 		goto error;
45369a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
45379a0bf528SMauro Carvalho Chehab 	if (status < 0)
45389a0bf528SMauro Carvalho Chehab 		goto error;
45399a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
45409a0bf528SMauro Carvalho Chehab 	if (status < 0)
45419a0bf528SMauro Carvalho Chehab 		goto error;
45429a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
45439a0bf528SMauro Carvalho Chehab 	if (status < 0)
45449a0bf528SMauro Carvalho Chehab 		goto error;
45459a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
45469a0bf528SMauro Carvalho Chehab 	if (status < 0)
45479a0bf528SMauro Carvalho Chehab 		goto error;
45489a0bf528SMauro Carvalho Chehab 
45499a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
45509a0bf528SMauro Carvalho Chehab 	if (status < 0)
45519a0bf528SMauro Carvalho Chehab 		goto error;
45529a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
45539a0bf528SMauro Carvalho Chehab 	if (status < 0)
45549a0bf528SMauro Carvalho Chehab 		goto error;
45559a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
45569a0bf528SMauro Carvalho Chehab 	if (status < 0)
45579a0bf528SMauro Carvalho Chehab 		goto error;
45589a0bf528SMauro Carvalho Chehab 
45599a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
45609a0bf528SMauro Carvalho Chehab 
45619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
45629a0bf528SMauro Carvalho Chehab 	if (status < 0)
45639a0bf528SMauro Carvalho Chehab 		goto error;
45649a0bf528SMauro Carvalho Chehab 
45659a0bf528SMauro Carvalho Chehab 
45669a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
45679a0bf528SMauro Carvalho Chehab 
45689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
45699a0bf528SMauro Carvalho Chehab 	if (status < 0)
45709a0bf528SMauro Carvalho Chehab 		goto error;
45719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
45729a0bf528SMauro Carvalho Chehab 	if (status < 0)
45739a0bf528SMauro Carvalho Chehab 		goto error;
45749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
45759a0bf528SMauro Carvalho Chehab 	if (status < 0)
45769a0bf528SMauro Carvalho Chehab 		goto error;
45779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
45789a0bf528SMauro Carvalho Chehab 	if (status < 0)
45799a0bf528SMauro Carvalho Chehab 		goto error;
45809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
45819a0bf528SMauro Carvalho Chehab 	if (status < 0)
45829a0bf528SMauro Carvalho Chehab 		goto error;
45839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
45849a0bf528SMauro Carvalho Chehab 	if (status < 0)
45859a0bf528SMauro Carvalho Chehab 		goto error;
45869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
45879a0bf528SMauro Carvalho Chehab 	if (status < 0)
45889a0bf528SMauro Carvalho Chehab 		goto error;
45899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
45909a0bf528SMauro Carvalho Chehab 	if (status < 0)
45919a0bf528SMauro Carvalho Chehab 		goto error;
45929a0bf528SMauro Carvalho Chehab 
45939a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45949a0bf528SMauro Carvalho Chehab 	if (status < 0)
45959a0bf528SMauro Carvalho Chehab 		goto error;
45969a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45979a0bf528SMauro Carvalho Chehab 	if (status < 0)
45989a0bf528SMauro Carvalho Chehab 		goto error;
45999a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
46009a0bf528SMauro Carvalho Chehab 	if (status < 0)
46019a0bf528SMauro Carvalho Chehab 		goto error;
46029a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
46039a0bf528SMauro Carvalho Chehab 	if (status < 0)
46049a0bf528SMauro Carvalho Chehab 		goto error;
46059a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
46069a0bf528SMauro Carvalho Chehab 	if (status < 0)
46079a0bf528SMauro Carvalho Chehab 		goto error;
46089a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
46099a0bf528SMauro Carvalho Chehab 	if (status < 0)
46109a0bf528SMauro Carvalho Chehab 		goto error;
46119a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
46129a0bf528SMauro Carvalho Chehab 	if (status < 0)
46139a0bf528SMauro Carvalho Chehab 		goto error;
46149a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
46159a0bf528SMauro Carvalho Chehab 	if (status < 0)
46169a0bf528SMauro Carvalho Chehab 		goto error;
46179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
46189a0bf528SMauro Carvalho Chehab 	if (status < 0)
46199a0bf528SMauro Carvalho Chehab 		goto error;
46209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
46219a0bf528SMauro Carvalho Chehab 	if (status < 0)
46229a0bf528SMauro Carvalho Chehab 		goto error;
46239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
46249a0bf528SMauro Carvalho Chehab 	if (status < 0)
46259a0bf528SMauro Carvalho Chehab 		goto error;
46269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
46279a0bf528SMauro Carvalho Chehab 	if (status < 0)
46289a0bf528SMauro Carvalho Chehab 		goto error;
46299a0bf528SMauro Carvalho Chehab 
46309a0bf528SMauro Carvalho Chehab 
46319a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
46329a0bf528SMauro Carvalho Chehab 
46339a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
46349a0bf528SMauro Carvalho Chehab 	if (status < 0)
46359a0bf528SMauro Carvalho Chehab 		goto error;
46369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
46379a0bf528SMauro Carvalho Chehab 	if (status < 0)
46389a0bf528SMauro Carvalho Chehab 		goto error;
46399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
46409a0bf528SMauro Carvalho Chehab 	if (status < 0)
46419a0bf528SMauro Carvalho Chehab 		goto error;
46429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
46439a0bf528SMauro Carvalho Chehab 	if (status < 0)
46449a0bf528SMauro Carvalho Chehab 		goto error;
46459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
46469a0bf528SMauro Carvalho Chehab 	if (status < 0)
46479a0bf528SMauro Carvalho Chehab 		goto error;
46489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
46499a0bf528SMauro Carvalho Chehab 	if (status < 0)
46509a0bf528SMauro Carvalho Chehab 		goto error;
46519a0bf528SMauro Carvalho Chehab 
46529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
46539a0bf528SMauro Carvalho Chehab 	if (status < 0)
46549a0bf528SMauro Carvalho Chehab 		goto error;
46559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
46569a0bf528SMauro Carvalho Chehab 	if (status < 0)
46579a0bf528SMauro Carvalho Chehab 		goto error;
46589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
46599a0bf528SMauro Carvalho Chehab 	if (status < 0)
46609a0bf528SMauro Carvalho Chehab 		goto error;
46619a0bf528SMauro Carvalho Chehab 
46629a0bf528SMauro Carvalho Chehab 
46639a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
46649a0bf528SMauro Carvalho Chehab 
46659a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
46669a0bf528SMauro Carvalho Chehab 	if (status < 0)
46679a0bf528SMauro Carvalho Chehab 		goto error;
46689a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
46699a0bf528SMauro Carvalho Chehab 	if (status < 0)
46709a0bf528SMauro Carvalho Chehab 		goto error;
46719a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
46729a0bf528SMauro Carvalho Chehab 	if (status < 0)
46739a0bf528SMauro Carvalho Chehab 		goto error;
46749a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
46759a0bf528SMauro Carvalho Chehab 	if (status < 0)
46769a0bf528SMauro Carvalho Chehab 		goto error;
46779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
46789a0bf528SMauro Carvalho Chehab 	if (status < 0)
46799a0bf528SMauro Carvalho Chehab 		goto error;
46809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
46819a0bf528SMauro Carvalho Chehab 	if (status < 0)
46829a0bf528SMauro Carvalho Chehab 		goto error;
46839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
46849a0bf528SMauro Carvalho Chehab error:
46859a0bf528SMauro Carvalho Chehab 	if (status < 0)
46869a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
46879a0bf528SMauro Carvalho Chehab 	return status;
46889a0bf528SMauro Carvalho Chehab }
46899a0bf528SMauro Carvalho Chehab 
46909a0bf528SMauro Carvalho Chehab /*============================================================================*/
46919a0bf528SMauro Carvalho Chehab 
46929a0bf528SMauro Carvalho Chehab /**
46939a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46949a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46959a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46969a0bf528SMauro Carvalho Chehab */
46979a0bf528SMauro Carvalho Chehab static int SetQAM64(struct drxk_state *state)
46989a0bf528SMauro Carvalho Chehab {
46999a0bf528SMauro Carvalho Chehab 	int status = 0;
47009a0bf528SMauro Carvalho Chehab 
47019a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
47029a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
47039a0bf528SMauro Carvalho Chehab 	/* Equalizer */
47049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
47059a0bf528SMauro Carvalho Chehab 	if (status < 0)
47069a0bf528SMauro Carvalho Chehab 		goto error;
47079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
47089a0bf528SMauro Carvalho Chehab 	if (status < 0)
47099a0bf528SMauro Carvalho Chehab 		goto error;
47109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
47119a0bf528SMauro Carvalho Chehab 	if (status < 0)
47129a0bf528SMauro Carvalho Chehab 		goto error;
47139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
47149a0bf528SMauro Carvalho Chehab 	if (status < 0)
47159a0bf528SMauro Carvalho Chehab 		goto error;
47169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
47179a0bf528SMauro Carvalho Chehab 	if (status < 0)
47189a0bf528SMauro Carvalho Chehab 		goto error;
47199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
47209a0bf528SMauro Carvalho Chehab 	if (status < 0)
47219a0bf528SMauro Carvalho Chehab 		goto error;
47229a0bf528SMauro Carvalho Chehab 
47239a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
47249a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
47259a0bf528SMauro Carvalho Chehab 	if (status < 0)
47269a0bf528SMauro Carvalho Chehab 		goto error;
47279a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
47289a0bf528SMauro Carvalho Chehab 	if (status < 0)
47299a0bf528SMauro Carvalho Chehab 		goto error;
47309a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
47319a0bf528SMauro Carvalho Chehab 	if (status < 0)
47329a0bf528SMauro Carvalho Chehab 		goto error;
47339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
47349a0bf528SMauro Carvalho Chehab 	if (status < 0)
47359a0bf528SMauro Carvalho Chehab 		goto error;
47369a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
47379a0bf528SMauro Carvalho Chehab 	if (status < 0)
47389a0bf528SMauro Carvalho Chehab 		goto error;
47399a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
47409a0bf528SMauro Carvalho Chehab 	if (status < 0)
47419a0bf528SMauro Carvalho Chehab 		goto error;
47429a0bf528SMauro Carvalho Chehab 
47439a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
47449a0bf528SMauro Carvalho Chehab 	if (status < 0)
47459a0bf528SMauro Carvalho Chehab 		goto error;
47469a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
47479a0bf528SMauro Carvalho Chehab 	if (status < 0)
47489a0bf528SMauro Carvalho Chehab 		goto error;
47499a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
47509a0bf528SMauro Carvalho Chehab 	if (status < 0)
47519a0bf528SMauro Carvalho Chehab 		goto error;
47529a0bf528SMauro Carvalho Chehab 
47539a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
47549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
47559a0bf528SMauro Carvalho Chehab 	if (status < 0)
47569a0bf528SMauro Carvalho Chehab 		goto error;
47579a0bf528SMauro Carvalho Chehab 
47589a0bf528SMauro Carvalho Chehab 
47599a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
47609a0bf528SMauro Carvalho Chehab 
47619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
47629a0bf528SMauro Carvalho Chehab 	if (status < 0)
47639a0bf528SMauro Carvalho Chehab 		goto error;
47649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
47659a0bf528SMauro Carvalho Chehab 	if (status < 0)
47669a0bf528SMauro Carvalho Chehab 		goto error;
47679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
47689a0bf528SMauro Carvalho Chehab 	if (status < 0)
47699a0bf528SMauro Carvalho Chehab 		goto error;
47709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
47719a0bf528SMauro Carvalho Chehab 	if (status < 0)
47729a0bf528SMauro Carvalho Chehab 		goto error;
47739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
47749a0bf528SMauro Carvalho Chehab 	if (status < 0)
47759a0bf528SMauro Carvalho Chehab 		goto error;
47769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
47779a0bf528SMauro Carvalho Chehab 	if (status < 0)
47789a0bf528SMauro Carvalho Chehab 		goto error;
47799a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
47809a0bf528SMauro Carvalho Chehab 	if (status < 0)
47819a0bf528SMauro Carvalho Chehab 		goto error;
47829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
47839a0bf528SMauro Carvalho Chehab 	if (status < 0)
47849a0bf528SMauro Carvalho Chehab 		goto error;
47859a0bf528SMauro Carvalho Chehab 
47869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
47879a0bf528SMauro Carvalho Chehab 	if (status < 0)
47889a0bf528SMauro Carvalho Chehab 		goto error;
47899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47909a0bf528SMauro Carvalho Chehab 	if (status < 0)
47919a0bf528SMauro Carvalho Chehab 		goto error;
47929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47939a0bf528SMauro Carvalho Chehab 	if (status < 0)
47949a0bf528SMauro Carvalho Chehab 		goto error;
47959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47969a0bf528SMauro Carvalho Chehab 	if (status < 0)
47979a0bf528SMauro Carvalho Chehab 		goto error;
47989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47999a0bf528SMauro Carvalho Chehab 	if (status < 0)
48009a0bf528SMauro Carvalho Chehab 		goto error;
48019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
48029a0bf528SMauro Carvalho Chehab 	if (status < 0)
48039a0bf528SMauro Carvalho Chehab 		goto error;
48049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
48059a0bf528SMauro Carvalho Chehab 	if (status < 0)
48069a0bf528SMauro Carvalho Chehab 		goto error;
48079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
48089a0bf528SMauro Carvalho Chehab 	if (status < 0)
48099a0bf528SMauro Carvalho Chehab 		goto error;
48109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
48119a0bf528SMauro Carvalho Chehab 	if (status < 0)
48129a0bf528SMauro Carvalho Chehab 		goto error;
48139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
48149a0bf528SMauro Carvalho Chehab 	if (status < 0)
48159a0bf528SMauro Carvalho Chehab 		goto error;
48169a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
48179a0bf528SMauro Carvalho Chehab 	if (status < 0)
48189a0bf528SMauro Carvalho Chehab 		goto error;
48199a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
48209a0bf528SMauro Carvalho Chehab 	if (status < 0)
48219a0bf528SMauro Carvalho Chehab 		goto error;
48229a0bf528SMauro Carvalho Chehab 
48239a0bf528SMauro Carvalho Chehab 
48249a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
48259a0bf528SMauro Carvalho Chehab 
48269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
48279a0bf528SMauro Carvalho Chehab 	if (status < 0)
48289a0bf528SMauro Carvalho Chehab 		goto error;
48299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
48309a0bf528SMauro Carvalho Chehab 	if (status < 0)
48319a0bf528SMauro Carvalho Chehab 		goto error;
48329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
48339a0bf528SMauro Carvalho Chehab 	if (status < 0)
48349a0bf528SMauro Carvalho Chehab 		goto error;
48359a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
48369a0bf528SMauro Carvalho Chehab 	if (status < 0)
48379a0bf528SMauro Carvalho Chehab 		goto error;
48389a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
48399a0bf528SMauro Carvalho Chehab 	if (status < 0)
48409a0bf528SMauro Carvalho Chehab 		goto error;
48419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
48429a0bf528SMauro Carvalho Chehab 	if (status < 0)
48439a0bf528SMauro Carvalho Chehab 		goto error;
48449a0bf528SMauro Carvalho Chehab 
48459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
48469a0bf528SMauro Carvalho Chehab 	if (status < 0)
48479a0bf528SMauro Carvalho Chehab 		goto error;
48489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
48499a0bf528SMauro Carvalho Chehab 	if (status < 0)
48509a0bf528SMauro Carvalho Chehab 		goto error;
48519a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
48529a0bf528SMauro Carvalho Chehab 	if (status < 0)
48539a0bf528SMauro Carvalho Chehab 		goto error;
48549a0bf528SMauro Carvalho Chehab 
48559a0bf528SMauro Carvalho Chehab 
48569a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
48579a0bf528SMauro Carvalho Chehab 
48589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
48599a0bf528SMauro Carvalho Chehab 	if (status < 0)
48609a0bf528SMauro Carvalho Chehab 		goto error;
48619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
48629a0bf528SMauro Carvalho Chehab 	if (status < 0)
48639a0bf528SMauro Carvalho Chehab 		goto error;
48649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
48659a0bf528SMauro Carvalho Chehab 	if (status < 0)
48669a0bf528SMauro Carvalho Chehab 		goto error;
48679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
48689a0bf528SMauro Carvalho Chehab 	if (status < 0)
48699a0bf528SMauro Carvalho Chehab 		goto error;
48709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
48719a0bf528SMauro Carvalho Chehab 	if (status < 0)
48729a0bf528SMauro Carvalho Chehab 		goto error;
48739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
48749a0bf528SMauro Carvalho Chehab 	if (status < 0)
48759a0bf528SMauro Carvalho Chehab 		goto error;
48769a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
48779a0bf528SMauro Carvalho Chehab error:
48789a0bf528SMauro Carvalho Chehab 	if (status < 0)
48799a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
48809a0bf528SMauro Carvalho Chehab 
48819a0bf528SMauro Carvalho Chehab 	return status;
48829a0bf528SMauro Carvalho Chehab }
48839a0bf528SMauro Carvalho Chehab 
48849a0bf528SMauro Carvalho Chehab /*============================================================================*/
48859a0bf528SMauro Carvalho Chehab 
48869a0bf528SMauro Carvalho Chehab /**
48879a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
48889a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
48899a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48909a0bf528SMauro Carvalho Chehab */
48919a0bf528SMauro Carvalho Chehab static int SetQAM128(struct drxk_state *state)
48929a0bf528SMauro Carvalho Chehab {
48939a0bf528SMauro Carvalho Chehab 	int status = 0;
48949a0bf528SMauro Carvalho Chehab 
48959a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
48969a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
48979a0bf528SMauro Carvalho Chehab 	/* Equalizer */
48989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48999a0bf528SMauro Carvalho Chehab 	if (status < 0)
49009a0bf528SMauro Carvalho Chehab 		goto error;
49019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
49029a0bf528SMauro Carvalho Chehab 	if (status < 0)
49039a0bf528SMauro Carvalho Chehab 		goto error;
49049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
49059a0bf528SMauro Carvalho Chehab 	if (status < 0)
49069a0bf528SMauro Carvalho Chehab 		goto error;
49079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
49089a0bf528SMauro Carvalho Chehab 	if (status < 0)
49099a0bf528SMauro Carvalho Chehab 		goto error;
49109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
49119a0bf528SMauro Carvalho Chehab 	if (status < 0)
49129a0bf528SMauro Carvalho Chehab 		goto error;
49139a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
49149a0bf528SMauro Carvalho Chehab 	if (status < 0)
49159a0bf528SMauro Carvalho Chehab 		goto error;
49169a0bf528SMauro Carvalho Chehab 
49179a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
49189a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
49199a0bf528SMauro Carvalho Chehab 	if (status < 0)
49209a0bf528SMauro Carvalho Chehab 		goto error;
49219a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
49229a0bf528SMauro Carvalho Chehab 	if (status < 0)
49239a0bf528SMauro Carvalho Chehab 		goto error;
49249a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
49259a0bf528SMauro Carvalho Chehab 	if (status < 0)
49269a0bf528SMauro Carvalho Chehab 		goto error;
49279a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
49289a0bf528SMauro Carvalho Chehab 	if (status < 0)
49299a0bf528SMauro Carvalho Chehab 		goto error;
49309a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
49319a0bf528SMauro Carvalho Chehab 	if (status < 0)
49329a0bf528SMauro Carvalho Chehab 		goto error;
49339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
49349a0bf528SMauro Carvalho Chehab 	if (status < 0)
49359a0bf528SMauro Carvalho Chehab 		goto error;
49369a0bf528SMauro Carvalho Chehab 
49379a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 6);
49389a0bf528SMauro Carvalho Chehab 	if (status < 0)
49399a0bf528SMauro Carvalho Chehab 		goto error;
49409a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 5);
49419a0bf528SMauro Carvalho Chehab 	if (status < 0)
49429a0bf528SMauro Carvalho Chehab 		goto error;
49439a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
49449a0bf528SMauro Carvalho Chehab 	if (status < 0)
49459a0bf528SMauro Carvalho Chehab 		goto error;
49469a0bf528SMauro Carvalho Chehab 
49479a0bf528SMauro Carvalho Chehab 
49489a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
49499a0bf528SMauro Carvalho Chehab 
49509a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
49519a0bf528SMauro Carvalho Chehab 	if (status < 0)
49529a0bf528SMauro Carvalho Chehab 		goto error;
49539a0bf528SMauro Carvalho Chehab 
49549a0bf528SMauro Carvalho Chehab 
49559a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
49569a0bf528SMauro Carvalho Chehab 
49579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
49589a0bf528SMauro Carvalho Chehab 	if (status < 0)
49599a0bf528SMauro Carvalho Chehab 		goto error;
49609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
49619a0bf528SMauro Carvalho Chehab 	if (status < 0)
49629a0bf528SMauro Carvalho Chehab 		goto error;
49639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
49649a0bf528SMauro Carvalho Chehab 	if (status < 0)
49659a0bf528SMauro Carvalho Chehab 		goto error;
49669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
49679a0bf528SMauro Carvalho Chehab 	if (status < 0)
49689a0bf528SMauro Carvalho Chehab 		goto error;
49699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
49709a0bf528SMauro Carvalho Chehab 	if (status < 0)
49719a0bf528SMauro Carvalho Chehab 		goto error;
49729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
49739a0bf528SMauro Carvalho Chehab 	if (status < 0)
49749a0bf528SMauro Carvalho Chehab 		goto error;
49759a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
49769a0bf528SMauro Carvalho Chehab 	if (status < 0)
49779a0bf528SMauro Carvalho Chehab 		goto error;
49789a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
49799a0bf528SMauro Carvalho Chehab 	if (status < 0)
49809a0bf528SMauro Carvalho Chehab 		goto error;
49819a0bf528SMauro Carvalho Chehab 
49829a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
49839a0bf528SMauro Carvalho Chehab 	if (status < 0)
49849a0bf528SMauro Carvalho Chehab 		goto error;
49859a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
49869a0bf528SMauro Carvalho Chehab 	if (status < 0)
49879a0bf528SMauro Carvalho Chehab 		goto error;
49889a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49899a0bf528SMauro Carvalho Chehab 	if (status < 0)
49909a0bf528SMauro Carvalho Chehab 		goto error;
49919a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49929a0bf528SMauro Carvalho Chehab 	if (status < 0)
49939a0bf528SMauro Carvalho Chehab 		goto error;
49949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49959a0bf528SMauro Carvalho Chehab 	if (status < 0)
49969a0bf528SMauro Carvalho Chehab 		goto error;
49979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49989a0bf528SMauro Carvalho Chehab 	if (status < 0)
49999a0bf528SMauro Carvalho Chehab 		goto error;
50009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
50019a0bf528SMauro Carvalho Chehab 	if (status < 0)
50029a0bf528SMauro Carvalho Chehab 		goto error;
50039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
50049a0bf528SMauro Carvalho Chehab 	if (status < 0)
50059a0bf528SMauro Carvalho Chehab 		goto error;
50069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
50079a0bf528SMauro Carvalho Chehab 	if (status < 0)
50089a0bf528SMauro Carvalho Chehab 		goto error;
50099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
50109a0bf528SMauro Carvalho Chehab 	if (status < 0)
50119a0bf528SMauro Carvalho Chehab 		goto error;
50129a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
50139a0bf528SMauro Carvalho Chehab 	if (status < 0)
50149a0bf528SMauro Carvalho Chehab 		goto error;
50159a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
50169a0bf528SMauro Carvalho Chehab 	if (status < 0)
50179a0bf528SMauro Carvalho Chehab 		goto error;
50189a0bf528SMauro Carvalho Chehab 
50199a0bf528SMauro Carvalho Chehab 
50209a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
50219a0bf528SMauro Carvalho Chehab 
50229a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
50239a0bf528SMauro Carvalho Chehab 	if (status < 0)
50249a0bf528SMauro Carvalho Chehab 		goto error;
50259a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
50269a0bf528SMauro Carvalho Chehab 	if (status < 0)
50279a0bf528SMauro Carvalho Chehab 		goto error;
50289a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
50299a0bf528SMauro Carvalho Chehab 	if (status < 0)
50309a0bf528SMauro Carvalho Chehab 		goto error;
50319a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
50329a0bf528SMauro Carvalho Chehab 	if (status < 0)
50339a0bf528SMauro Carvalho Chehab 		goto error;
50349a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
50359a0bf528SMauro Carvalho Chehab 	if (status < 0)
50369a0bf528SMauro Carvalho Chehab 		goto error;
50379a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
50389a0bf528SMauro Carvalho Chehab 	if (status < 0)
50399a0bf528SMauro Carvalho Chehab 		goto error;
50409a0bf528SMauro Carvalho Chehab 
50419a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
50429a0bf528SMauro Carvalho Chehab 	if (status < 0)
50439a0bf528SMauro Carvalho Chehab 		goto error;
50449a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
50459a0bf528SMauro Carvalho Chehab 	if (status < 0)
50469a0bf528SMauro Carvalho Chehab 		goto error;
50479a0bf528SMauro Carvalho Chehab 
50489a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
50499a0bf528SMauro Carvalho Chehab 	if (status < 0)
50509a0bf528SMauro Carvalho Chehab 		goto error;
50519a0bf528SMauro Carvalho Chehab 
50529a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
50539a0bf528SMauro Carvalho Chehab 
50549a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
50559a0bf528SMauro Carvalho Chehab 	if (status < 0)
50569a0bf528SMauro Carvalho Chehab 		goto error;
50579a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
50589a0bf528SMauro Carvalho Chehab 	if (status < 0)
50599a0bf528SMauro Carvalho Chehab 		goto error;
50609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
50619a0bf528SMauro Carvalho Chehab 	if (status < 0)
50629a0bf528SMauro Carvalho Chehab 		goto error;
50639a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
50649a0bf528SMauro Carvalho Chehab 	if (status < 0)
50659a0bf528SMauro Carvalho Chehab 		goto error;
50669a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
50679a0bf528SMauro Carvalho Chehab 	if (status < 0)
50689a0bf528SMauro Carvalho Chehab 		goto error;
50699a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
50709a0bf528SMauro Carvalho Chehab 	if (status < 0)
50719a0bf528SMauro Carvalho Chehab 		goto error;
50729a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
50739a0bf528SMauro Carvalho Chehab error:
50749a0bf528SMauro Carvalho Chehab 	if (status < 0)
50759a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
50769a0bf528SMauro Carvalho Chehab 
50779a0bf528SMauro Carvalho Chehab 	return status;
50789a0bf528SMauro Carvalho Chehab }
50799a0bf528SMauro Carvalho Chehab 
50809a0bf528SMauro Carvalho Chehab /*============================================================================*/
50819a0bf528SMauro Carvalho Chehab 
50829a0bf528SMauro Carvalho Chehab /**
50839a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
50849a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
50859a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
50869a0bf528SMauro Carvalho Chehab */
50879a0bf528SMauro Carvalho Chehab static int SetQAM256(struct drxk_state *state)
50889a0bf528SMauro Carvalho Chehab {
50899a0bf528SMauro Carvalho Chehab 	int status = 0;
50909a0bf528SMauro Carvalho Chehab 
50919a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
50929a0bf528SMauro Carvalho Chehab 	/* QAM Equalizer Setup */
50939a0bf528SMauro Carvalho Chehab 	/* Equalizer */
50949a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50959a0bf528SMauro Carvalho Chehab 	if (status < 0)
50969a0bf528SMauro Carvalho Chehab 		goto error;
50979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50989a0bf528SMauro Carvalho Chehab 	if (status < 0)
50999a0bf528SMauro Carvalho Chehab 		goto error;
51009a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
51019a0bf528SMauro Carvalho Chehab 	if (status < 0)
51029a0bf528SMauro Carvalho Chehab 		goto error;
51039a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
51049a0bf528SMauro Carvalho Chehab 	if (status < 0)
51059a0bf528SMauro Carvalho Chehab 		goto error;
51069a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
51079a0bf528SMauro Carvalho Chehab 	if (status < 0)
51089a0bf528SMauro Carvalho Chehab 		goto error;
51099a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
51109a0bf528SMauro Carvalho Chehab 	if (status < 0)
51119a0bf528SMauro Carvalho Chehab 		goto error;
51129a0bf528SMauro Carvalho Chehab 
51139a0bf528SMauro Carvalho Chehab 	/* Decision Feedback Equalizer */
51149a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
51159a0bf528SMauro Carvalho Chehab 	if (status < 0)
51169a0bf528SMauro Carvalho Chehab 		goto error;
51179a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
51189a0bf528SMauro Carvalho Chehab 	if (status < 0)
51199a0bf528SMauro Carvalho Chehab 		goto error;
51209a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
51219a0bf528SMauro Carvalho Chehab 	if (status < 0)
51229a0bf528SMauro Carvalho Chehab 		goto error;
51239a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
51249a0bf528SMauro Carvalho Chehab 	if (status < 0)
51259a0bf528SMauro Carvalho Chehab 		goto error;
51269a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
51279a0bf528SMauro Carvalho Chehab 	if (status < 0)
51289a0bf528SMauro Carvalho Chehab 		goto error;
51299a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
51309a0bf528SMauro Carvalho Chehab 	if (status < 0)
51319a0bf528SMauro Carvalho Chehab 		goto error;
51329a0bf528SMauro Carvalho Chehab 
51339a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_HWM__A, 5);
51349a0bf528SMauro Carvalho Chehab 	if (status < 0)
51359a0bf528SMauro Carvalho Chehab 		goto error;
51369a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_AWM__A, 4);
51379a0bf528SMauro Carvalho Chehab 	if (status < 0)
51389a0bf528SMauro Carvalho Chehab 		goto error;
51399a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SYNC_LWM__A, 3);
51409a0bf528SMauro Carvalho Chehab 	if (status < 0)
51419a0bf528SMauro Carvalho Chehab 		goto error;
51429a0bf528SMauro Carvalho Chehab 
51439a0bf528SMauro Carvalho Chehab 	/* QAM Slicer Settings */
51449a0bf528SMauro Carvalho Chehab 
51459a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
51469a0bf528SMauro Carvalho Chehab 	if (status < 0)
51479a0bf528SMauro Carvalho Chehab 		goto error;
51489a0bf528SMauro Carvalho Chehab 
51499a0bf528SMauro Carvalho Chehab 
51509a0bf528SMauro Carvalho Chehab 	/* QAM Loop Controller Coeficients */
51519a0bf528SMauro Carvalho Chehab 
51529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
51539a0bf528SMauro Carvalho Chehab 	if (status < 0)
51549a0bf528SMauro Carvalho Chehab 		goto error;
51559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
51569a0bf528SMauro Carvalho Chehab 	if (status < 0)
51579a0bf528SMauro Carvalho Chehab 		goto error;
51589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
51599a0bf528SMauro Carvalho Chehab 	if (status < 0)
51609a0bf528SMauro Carvalho Chehab 		goto error;
51619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
51629a0bf528SMauro Carvalho Chehab 	if (status < 0)
51639a0bf528SMauro Carvalho Chehab 		goto error;
51649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
51659a0bf528SMauro Carvalho Chehab 	if (status < 0)
51669a0bf528SMauro Carvalho Chehab 		goto error;
51679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
51689a0bf528SMauro Carvalho Chehab 	if (status < 0)
51699a0bf528SMauro Carvalho Chehab 		goto error;
51709a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
51719a0bf528SMauro Carvalho Chehab 	if (status < 0)
51729a0bf528SMauro Carvalho Chehab 		goto error;
51739a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
51749a0bf528SMauro Carvalho Chehab 	if (status < 0)
51759a0bf528SMauro Carvalho Chehab 		goto error;
51769a0bf528SMauro Carvalho Chehab 
51779a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
51789a0bf528SMauro Carvalho Chehab 	if (status < 0)
51799a0bf528SMauro Carvalho Chehab 		goto error;
51809a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
51819a0bf528SMauro Carvalho Chehab 	if (status < 0)
51829a0bf528SMauro Carvalho Chehab 		goto error;
51839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
51849a0bf528SMauro Carvalho Chehab 	if (status < 0)
51859a0bf528SMauro Carvalho Chehab 		goto error;
51869a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
51879a0bf528SMauro Carvalho Chehab 	if (status < 0)
51889a0bf528SMauro Carvalho Chehab 		goto error;
51899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51909a0bf528SMauro Carvalho Chehab 	if (status < 0)
51919a0bf528SMauro Carvalho Chehab 		goto error;
51929a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51939a0bf528SMauro Carvalho Chehab 	if (status < 0)
51949a0bf528SMauro Carvalho Chehab 		goto error;
51959a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51969a0bf528SMauro Carvalho Chehab 	if (status < 0)
51979a0bf528SMauro Carvalho Chehab 		goto error;
51989a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51999a0bf528SMauro Carvalho Chehab 	if (status < 0)
52009a0bf528SMauro Carvalho Chehab 		goto error;
52019a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
52029a0bf528SMauro Carvalho Chehab 	if (status < 0)
52039a0bf528SMauro Carvalho Chehab 		goto error;
52049a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
52059a0bf528SMauro Carvalho Chehab 	if (status < 0)
52069a0bf528SMauro Carvalho Chehab 		goto error;
52079a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
52089a0bf528SMauro Carvalho Chehab 	if (status < 0)
52099a0bf528SMauro Carvalho Chehab 		goto error;
52109a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
52119a0bf528SMauro Carvalho Chehab 	if (status < 0)
52129a0bf528SMauro Carvalho Chehab 		goto error;
52139a0bf528SMauro Carvalho Chehab 
52149a0bf528SMauro Carvalho Chehab 
52159a0bf528SMauro Carvalho Chehab 	/* QAM State Machine (FSM) Thresholds */
52169a0bf528SMauro Carvalho Chehab 
52179a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
52189a0bf528SMauro Carvalho Chehab 	if (status < 0)
52199a0bf528SMauro Carvalho Chehab 		goto error;
52209a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
52219a0bf528SMauro Carvalho Chehab 	if (status < 0)
52229a0bf528SMauro Carvalho Chehab 		goto error;
52239a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
52249a0bf528SMauro Carvalho Chehab 	if (status < 0)
52259a0bf528SMauro Carvalho Chehab 		goto error;
52269a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
52279a0bf528SMauro Carvalho Chehab 	if (status < 0)
52289a0bf528SMauro Carvalho Chehab 		goto error;
52299a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
52309a0bf528SMauro Carvalho Chehab 	if (status < 0)
52319a0bf528SMauro Carvalho Chehab 		goto error;
52329a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
52339a0bf528SMauro Carvalho Chehab 	if (status < 0)
52349a0bf528SMauro Carvalho Chehab 		goto error;
52359a0bf528SMauro Carvalho Chehab 
52369a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
52379a0bf528SMauro Carvalho Chehab 	if (status < 0)
52389a0bf528SMauro Carvalho Chehab 		goto error;
52399a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
52409a0bf528SMauro Carvalho Chehab 	if (status < 0)
52419a0bf528SMauro Carvalho Chehab 		goto error;
52429a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
52439a0bf528SMauro Carvalho Chehab 	if (status < 0)
52449a0bf528SMauro Carvalho Chehab 		goto error;
52459a0bf528SMauro Carvalho Chehab 
52469a0bf528SMauro Carvalho Chehab 
52479a0bf528SMauro Carvalho Chehab 	/* QAM FSM Tracking Parameters */
52489a0bf528SMauro Carvalho Chehab 
52499a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
52509a0bf528SMauro Carvalho Chehab 	if (status < 0)
52519a0bf528SMauro Carvalho Chehab 		goto error;
52529a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
52539a0bf528SMauro Carvalho Chehab 	if (status < 0)
52549a0bf528SMauro Carvalho Chehab 		goto error;
52559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
52569a0bf528SMauro Carvalho Chehab 	if (status < 0)
52579a0bf528SMauro Carvalho Chehab 		goto error;
52589a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
52599a0bf528SMauro Carvalho Chehab 	if (status < 0)
52609a0bf528SMauro Carvalho Chehab 		goto error;
52619a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
52629a0bf528SMauro Carvalho Chehab 	if (status < 0)
52639a0bf528SMauro Carvalho Chehab 		goto error;
52649a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
52659a0bf528SMauro Carvalho Chehab 	if (status < 0)
52669a0bf528SMauro Carvalho Chehab 		goto error;
52679a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
52689a0bf528SMauro Carvalho Chehab error:
52699a0bf528SMauro Carvalho Chehab 	if (status < 0)
52709a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
52719a0bf528SMauro Carvalho Chehab 	return status;
52729a0bf528SMauro Carvalho Chehab }
52739a0bf528SMauro Carvalho Chehab 
52749a0bf528SMauro Carvalho Chehab 
52759a0bf528SMauro Carvalho Chehab /*============================================================================*/
52769a0bf528SMauro Carvalho Chehab /**
52779a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
52789a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
52799a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52809a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52819a0bf528SMauro Carvalho Chehab */
52829a0bf528SMauro Carvalho Chehab static int QAMResetQAM(struct drxk_state *state)
52839a0bf528SMauro Carvalho Chehab {
52849a0bf528SMauro Carvalho Chehab 	int status;
52859a0bf528SMauro Carvalho Chehab 	u16 cmdResult;
52869a0bf528SMauro Carvalho Chehab 
52879a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
52889a0bf528SMauro Carvalho Chehab 	/* Stop QAM comstate->m_exec */
52899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52909a0bf528SMauro Carvalho Chehab 	if (status < 0)
52919a0bf528SMauro Carvalho Chehab 		goto error;
52929a0bf528SMauro Carvalho Chehab 
52939a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
52949a0bf528SMauro Carvalho Chehab error:
52959a0bf528SMauro Carvalho Chehab 	if (status < 0)
52969a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
52979a0bf528SMauro Carvalho Chehab 	return status;
52989a0bf528SMauro Carvalho Chehab }
52999a0bf528SMauro Carvalho Chehab 
53009a0bf528SMauro Carvalho Chehab /*============================================================================*/
53019a0bf528SMauro Carvalho Chehab 
53029a0bf528SMauro Carvalho Chehab /**
53039a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
53049a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
53059a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
53069a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
53079a0bf528SMauro Carvalho Chehab */
53089a0bf528SMauro Carvalho Chehab static int QAMSetSymbolrate(struct drxk_state *state)
53099a0bf528SMauro Carvalho Chehab {
53109a0bf528SMauro Carvalho Chehab 	u32 adcFrequency = 0;
53119a0bf528SMauro Carvalho Chehab 	u32 symbFreq = 0;
53129a0bf528SMauro Carvalho Chehab 	u32 iqmRcRate = 0;
53139a0bf528SMauro Carvalho Chehab 	u16 ratesel = 0;
53149a0bf528SMauro Carvalho Chehab 	u32 lcSymbRate = 0;
53159a0bf528SMauro Carvalho Chehab 	int status;
53169a0bf528SMauro Carvalho Chehab 
53179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
53189a0bf528SMauro Carvalho Chehab 	/* Select & calculate correct IQM rate */
53199a0bf528SMauro Carvalho Chehab 	adcFrequency = (state->m_sysClockFreq * 1000) / 3;
53209a0bf528SMauro Carvalho Chehab 	ratesel = 0;
53219a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
53229a0bf528SMauro Carvalho Chehab 	if (state->props.symbol_rate <= 1188750)
53239a0bf528SMauro Carvalho Chehab 		ratesel = 3;
53249a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 2377500)
53259a0bf528SMauro Carvalho Chehab 		ratesel = 2;
53269a0bf528SMauro Carvalho Chehab 	else if (state->props.symbol_rate <= 4755000)
53279a0bf528SMauro Carvalho Chehab 		ratesel = 1;
53289a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FD_RATESEL__A, ratesel);
53299a0bf528SMauro Carvalho Chehab 	if (status < 0)
53309a0bf528SMauro Carvalho Chehab 		goto error;
53319a0bf528SMauro Carvalho Chehab 
53329a0bf528SMauro Carvalho Chehab 	/*
53339a0bf528SMauro Carvalho Chehab 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
53349a0bf528SMauro Carvalho Chehab 		*/
53359a0bf528SMauro Carvalho Chehab 	symbFreq = state->props.symbol_rate * (1 << ratesel);
53369a0bf528SMauro Carvalho Chehab 	if (symbFreq == 0) {
53379a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53389a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53399a0bf528SMauro Carvalho Chehab 		goto error;
53409a0bf528SMauro Carvalho Chehab 	}
53419a0bf528SMauro Carvalho Chehab 	iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
53429a0bf528SMauro Carvalho Chehab 		(Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
53439a0bf528SMauro Carvalho Chehab 		(1 << 23);
53449a0bf528SMauro Carvalho Chehab 	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
53459a0bf528SMauro Carvalho Chehab 	if (status < 0)
53469a0bf528SMauro Carvalho Chehab 		goto error;
53479a0bf528SMauro Carvalho Chehab 	state->m_iqmRcRate = iqmRcRate;
53489a0bf528SMauro Carvalho Chehab 	/*
53499a0bf528SMauro Carvalho Chehab 		LcSymbFreq = round (.125 *  symbolrate / adcFreq * (1<<15))
53509a0bf528SMauro Carvalho Chehab 		*/
53519a0bf528SMauro Carvalho Chehab 	symbFreq = state->props.symbol_rate;
53529a0bf528SMauro Carvalho Chehab 	if (adcFrequency == 0) {
53539a0bf528SMauro Carvalho Chehab 		/* Divide by zero */
53549a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
53559a0bf528SMauro Carvalho Chehab 		goto error;
53569a0bf528SMauro Carvalho Chehab 	}
53579a0bf528SMauro Carvalho Chehab 	lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
53589a0bf528SMauro Carvalho Chehab 		(Frac28a((symbFreq % adcFrequency), adcFrequency) >>
53599a0bf528SMauro Carvalho Chehab 		16);
53609a0bf528SMauro Carvalho Chehab 	if (lcSymbRate > 511)
53619a0bf528SMauro Carvalho Chehab 		lcSymbRate = 511;
53629a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
53639a0bf528SMauro Carvalho Chehab 
53649a0bf528SMauro Carvalho Chehab error:
53659a0bf528SMauro Carvalho Chehab 	if (status < 0)
53669a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
53679a0bf528SMauro Carvalho Chehab 	return status;
53689a0bf528SMauro Carvalho Chehab }
53699a0bf528SMauro Carvalho Chehab 
53709a0bf528SMauro Carvalho Chehab /*============================================================================*/
53719a0bf528SMauro Carvalho Chehab 
53729a0bf528SMauro Carvalho Chehab /**
53739a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
53749a0bf528SMauro Carvalho Chehab * \param demod:   instance of demod.
53759a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
53769a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
53779a0bf528SMauro Carvalho Chehab */
53789a0bf528SMauro Carvalho Chehab 
53799a0bf528SMauro Carvalho Chehab static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
53809a0bf528SMauro Carvalho Chehab {
53819a0bf528SMauro Carvalho Chehab 	int status;
53829a0bf528SMauro Carvalho Chehab 	u16 Result[2] = { 0, 0 };
53839a0bf528SMauro Carvalho Chehab 
53849a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
53859a0bf528SMauro Carvalho Chehab 	*pLockStatus = NOT_LOCKED;
53869a0bf528SMauro Carvalho Chehab 	status = scu_command(state,
53879a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_STANDARD_QAM |
53889a0bf528SMauro Carvalho Chehab 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
53899a0bf528SMauro Carvalho Chehab 			Result);
53909a0bf528SMauro Carvalho Chehab 	if (status < 0)
53919a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
53929a0bf528SMauro Carvalho Chehab 
53939a0bf528SMauro Carvalho Chehab 	if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53949a0bf528SMauro Carvalho Chehab 		/* 0x0000 NOT LOCKED */
53959a0bf528SMauro Carvalho Chehab 	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53969a0bf528SMauro Carvalho Chehab 		/* 0x4000 DEMOD LOCKED */
53979a0bf528SMauro Carvalho Chehab 		*pLockStatus = DEMOD_LOCK;
53989a0bf528SMauro Carvalho Chehab 	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53999a0bf528SMauro Carvalho Chehab 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
54009a0bf528SMauro Carvalho Chehab 		*pLockStatus = MPEG_LOCK;
54019a0bf528SMauro Carvalho Chehab 	} else {
54029a0bf528SMauro Carvalho Chehab 		/* 0xC000 NEVER LOCKED */
54039a0bf528SMauro Carvalho Chehab 		/* (system will never be able to lock to the signal) */
54049a0bf528SMauro Carvalho Chehab 		/* TODO: check this, intermediate & standard specific lock states are not
54059a0bf528SMauro Carvalho Chehab 		   taken into account here */
54069a0bf528SMauro Carvalho Chehab 		*pLockStatus = NEVER_LOCK;
54079a0bf528SMauro Carvalho Chehab 	}
54089a0bf528SMauro Carvalho Chehab 	return status;
54099a0bf528SMauro Carvalho Chehab }
54109a0bf528SMauro Carvalho Chehab 
54119a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M         0x03
54129a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL     0x00
54139a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED          0x01
54149a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON    0x02
54159a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M      0x10
54169a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL  0x10
54179a0bf528SMauro Carvalho Chehab 
54189a0bf528SMauro Carvalho Chehab static int QAMDemodulatorCommand(struct drxk_state *state,
54199a0bf528SMauro Carvalho Chehab 				 int numberOfParameters)
54209a0bf528SMauro Carvalho Chehab {
54219a0bf528SMauro Carvalho Chehab 	int status;
54229a0bf528SMauro Carvalho Chehab 	u16 cmdResult;
54239a0bf528SMauro Carvalho Chehab 	u16 setParamParameters[4] = { 0, 0, 0, 0 };
54249a0bf528SMauro Carvalho Chehab 
54259a0bf528SMauro Carvalho Chehab 	setParamParameters[0] = state->m_Constellation;	/* modulation     */
54269a0bf528SMauro Carvalho Chehab 	setParamParameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
54279a0bf528SMauro Carvalho Chehab 
54289a0bf528SMauro Carvalho Chehab 	if (numberOfParameters == 2) {
54299a0bf528SMauro Carvalho Chehab 		u16 setEnvParameters[1] = { 0 };
54309a0bf528SMauro Carvalho Chehab 
54319a0bf528SMauro Carvalho Chehab 		if (state->m_OperationMode == OM_QAM_ITU_C)
54329a0bf528SMauro Carvalho Chehab 			setEnvParameters[0] = QAM_TOP_ANNEX_C;
54339a0bf528SMauro Carvalho Chehab 		else
54349a0bf528SMauro Carvalho Chehab 			setEnvParameters[0] = QAM_TOP_ANNEX_A;
54359a0bf528SMauro Carvalho Chehab 
54369a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
54379a0bf528SMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
54389a0bf528SMauro Carvalho Chehab 				     1, setEnvParameters, 1, &cmdResult);
54399a0bf528SMauro Carvalho Chehab 		if (status < 0)
54409a0bf528SMauro Carvalho Chehab 			goto error;
54419a0bf528SMauro Carvalho Chehab 
54429a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
54439a0bf528SMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
54449a0bf528SMauro Carvalho Chehab 				     numberOfParameters, setParamParameters,
54459a0bf528SMauro Carvalho Chehab 				     1, &cmdResult);
54469a0bf528SMauro Carvalho Chehab 	} else if (numberOfParameters == 4) {
54479a0bf528SMauro Carvalho Chehab 		if (state->m_OperationMode == OM_QAM_ITU_C)
54489a0bf528SMauro Carvalho Chehab 			setParamParameters[2] = QAM_TOP_ANNEX_C;
54499a0bf528SMauro Carvalho Chehab 		else
54509a0bf528SMauro Carvalho Chehab 			setParamParameters[2] = QAM_TOP_ANNEX_A;
54519a0bf528SMauro Carvalho Chehab 
54529a0bf528SMauro Carvalho Chehab 		setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
54539a0bf528SMauro Carvalho Chehab 		/* Env parameters */
54549a0bf528SMauro Carvalho Chehab 		/* check for LOCKRANGE Extented */
54559a0bf528SMauro Carvalho Chehab 		/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
54569a0bf528SMauro Carvalho Chehab 
54579a0bf528SMauro Carvalho Chehab 		status = scu_command(state,
54589a0bf528SMauro Carvalho Chehab 				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
54599a0bf528SMauro Carvalho Chehab 				     numberOfParameters, setParamParameters,
54609a0bf528SMauro Carvalho Chehab 				     1, &cmdResult);
54619a0bf528SMauro Carvalho Chehab 	} else {
54629a0bf528SMauro Carvalho Chehab 		printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
54639a0bf528SMauro Carvalho Chehab 			"count %d\n", numberOfParameters);
54649a0bf528SMauro Carvalho Chehab 	}
54659a0bf528SMauro Carvalho Chehab 
54669a0bf528SMauro Carvalho Chehab error:
54679a0bf528SMauro Carvalho Chehab 	if (status < 0)
54689a0bf528SMauro Carvalho Chehab 		printk(KERN_WARNING "drxk: Warning %d on %s\n",
54699a0bf528SMauro Carvalho Chehab 		       status, __func__);
54709a0bf528SMauro Carvalho Chehab 	return status;
54719a0bf528SMauro Carvalho Chehab }
54729a0bf528SMauro Carvalho Chehab 
54739a0bf528SMauro Carvalho Chehab static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
54749a0bf528SMauro Carvalho Chehab 		  s32 tunerFreqOffset)
54759a0bf528SMauro Carvalho Chehab {
54769a0bf528SMauro Carvalho Chehab 	int status;
54779a0bf528SMauro Carvalho Chehab 	u16 cmdResult;
54789a0bf528SMauro Carvalho Chehab 	int qamDemodParamCount = state->qam_demod_parameter_count;
54799a0bf528SMauro Carvalho Chehab 
54809a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
54819a0bf528SMauro Carvalho Chehab 	/*
54829a0bf528SMauro Carvalho Chehab 	 * STEP 1: reset demodulator
54839a0bf528SMauro Carvalho Chehab 	 *	resets FEC DI and FEC RS
54849a0bf528SMauro Carvalho Chehab 	 *	resets QAM block
54859a0bf528SMauro Carvalho Chehab 	 *	resets SCU variables
54869a0bf528SMauro Carvalho Chehab 	 */
54879a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54889a0bf528SMauro Carvalho Chehab 	if (status < 0)
54899a0bf528SMauro Carvalho Chehab 		goto error;
54909a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54919a0bf528SMauro Carvalho Chehab 	if (status < 0)
54929a0bf528SMauro Carvalho Chehab 		goto error;
54939a0bf528SMauro Carvalho Chehab 	status = QAMResetQAM(state);
54949a0bf528SMauro Carvalho Chehab 	if (status < 0)
54959a0bf528SMauro Carvalho Chehab 		goto error;
54969a0bf528SMauro Carvalho Chehab 
54979a0bf528SMauro Carvalho Chehab 	/*
54989a0bf528SMauro Carvalho Chehab 	 * STEP 2: configure demodulator
54999a0bf528SMauro Carvalho Chehab 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
55009a0bf528SMauro Carvalho Chehab 	 *       SCU variables
55019a0bf528SMauro Carvalho Chehab 	 */
55029a0bf528SMauro Carvalho Chehab 	status = QAMSetSymbolrate(state);
55039a0bf528SMauro Carvalho Chehab 	if (status < 0)
55049a0bf528SMauro Carvalho Chehab 		goto error;
55059a0bf528SMauro Carvalho Chehab 
55069a0bf528SMauro Carvalho Chehab 	/* Set params */
55079a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
55089a0bf528SMauro Carvalho Chehab 	case QAM_256:
55099a0bf528SMauro Carvalho Chehab 		state->m_Constellation = DRX_CONSTELLATION_QAM256;
55109a0bf528SMauro Carvalho Chehab 		break;
55119a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
55129a0bf528SMauro Carvalho Chehab 	case QAM_64:
55139a0bf528SMauro Carvalho Chehab 		state->m_Constellation = DRX_CONSTELLATION_QAM64;
55149a0bf528SMauro Carvalho Chehab 		break;
55159a0bf528SMauro Carvalho Chehab 	case QAM_16:
55169a0bf528SMauro Carvalho Chehab 		state->m_Constellation = DRX_CONSTELLATION_QAM16;
55179a0bf528SMauro Carvalho Chehab 		break;
55189a0bf528SMauro Carvalho Chehab 	case QAM_32:
55199a0bf528SMauro Carvalho Chehab 		state->m_Constellation = DRX_CONSTELLATION_QAM32;
55209a0bf528SMauro Carvalho Chehab 		break;
55219a0bf528SMauro Carvalho Chehab 	case QAM_128:
55229a0bf528SMauro Carvalho Chehab 		state->m_Constellation = DRX_CONSTELLATION_QAM128;
55239a0bf528SMauro Carvalho Chehab 		break;
55249a0bf528SMauro Carvalho Chehab 	default:
55259a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
55269a0bf528SMauro Carvalho Chehab 		break;
55279a0bf528SMauro Carvalho Chehab 	}
55289a0bf528SMauro Carvalho Chehab 	if (status < 0)
55299a0bf528SMauro Carvalho Chehab 		goto error;
55309a0bf528SMauro Carvalho Chehab 
55319a0bf528SMauro Carvalho Chehab 	/* Use the 4-parameter if it's requested or we're probing for
55329a0bf528SMauro Carvalho Chehab 	 * the correct command. */
55339a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 4
55349a0bf528SMauro Carvalho Chehab 		|| !state->qam_demod_parameter_count) {
55359a0bf528SMauro Carvalho Chehab 		qamDemodParamCount = 4;
55369a0bf528SMauro Carvalho Chehab 		status = QAMDemodulatorCommand(state, qamDemodParamCount);
55379a0bf528SMauro Carvalho Chehab 	}
55389a0bf528SMauro Carvalho Chehab 
55399a0bf528SMauro Carvalho Chehab 	/* Use the 2-parameter command if it was requested or if we're
55409a0bf528SMauro Carvalho Chehab 	 * probing for the correct command and the 4-parameter command
55419a0bf528SMauro Carvalho Chehab 	 * failed. */
55429a0bf528SMauro Carvalho Chehab 	if (state->qam_demod_parameter_count == 2
55439a0bf528SMauro Carvalho Chehab 		|| (!state->qam_demod_parameter_count && status < 0)) {
55449a0bf528SMauro Carvalho Chehab 		qamDemodParamCount = 2;
55459a0bf528SMauro Carvalho Chehab 		status = QAMDemodulatorCommand(state, qamDemodParamCount);
55469a0bf528SMauro Carvalho Chehab 	}
55479a0bf528SMauro Carvalho Chehab 
55489a0bf528SMauro Carvalho Chehab 	if (status < 0) {
55499a0bf528SMauro Carvalho Chehab 		dprintk(1, "Could not set demodulator parameters. Make "
55509a0bf528SMauro Carvalho Chehab 			"sure qam_demod_parameter_count (%d) is correct for "
55519a0bf528SMauro Carvalho Chehab 			"your firmware (%s).\n",
55529a0bf528SMauro Carvalho Chehab 			state->qam_demod_parameter_count,
55539a0bf528SMauro Carvalho Chehab 			state->microcode_name);
55549a0bf528SMauro Carvalho Chehab 		goto error;
55559a0bf528SMauro Carvalho Chehab 	} else if (!state->qam_demod_parameter_count) {
55569a0bf528SMauro Carvalho Chehab 		dprintk(1, "Auto-probing the correct QAM demodulator command "
55579a0bf528SMauro Carvalho Chehab 			"parameters was successful - using %d parameters.\n",
55589a0bf528SMauro Carvalho Chehab 			qamDemodParamCount);
55599a0bf528SMauro Carvalho Chehab 
55609a0bf528SMauro Carvalho Chehab 		/*
55619a0bf528SMauro Carvalho Chehab 		 * One of our commands was successful. We don't need to
55629a0bf528SMauro Carvalho Chehab 		 * auto-probe anymore, now that we got the correct command.
55639a0bf528SMauro Carvalho Chehab 		 */
55649a0bf528SMauro Carvalho Chehab 		state->qam_demod_parameter_count = qamDemodParamCount;
55659a0bf528SMauro Carvalho Chehab 	}
55669a0bf528SMauro Carvalho Chehab 
55679a0bf528SMauro Carvalho Chehab 	/*
55689a0bf528SMauro Carvalho Chehab 	 * STEP 3: enable the system in a mode where the ADC provides valid
55699a0bf528SMauro Carvalho Chehab 	 * signal setup modulation independent registers
55709a0bf528SMauro Carvalho Chehab 	 */
55719a0bf528SMauro Carvalho Chehab #if 0
55729a0bf528SMauro Carvalho Chehab 	status = SetFrequency(channel, tunerFreqOffset));
55739a0bf528SMauro Carvalho Chehab 	if (status < 0)
55749a0bf528SMauro Carvalho Chehab 		goto error;
55759a0bf528SMauro Carvalho Chehab #endif
55769a0bf528SMauro Carvalho Chehab 	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
55779a0bf528SMauro Carvalho Chehab 	if (status < 0)
55789a0bf528SMauro Carvalho Chehab 		goto error;
55799a0bf528SMauro Carvalho Chehab 
55809a0bf528SMauro Carvalho Chehab 	/* Setup BER measurement */
55819a0bf528SMauro Carvalho Chehab 	status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
55829a0bf528SMauro Carvalho Chehab 	if (status < 0)
55839a0bf528SMauro Carvalho Chehab 		goto error;
55849a0bf528SMauro Carvalho Chehab 
55859a0bf528SMauro Carvalho Chehab 	/* Reset default values */
55869a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55879a0bf528SMauro Carvalho Chehab 	if (status < 0)
55889a0bf528SMauro Carvalho Chehab 		goto error;
55899a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55909a0bf528SMauro Carvalho Chehab 	if (status < 0)
55919a0bf528SMauro Carvalho Chehab 		goto error;
55929a0bf528SMauro Carvalho Chehab 
55939a0bf528SMauro Carvalho Chehab 	/* Reset default LC values */
55949a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55959a0bf528SMauro Carvalho Chehab 	if (status < 0)
55969a0bf528SMauro Carvalho Chehab 		goto error;
55979a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55989a0bf528SMauro Carvalho Chehab 	if (status < 0)
55999a0bf528SMauro Carvalho Chehab 		goto error;
56009a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
56019a0bf528SMauro Carvalho Chehab 	if (status < 0)
56029a0bf528SMauro Carvalho Chehab 		goto error;
56039a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_MODE__A, 7);
56049a0bf528SMauro Carvalho Chehab 	if (status < 0)
56059a0bf528SMauro Carvalho Chehab 		goto error;
56069a0bf528SMauro Carvalho Chehab 
56079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
56089a0bf528SMauro Carvalho Chehab 	if (status < 0)
56099a0bf528SMauro Carvalho Chehab 		goto error;
56109a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
56119a0bf528SMauro Carvalho Chehab 	if (status < 0)
56129a0bf528SMauro Carvalho Chehab 		goto error;
56139a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
56149a0bf528SMauro Carvalho Chehab 	if (status < 0)
56159a0bf528SMauro Carvalho Chehab 		goto error;
56169a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
56179a0bf528SMauro Carvalho Chehab 	if (status < 0)
56189a0bf528SMauro Carvalho Chehab 		goto error;
56199a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
56209a0bf528SMauro Carvalho Chehab 	if (status < 0)
56219a0bf528SMauro Carvalho Chehab 		goto error;
56229a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
56239a0bf528SMauro Carvalho Chehab 	if (status < 0)
56249a0bf528SMauro Carvalho Chehab 		goto error;
56259a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
56269a0bf528SMauro Carvalho Chehab 	if (status < 0)
56279a0bf528SMauro Carvalho Chehab 		goto error;
56289a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
56299a0bf528SMauro Carvalho Chehab 	if (status < 0)
56309a0bf528SMauro Carvalho Chehab 		goto error;
56319a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
56329a0bf528SMauro Carvalho Chehab 	if (status < 0)
56339a0bf528SMauro Carvalho Chehab 		goto error;
56349a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
56359a0bf528SMauro Carvalho Chehab 	if (status < 0)
56369a0bf528SMauro Carvalho Chehab 		goto error;
56379a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
56389a0bf528SMauro Carvalho Chehab 	if (status < 0)
56399a0bf528SMauro Carvalho Chehab 		goto error;
56409a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
56419a0bf528SMauro Carvalho Chehab 	if (status < 0)
56429a0bf528SMauro Carvalho Chehab 		goto error;
56439a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
56449a0bf528SMauro Carvalho Chehab 	if (status < 0)
56459a0bf528SMauro Carvalho Chehab 		goto error;
56469a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
56479a0bf528SMauro Carvalho Chehab 	if (status < 0)
56489a0bf528SMauro Carvalho Chehab 		goto error;
56499a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
56509a0bf528SMauro Carvalho Chehab 	if (status < 0)
56519a0bf528SMauro Carvalho Chehab 		goto error;
56529a0bf528SMauro Carvalho Chehab 
56539a0bf528SMauro Carvalho Chehab 	/* Mirroring, QAM-block starting point not inverted */
56549a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
56559a0bf528SMauro Carvalho Chehab 	if (status < 0)
56569a0bf528SMauro Carvalho Chehab 		goto error;
56579a0bf528SMauro Carvalho Chehab 
56589a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
56599a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
56609a0bf528SMauro Carvalho Chehab 	if (status < 0)
56619a0bf528SMauro Carvalho Chehab 		goto error;
56629a0bf528SMauro Carvalho Chehab 
56639a0bf528SMauro Carvalho Chehab 	/* STEP 4: modulation specific setup */
56649a0bf528SMauro Carvalho Chehab 	switch (state->props.modulation) {
56659a0bf528SMauro Carvalho Chehab 	case QAM_16:
56669a0bf528SMauro Carvalho Chehab 		status = SetQAM16(state);
56679a0bf528SMauro Carvalho Chehab 		break;
56689a0bf528SMauro Carvalho Chehab 	case QAM_32:
56699a0bf528SMauro Carvalho Chehab 		status = SetQAM32(state);
56709a0bf528SMauro Carvalho Chehab 		break;
56719a0bf528SMauro Carvalho Chehab 	case QAM_AUTO:
56729a0bf528SMauro Carvalho Chehab 	case QAM_64:
56739a0bf528SMauro Carvalho Chehab 		status = SetQAM64(state);
56749a0bf528SMauro Carvalho Chehab 		break;
56759a0bf528SMauro Carvalho Chehab 	case QAM_128:
56769a0bf528SMauro Carvalho Chehab 		status = SetQAM128(state);
56779a0bf528SMauro Carvalho Chehab 		break;
56789a0bf528SMauro Carvalho Chehab 	case QAM_256:
56799a0bf528SMauro Carvalho Chehab 		status = SetQAM256(state);
56809a0bf528SMauro Carvalho Chehab 		break;
56819a0bf528SMauro Carvalho Chehab 	default:
56829a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
56839a0bf528SMauro Carvalho Chehab 		break;
56849a0bf528SMauro Carvalho Chehab 	}
56859a0bf528SMauro Carvalho Chehab 	if (status < 0)
56869a0bf528SMauro Carvalho Chehab 		goto error;
56879a0bf528SMauro Carvalho Chehab 
56889a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
56899a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56909a0bf528SMauro Carvalho Chehab 	if (status < 0)
56919a0bf528SMauro Carvalho Chehab 		goto error;
56929a0bf528SMauro Carvalho Chehab 
56939a0bf528SMauro Carvalho Chehab 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
56949a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.modulation = channel->modulation; */
56959a0bf528SMauro Carvalho Chehab 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
56969a0bf528SMauro Carvalho Chehab 	status = MPEGTSDtoSetup(state, state->m_OperationMode);
56979a0bf528SMauro Carvalho Chehab 	if (status < 0)
56989a0bf528SMauro Carvalho Chehab 		goto error;
56999a0bf528SMauro Carvalho Chehab 
57009a0bf528SMauro Carvalho Chehab 	/* Start processes */
57019a0bf528SMauro Carvalho Chehab 	status = MPEGTSStart(state);
57029a0bf528SMauro Carvalho Chehab 	if (status < 0)
57039a0bf528SMauro Carvalho Chehab 		goto error;
57049a0bf528SMauro Carvalho Chehab 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
57059a0bf528SMauro Carvalho Chehab 	if (status < 0)
57069a0bf528SMauro Carvalho Chehab 		goto error;
57079a0bf528SMauro Carvalho Chehab 	status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
57089a0bf528SMauro Carvalho Chehab 	if (status < 0)
57099a0bf528SMauro Carvalho Chehab 		goto error;
57109a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
57119a0bf528SMauro Carvalho Chehab 	if (status < 0)
57129a0bf528SMauro Carvalho Chehab 		goto error;
57139a0bf528SMauro Carvalho Chehab 
57149a0bf528SMauro Carvalho Chehab 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
57159a0bf528SMauro Carvalho Chehab 	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
57169a0bf528SMauro Carvalho Chehab 	if (status < 0)
57179a0bf528SMauro Carvalho Chehab 		goto error;
57189a0bf528SMauro Carvalho Chehab 
57199a0bf528SMauro Carvalho Chehab 	/* update global DRXK data container */
57209a0bf528SMauro Carvalho Chehab /*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
57219a0bf528SMauro Carvalho Chehab 
57229a0bf528SMauro Carvalho Chehab error:
57239a0bf528SMauro Carvalho Chehab 	if (status < 0)
57249a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
57259a0bf528SMauro Carvalho Chehab 	return status;
57269a0bf528SMauro Carvalho Chehab }
57279a0bf528SMauro Carvalho Chehab 
57289a0bf528SMauro Carvalho Chehab static int SetQAMStandard(struct drxk_state *state,
57299a0bf528SMauro Carvalho Chehab 			  enum OperationMode oMode)
57309a0bf528SMauro Carvalho Chehab {
57319a0bf528SMauro Carvalho Chehab 	int status;
57329a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
57339a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
57349a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
57359a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
57369a0bf528SMauro Carvalho Chehab #endif
57379a0bf528SMauro Carvalho Chehab 
57389a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
57399a0bf528SMauro Carvalho Chehab 
57409a0bf528SMauro Carvalho Chehab 	/* added antenna switch */
57419a0bf528SMauro Carvalho Chehab 	SwitchAntennaToQAM(state);
57429a0bf528SMauro Carvalho Chehab 
57439a0bf528SMauro Carvalho Chehab 	/* Ensure correct power-up mode */
57449a0bf528SMauro Carvalho Chehab 	status = PowerUpQAM(state);
57459a0bf528SMauro Carvalho Chehab 	if (status < 0)
57469a0bf528SMauro Carvalho Chehab 		goto error;
57479a0bf528SMauro Carvalho Chehab 	/* Reset QAM block */
57489a0bf528SMauro Carvalho Chehab 	status = QAMResetQAM(state);
57499a0bf528SMauro Carvalho Chehab 	if (status < 0)
57509a0bf528SMauro Carvalho Chehab 		goto error;
57519a0bf528SMauro Carvalho Chehab 
57529a0bf528SMauro Carvalho Chehab 	/* Setup IQM */
57539a0bf528SMauro Carvalho Chehab 
57549a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
57559a0bf528SMauro Carvalho Chehab 	if (status < 0)
57569a0bf528SMauro Carvalho Chehab 		goto error;
57579a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
57589a0bf528SMauro Carvalho Chehab 	if (status < 0)
57599a0bf528SMauro Carvalho Chehab 		goto error;
57609a0bf528SMauro Carvalho Chehab 
57619a0bf528SMauro Carvalho Chehab 	/* Upload IQM Channel Filter settings by
57629a0bf528SMauro Carvalho Chehab 		boot loader from ROM table */
57639a0bf528SMauro Carvalho Chehab 	switch (oMode) {
57649a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_A:
57659a0bf528SMauro Carvalho Chehab 		status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
57669a0bf528SMauro Carvalho Chehab 		break;
57679a0bf528SMauro Carvalho Chehab 	case OM_QAM_ITU_C:
57689a0bf528SMauro Carvalho Chehab 		status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
57699a0bf528SMauro Carvalho Chehab 		if (status < 0)
57709a0bf528SMauro Carvalho Chehab 			goto error;
57719a0bf528SMauro Carvalho Chehab 		status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
57729a0bf528SMauro Carvalho Chehab 		break;
57739a0bf528SMauro Carvalho Chehab 	default:
57749a0bf528SMauro Carvalho Chehab 		status = -EINVAL;
57759a0bf528SMauro Carvalho Chehab 	}
57769a0bf528SMauro Carvalho Chehab 	if (status < 0)
57779a0bf528SMauro Carvalho Chehab 		goto error;
57789a0bf528SMauro Carvalho Chehab 
57799a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
57809a0bf528SMauro Carvalho Chehab 	if (status < 0)
57819a0bf528SMauro Carvalho Chehab 		goto error;
57829a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57839a0bf528SMauro Carvalho Chehab 	if (status < 0)
57849a0bf528SMauro Carvalho Chehab 		goto error;
57859a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57869a0bf528SMauro Carvalho Chehab 	if (status < 0)
57879a0bf528SMauro Carvalho Chehab 		goto error;
57889a0bf528SMauro Carvalho Chehab 
57899a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_STRETCH__A, 21);
57909a0bf528SMauro Carvalho Chehab 	if (status < 0)
57919a0bf528SMauro Carvalho Chehab 		goto error;
57929a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_LEN__A, 0);
57939a0bf528SMauro Carvalho Chehab 	if (status < 0)
57949a0bf528SMauro Carvalho Chehab 		goto error;
57959a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_CLP_TH__A, 448);
57969a0bf528SMauro Carvalho Chehab 	if (status < 0)
57979a0bf528SMauro Carvalho Chehab 		goto error;
57989a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_SNS_LEN__A, 0);
57999a0bf528SMauro Carvalho Chehab 	if (status < 0)
58009a0bf528SMauro Carvalho Chehab 		goto error;
58019a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
58029a0bf528SMauro Carvalho Chehab 	if (status < 0)
58039a0bf528SMauro Carvalho Chehab 		goto error;
58049a0bf528SMauro Carvalho Chehab 
58059a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_FS_ADJ_SEL__A, 1);
58069a0bf528SMauro Carvalho Chehab 	if (status < 0)
58079a0bf528SMauro Carvalho Chehab 		goto error;
58089a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_RC_ADJ_SEL__A, 1);
58099a0bf528SMauro Carvalho Chehab 	if (status < 0)
58109a0bf528SMauro Carvalho Chehab 		goto error;
58119a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_ADJ_SEL__A, 1);
58129a0bf528SMauro Carvalho Chehab 	if (status < 0)
58139a0bf528SMauro Carvalho Chehab 		goto error;
58149a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_UPD_SEL__A, 0);
58159a0bf528SMauro Carvalho Chehab 	if (status < 0)
58169a0bf528SMauro Carvalho Chehab 		goto error;
58179a0bf528SMauro Carvalho Chehab 
58189a0bf528SMauro Carvalho Chehab 	/* IQM Impulse Noise Processing Unit */
58199a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_CLP_VAL__A, 500);
58209a0bf528SMauro Carvalho Chehab 	if (status < 0)
58219a0bf528SMauro Carvalho Chehab 		goto error;
58229a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DATATH__A, 1000);
58239a0bf528SMauro Carvalho Chehab 	if (status < 0)
58249a0bf528SMauro Carvalho Chehab 		goto error;
58259a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_BYPASSDET__A, 1);
58269a0bf528SMauro Carvalho Chehab 	if (status < 0)
58279a0bf528SMauro Carvalho Chehab 		goto error;
58289a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_DET_LCT__A, 0);
58299a0bf528SMauro Carvalho Chehab 	if (status < 0)
58309a0bf528SMauro Carvalho Chehab 		goto error;
58319a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_WND_LEN__A, 1);
58329a0bf528SMauro Carvalho Chehab 	if (status < 0)
58339a0bf528SMauro Carvalho Chehab 		goto error;
58349a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_CF_PKDTH__A, 1);
58359a0bf528SMauro Carvalho Chehab 	if (status < 0)
58369a0bf528SMauro Carvalho Chehab 		goto error;
58379a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_INC_BYPASS__A, 1);
58389a0bf528SMauro Carvalho Chehab 	if (status < 0)
58399a0bf528SMauro Carvalho Chehab 		goto error;
58409a0bf528SMauro Carvalho Chehab 
58419a0bf528SMauro Carvalho Chehab 	/* turn on IQMAF. Must be done before setAgc**() */
58429a0bf528SMauro Carvalho Chehab 	status = SetIqmAf(state, true);
58439a0bf528SMauro Carvalho Chehab 	if (status < 0)
58449a0bf528SMauro Carvalho Chehab 		goto error;
58459a0bf528SMauro Carvalho Chehab 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
58469a0bf528SMauro Carvalho Chehab 	if (status < 0)
58479a0bf528SMauro Carvalho Chehab 		goto error;
58489a0bf528SMauro Carvalho Chehab 
58499a0bf528SMauro Carvalho Chehab 	/* IQM will not be reset from here, sync ADC and update/init AGC */
58509a0bf528SMauro Carvalho Chehab 	status = ADCSynchronization(state);
58519a0bf528SMauro Carvalho Chehab 	if (status < 0)
58529a0bf528SMauro Carvalho Chehab 		goto error;
58539a0bf528SMauro Carvalho Chehab 
58549a0bf528SMauro Carvalho Chehab 	/* Set the FSM step period */
58559a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
58569a0bf528SMauro Carvalho Chehab 	if (status < 0)
58579a0bf528SMauro Carvalho Chehab 		goto error;
58589a0bf528SMauro Carvalho Chehab 
58599a0bf528SMauro Carvalho Chehab 	/* Halt SCU to enable safe non-atomic accesses */
58609a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
58619a0bf528SMauro Carvalho Chehab 	if (status < 0)
58629a0bf528SMauro Carvalho Chehab 		goto error;
58639a0bf528SMauro Carvalho Chehab 
58649a0bf528SMauro Carvalho Chehab 	/* No more resets of the IQM, current standard correctly set =>
58659a0bf528SMauro Carvalho Chehab 		now AGCs can be configured. */
58669a0bf528SMauro Carvalho Chehab 
58679a0bf528SMauro Carvalho Chehab 	status = InitAGC(state, true);
58689a0bf528SMauro Carvalho Chehab 	if (status < 0)
58699a0bf528SMauro Carvalho Chehab 		goto error;
58709a0bf528SMauro Carvalho Chehab 	status = SetPreSaw(state, &(state->m_qamPreSawCfg));
58719a0bf528SMauro Carvalho Chehab 	if (status < 0)
58729a0bf528SMauro Carvalho Chehab 		goto error;
58739a0bf528SMauro Carvalho Chehab 
58749a0bf528SMauro Carvalho Chehab 	/* Configure AGC's */
58759a0bf528SMauro Carvalho Chehab 	status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
58769a0bf528SMauro Carvalho Chehab 	if (status < 0)
58779a0bf528SMauro Carvalho Chehab 		goto error;
58789a0bf528SMauro Carvalho Chehab 	status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
58799a0bf528SMauro Carvalho Chehab 	if (status < 0)
58809a0bf528SMauro Carvalho Chehab 		goto error;
58819a0bf528SMauro Carvalho Chehab 
58829a0bf528SMauro Carvalho Chehab 	/* Activate SCU to enable SCU commands */
58839a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58849a0bf528SMauro Carvalho Chehab error:
58859a0bf528SMauro Carvalho Chehab 	if (status < 0)
58869a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
58879a0bf528SMauro Carvalho Chehab 	return status;
58889a0bf528SMauro Carvalho Chehab }
58899a0bf528SMauro Carvalho Chehab 
58909a0bf528SMauro Carvalho Chehab static int WriteGPIO(struct drxk_state *state)
58919a0bf528SMauro Carvalho Chehab {
58929a0bf528SMauro Carvalho Chehab 	int status;
58939a0bf528SMauro Carvalho Chehab 	u16 value = 0;
58949a0bf528SMauro Carvalho Chehab 
58959a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
58969a0bf528SMauro Carvalho Chehab 	/* stop lock indicator process */
58979a0bf528SMauro Carvalho Chehab 	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58989a0bf528SMauro Carvalho Chehab 	if (status < 0)
58999a0bf528SMauro Carvalho Chehab 		goto error;
59009a0bf528SMauro Carvalho Chehab 
59019a0bf528SMauro Carvalho Chehab 	/*  Write magic word to enable pdr reg write               */
59029a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
59039a0bf528SMauro Carvalho Chehab 	if (status < 0)
59049a0bf528SMauro Carvalho Chehab 		goto error;
59059a0bf528SMauro Carvalho Chehab 
59069a0bf528SMauro Carvalho Chehab 	if (state->m_hasSAWSW) {
59079a0bf528SMauro Carvalho Chehab 		if (state->UIO_mask & 0x0001) { /* UIO-1 */
59089a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
59099a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
59109a0bf528SMauro Carvalho Chehab 			if (status < 0)
59119a0bf528SMauro Carvalho Chehab 				goto error;
59129a0bf528SMauro Carvalho Chehab 
59139a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59149a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59159a0bf528SMauro Carvalho Chehab 			if (status < 0)
59169a0bf528SMauro Carvalho Chehab 				goto error;
59179a0bf528SMauro Carvalho Chehab 			if ((state->m_GPIO & 0x0001) == 0)
59189a0bf528SMauro Carvalho Chehab 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
59199a0bf528SMauro Carvalho Chehab 			else
59209a0bf528SMauro Carvalho Chehab 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
59219a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59229a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59239a0bf528SMauro Carvalho Chehab 			if (status < 0)
59249a0bf528SMauro Carvalho Chehab 				goto error;
59259a0bf528SMauro Carvalho Chehab 		}
59269a0bf528SMauro Carvalho Chehab 		if (state->UIO_mask & 0x0002) { /* UIO-2 */
59279a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
59289a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
59299a0bf528SMauro Carvalho Chehab 			if (status < 0)
59309a0bf528SMauro Carvalho Chehab 				goto error;
59319a0bf528SMauro Carvalho Chehab 
59329a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59339a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59349a0bf528SMauro Carvalho Chehab 			if (status < 0)
59359a0bf528SMauro Carvalho Chehab 				goto error;
59369a0bf528SMauro Carvalho Chehab 			if ((state->m_GPIO & 0x0002) == 0)
59379a0bf528SMauro Carvalho Chehab 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
59389a0bf528SMauro Carvalho Chehab 			else
59399a0bf528SMauro Carvalho Chehab 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
59409a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59419a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59429a0bf528SMauro Carvalho Chehab 			if (status < 0)
59439a0bf528SMauro Carvalho Chehab 				goto error;
59449a0bf528SMauro Carvalho Chehab 		}
59459a0bf528SMauro Carvalho Chehab 		if (state->UIO_mask & 0x0004) { /* UIO-3 */
59469a0bf528SMauro Carvalho Chehab 			/* write to io pad configuration register - output mode */
59479a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
59489a0bf528SMauro Carvalho Chehab 			if (status < 0)
59499a0bf528SMauro Carvalho Chehab 				goto error;
59509a0bf528SMauro Carvalho Chehab 
59519a0bf528SMauro Carvalho Chehab 			/* use corresponding bit in io data output registar */
59529a0bf528SMauro Carvalho Chehab 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
59539a0bf528SMauro Carvalho Chehab 			if (status < 0)
59549a0bf528SMauro Carvalho Chehab 				goto error;
59559a0bf528SMauro Carvalho Chehab 			if ((state->m_GPIO & 0x0004) == 0)
59569a0bf528SMauro Carvalho Chehab 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
59579a0bf528SMauro Carvalho Chehab 			else
59589a0bf528SMauro Carvalho Chehab 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
59599a0bf528SMauro Carvalho Chehab 			/* write back to io data output register */
59609a0bf528SMauro Carvalho Chehab 			status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
59619a0bf528SMauro Carvalho Chehab 			if (status < 0)
59629a0bf528SMauro Carvalho Chehab 				goto error;
59639a0bf528SMauro Carvalho Chehab 		}
59649a0bf528SMauro Carvalho Chehab 	}
59659a0bf528SMauro Carvalho Chehab 	/*  Write magic word to disable pdr reg write               */
59669a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59679a0bf528SMauro Carvalho Chehab error:
59689a0bf528SMauro Carvalho Chehab 	if (status < 0)
59699a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
59709a0bf528SMauro Carvalho Chehab 	return status;
59719a0bf528SMauro Carvalho Chehab }
59729a0bf528SMauro Carvalho Chehab 
59739a0bf528SMauro Carvalho Chehab static int SwitchAntennaToQAM(struct drxk_state *state)
59749a0bf528SMauro Carvalho Chehab {
59759a0bf528SMauro Carvalho Chehab 	int status = 0;
59769a0bf528SMauro Carvalho Chehab 	bool gpio_state;
59779a0bf528SMauro Carvalho Chehab 
59789a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
59799a0bf528SMauro Carvalho Chehab 
59809a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
59819a0bf528SMauro Carvalho Chehab 		return 0;
59829a0bf528SMauro Carvalho Chehab 
59839a0bf528SMauro Carvalho Chehab 	gpio_state = state->m_GPIO & state->antenna_gpio;
59849a0bf528SMauro Carvalho Chehab 
59859a0bf528SMauro Carvalho Chehab 	if (state->antenna_dvbt ^ gpio_state) {
59869a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-T mode. Switch */
59879a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
59889a0bf528SMauro Carvalho Chehab 			state->m_GPIO &= ~state->antenna_gpio;
59899a0bf528SMauro Carvalho Chehab 		else
59909a0bf528SMauro Carvalho Chehab 			state->m_GPIO |= state->antenna_gpio;
59919a0bf528SMauro Carvalho Chehab 		status = WriteGPIO(state);
59929a0bf528SMauro Carvalho Chehab 	}
59939a0bf528SMauro Carvalho Chehab 	if (status < 0)
59949a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
59959a0bf528SMauro Carvalho Chehab 	return status;
59969a0bf528SMauro Carvalho Chehab }
59979a0bf528SMauro Carvalho Chehab 
59989a0bf528SMauro Carvalho Chehab static int SwitchAntennaToDVBT(struct drxk_state *state)
59999a0bf528SMauro Carvalho Chehab {
60009a0bf528SMauro Carvalho Chehab 	int status = 0;
60019a0bf528SMauro Carvalho Chehab 	bool gpio_state;
60029a0bf528SMauro Carvalho Chehab 
60039a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60049a0bf528SMauro Carvalho Chehab 
60059a0bf528SMauro Carvalho Chehab 	if (!state->antenna_gpio)
60069a0bf528SMauro Carvalho Chehab 		return 0;
60079a0bf528SMauro Carvalho Chehab 
60089a0bf528SMauro Carvalho Chehab 	gpio_state = state->m_GPIO & state->antenna_gpio;
60099a0bf528SMauro Carvalho Chehab 
60109a0bf528SMauro Carvalho Chehab 	if (!(state->antenna_dvbt ^ gpio_state)) {
60119a0bf528SMauro Carvalho Chehab 		/* Antenna is on DVB-C mode. Switch */
60129a0bf528SMauro Carvalho Chehab 		if (state->antenna_dvbt)
60139a0bf528SMauro Carvalho Chehab 			state->m_GPIO |= state->antenna_gpio;
60149a0bf528SMauro Carvalho Chehab 		else
60159a0bf528SMauro Carvalho Chehab 			state->m_GPIO &= ~state->antenna_gpio;
60169a0bf528SMauro Carvalho Chehab 		status = WriteGPIO(state);
60179a0bf528SMauro Carvalho Chehab 	}
60189a0bf528SMauro Carvalho Chehab 	if (status < 0)
60199a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
60209a0bf528SMauro Carvalho Chehab 	return status;
60219a0bf528SMauro Carvalho Chehab }
60229a0bf528SMauro Carvalho Chehab 
60239a0bf528SMauro Carvalho Chehab 
60249a0bf528SMauro Carvalho Chehab static int PowerDownDevice(struct drxk_state *state)
60259a0bf528SMauro Carvalho Chehab {
60269a0bf528SMauro Carvalho Chehab 	/* Power down to requested mode */
60279a0bf528SMauro Carvalho Chehab 	/* Backup some register settings */
60289a0bf528SMauro Carvalho Chehab 	/* Set pins with possible pull-ups connected to them in input mode */
60299a0bf528SMauro Carvalho Chehab 	/* Analog power down */
60309a0bf528SMauro Carvalho Chehab 	/* ADC power down */
60319a0bf528SMauro Carvalho Chehab 	/* Power down device */
60329a0bf528SMauro Carvalho Chehab 	int status;
60339a0bf528SMauro Carvalho Chehab 
60349a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60359a0bf528SMauro Carvalho Chehab 	if (state->m_bPDownOpenBridge) {
60369a0bf528SMauro Carvalho Chehab 		/* Open I2C bridge before power down of DRXK */
60379a0bf528SMauro Carvalho Chehab 		status = ConfigureI2CBridge(state, true);
60389a0bf528SMauro Carvalho Chehab 		if (status < 0)
60399a0bf528SMauro Carvalho Chehab 			goto error;
60409a0bf528SMauro Carvalho Chehab 	}
60419a0bf528SMauro Carvalho Chehab 	/* driver 0.9.0 */
60429a0bf528SMauro Carvalho Chehab 	status = DVBTEnableOFDMTokenRing(state, false);
60439a0bf528SMauro Carvalho Chehab 	if (status < 0)
60449a0bf528SMauro Carvalho Chehab 		goto error;
60459a0bf528SMauro Carvalho Chehab 
60469a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
60479a0bf528SMauro Carvalho Chehab 	if (status < 0)
60489a0bf528SMauro Carvalho Chehab 		goto error;
60499a0bf528SMauro Carvalho Chehab 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60509a0bf528SMauro Carvalho Chehab 	if (status < 0)
60519a0bf528SMauro Carvalho Chehab 		goto error;
60529a0bf528SMauro Carvalho Chehab 	state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
60539a0bf528SMauro Carvalho Chehab 	status = HI_CfgCommand(state);
60549a0bf528SMauro Carvalho Chehab error:
60559a0bf528SMauro Carvalho Chehab 	if (status < 0)
60569a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
60579a0bf528SMauro Carvalho Chehab 
60589a0bf528SMauro Carvalho Chehab 	return status;
60599a0bf528SMauro Carvalho Chehab }
60609a0bf528SMauro Carvalho Chehab 
60619a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60629a0bf528SMauro Carvalho Chehab {
60639a0bf528SMauro Carvalho Chehab 	int status = 0, n = 0;
60649a0bf528SMauro Carvalho Chehab 	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
60659a0bf528SMauro Carvalho Chehab 	u16 driverVersion;
60669a0bf528SMauro Carvalho Chehab 
60679a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
60689a0bf528SMauro Carvalho Chehab 	if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
60699a0bf528SMauro Carvalho Chehab 		drxk_i2c_lock(state);
60709a0bf528SMauro Carvalho Chehab 		status = PowerUpDevice(state);
60719a0bf528SMauro Carvalho Chehab 		if (status < 0)
60729a0bf528SMauro Carvalho Chehab 			goto error;
60739a0bf528SMauro Carvalho Chehab 		status = DRXX_Open(state);
60749a0bf528SMauro Carvalho Chehab 		if (status < 0)
60759a0bf528SMauro Carvalho Chehab 			goto error;
60769a0bf528SMauro Carvalho Chehab 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
60779a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
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;
60839a0bf528SMauro Carvalho Chehab 		/* TODO is this needed, if yes how much delay in worst case scenario */
60849a0bf528SMauro Carvalho Chehab 		msleep(1);
60859a0bf528SMauro Carvalho Chehab 		state->m_DRXK_A3_PATCH_CODE = true;
60869a0bf528SMauro Carvalho Chehab 		status = GetDeviceCapabilities(state);
60879a0bf528SMauro Carvalho Chehab 		if (status < 0)
60889a0bf528SMauro Carvalho Chehab 			goto error;
60899a0bf528SMauro Carvalho Chehab 
60909a0bf528SMauro Carvalho Chehab 		/* Bridge delay, uses oscilator clock */
60919a0bf528SMauro Carvalho Chehab 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60929a0bf528SMauro Carvalho Chehab 		/* SDA brdige delay */
60939a0bf528SMauro Carvalho Chehab 		state->m_HICfgBridgeDelay =
60949a0bf528SMauro Carvalho Chehab 			(u16) ((state->m_oscClockFreq / 1000) *
60959a0bf528SMauro Carvalho Chehab 				HI_I2C_BRIDGE_DELAY) / 1000;
60969a0bf528SMauro Carvalho Chehab 		/* Clipping */
60979a0bf528SMauro Carvalho Chehab 		if (state->m_HICfgBridgeDelay >
60989a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
60999a0bf528SMauro Carvalho Chehab 			state->m_HICfgBridgeDelay =
61009a0bf528SMauro Carvalho Chehab 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
61019a0bf528SMauro Carvalho Chehab 		}
61029a0bf528SMauro Carvalho Chehab 		/* SCL bridge delay, same as SDA for now */
61039a0bf528SMauro Carvalho Chehab 		state->m_HICfgBridgeDelay +=
61049a0bf528SMauro Carvalho Chehab 			state->m_HICfgBridgeDelay <<
61059a0bf528SMauro Carvalho Chehab 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
61069a0bf528SMauro Carvalho Chehab 
61079a0bf528SMauro Carvalho Chehab 		status = InitHI(state);
61089a0bf528SMauro Carvalho Chehab 		if (status < 0)
61099a0bf528SMauro Carvalho Chehab 			goto error;
61109a0bf528SMauro Carvalho Chehab 		/* disable various processes */
61119a0bf528SMauro Carvalho Chehab #if NOA1ROM
61129a0bf528SMauro Carvalho Chehab 		if (!(state->m_DRXK_A1_ROM_CODE)
61139a0bf528SMauro Carvalho Chehab 			&& !(state->m_DRXK_A2_ROM_CODE))
61149a0bf528SMauro Carvalho Chehab #endif
61159a0bf528SMauro Carvalho Chehab 		{
61169a0bf528SMauro Carvalho Chehab 			status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
61179a0bf528SMauro Carvalho Chehab 			if (status < 0)
61189a0bf528SMauro Carvalho Chehab 				goto error;
61199a0bf528SMauro Carvalho Chehab 		}
61209a0bf528SMauro Carvalho Chehab 
61219a0bf528SMauro Carvalho Chehab 		/* disable MPEG port */
61229a0bf528SMauro Carvalho Chehab 		status = MPEGTSDisable(state);
61239a0bf528SMauro Carvalho Chehab 		if (status < 0)
61249a0bf528SMauro Carvalho Chehab 			goto error;
61259a0bf528SMauro Carvalho Chehab 
61269a0bf528SMauro Carvalho Chehab 		/* Stop AUD and SCU */
61279a0bf528SMauro Carvalho Chehab 		status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
61289a0bf528SMauro Carvalho Chehab 		if (status < 0)
61299a0bf528SMauro Carvalho Chehab 			goto error;
61309a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
61319a0bf528SMauro Carvalho Chehab 		if (status < 0)
61329a0bf528SMauro Carvalho Chehab 			goto error;
61339a0bf528SMauro Carvalho Chehab 
61349a0bf528SMauro Carvalho Chehab 		/* enable token-ring bus through OFDM block for possible ucode upload */
61359a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
61369a0bf528SMauro Carvalho Chehab 		if (status < 0)
61379a0bf528SMauro Carvalho Chehab 			goto error;
61389a0bf528SMauro Carvalho Chehab 
61399a0bf528SMauro Carvalho Chehab 		/* include boot loader section */
61409a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
61419a0bf528SMauro Carvalho Chehab 		if (status < 0)
61429a0bf528SMauro Carvalho Chehab 			goto error;
61439a0bf528SMauro Carvalho Chehab 		status = BLChainCmd(state, 0, 6, 100);
61449a0bf528SMauro Carvalho Chehab 		if (status < 0)
61459a0bf528SMauro Carvalho Chehab 			goto error;
61469a0bf528SMauro Carvalho Chehab 
61479a0bf528SMauro Carvalho Chehab 		if (state->fw) {
61489a0bf528SMauro Carvalho Chehab 			status = DownloadMicrocode(state, state->fw->data,
61499a0bf528SMauro Carvalho Chehab 						   state->fw->size);
61509a0bf528SMauro Carvalho Chehab 			if (status < 0)
61519a0bf528SMauro Carvalho Chehab 				goto error;
61529a0bf528SMauro Carvalho Chehab 		}
61539a0bf528SMauro Carvalho Chehab 
61549a0bf528SMauro Carvalho Chehab 		/* disable token-ring bus through OFDM block for possible ucode upload */
61559a0bf528SMauro Carvalho Chehab 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
61569a0bf528SMauro Carvalho Chehab 		if (status < 0)
61579a0bf528SMauro Carvalho Chehab 			goto error;
61589a0bf528SMauro Carvalho Chehab 
61599a0bf528SMauro Carvalho Chehab 		/* Run SCU for a little while to initialize microcode version numbers */
61609a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61619a0bf528SMauro Carvalho Chehab 		if (status < 0)
61629a0bf528SMauro Carvalho Chehab 			goto error;
61639a0bf528SMauro Carvalho Chehab 		status = DRXX_Open(state);
61649a0bf528SMauro Carvalho Chehab 		if (status < 0)
61659a0bf528SMauro Carvalho Chehab 			goto error;
61669a0bf528SMauro Carvalho Chehab 		/* added for test */
61679a0bf528SMauro Carvalho Chehab 		msleep(30);
61689a0bf528SMauro Carvalho Chehab 
61699a0bf528SMauro Carvalho Chehab 		powerMode = DRXK_POWER_DOWN_OFDM;
61709a0bf528SMauro Carvalho Chehab 		status = CtrlPowerMode(state, &powerMode);
61719a0bf528SMauro Carvalho Chehab 		if (status < 0)
61729a0bf528SMauro Carvalho Chehab 			goto error;
61739a0bf528SMauro Carvalho Chehab 
61749a0bf528SMauro Carvalho Chehab 		/* Stamp driver version number in SCU data RAM in BCD code
61759a0bf528SMauro Carvalho Chehab 			Done to enable field application engineers to retreive drxdriver version
61769a0bf528SMauro Carvalho Chehab 			via I2C from SCU RAM.
61779a0bf528SMauro Carvalho Chehab 			Not using SCU command interface for SCU register access since no
61789a0bf528SMauro Carvalho Chehab 			microcode may be present.
61799a0bf528SMauro Carvalho Chehab 			*/
61809a0bf528SMauro Carvalho Chehab 		driverVersion =
61819a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61829a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61839a0bf528SMauro Carvalho Chehab 			((DRXK_VERSION_MAJOR % 10) << 4) +
61849a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_MINOR % 10);
61859a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
61869a0bf528SMauro Carvalho Chehab 		if (status < 0)
61879a0bf528SMauro Carvalho Chehab 			goto error;
61889a0bf528SMauro Carvalho Chehab 		driverVersion =
61899a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61909a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61919a0bf528SMauro Carvalho Chehab 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
61929a0bf528SMauro Carvalho Chehab 			(DRXK_VERSION_PATCH % 10);
61939a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
61949a0bf528SMauro Carvalho Chehab 		if (status < 0)
61959a0bf528SMauro Carvalho Chehab 			goto error;
61969a0bf528SMauro Carvalho Chehab 
61979a0bf528SMauro Carvalho Chehab 		printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
61989a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
61999a0bf528SMauro Carvalho Chehab 			DRXK_VERSION_PATCH);
62009a0bf528SMauro Carvalho Chehab 
62019a0bf528SMauro Carvalho Chehab 		/* Dirty fix of default values for ROM/PATCH microcode
62029a0bf528SMauro Carvalho Chehab 			Dirty because this fix makes it impossible to setup suitable values
62039a0bf528SMauro Carvalho Chehab 			before calling DRX_Open. This solution requires changes to RF AGC speed
62049a0bf528SMauro Carvalho Chehab 			to be done via the CTRL function after calling DRX_Open */
62059a0bf528SMauro Carvalho Chehab 
62069a0bf528SMauro Carvalho Chehab 		/* m_dvbtRfAgcCfg.speed = 3; */
62079a0bf528SMauro Carvalho Chehab 
62089a0bf528SMauro Carvalho Chehab 		/* Reset driver debug flags to 0 */
62099a0bf528SMauro Carvalho Chehab 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
62109a0bf528SMauro Carvalho Chehab 		if (status < 0)
62119a0bf528SMauro Carvalho Chehab 			goto error;
62129a0bf528SMauro Carvalho Chehab 		/* driver 0.9.0 */
62139a0bf528SMauro Carvalho Chehab 		/* Setup FEC OC:
62149a0bf528SMauro Carvalho Chehab 			NOTE: No more full FEC resets allowed afterwards!! */
62159a0bf528SMauro Carvalho Chehab 		status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
62169a0bf528SMauro Carvalho Chehab 		if (status < 0)
62179a0bf528SMauro Carvalho Chehab 			goto error;
62189a0bf528SMauro Carvalho Chehab 		/* MPEGTS functions are still the same */
62199a0bf528SMauro Carvalho Chehab 		status = MPEGTSDtoInit(state);
62209a0bf528SMauro Carvalho Chehab 		if (status < 0)
62219a0bf528SMauro Carvalho Chehab 			goto error;
62229a0bf528SMauro Carvalho Chehab 		status = MPEGTSStop(state);
62239a0bf528SMauro Carvalho Chehab 		if (status < 0)
62249a0bf528SMauro Carvalho Chehab 			goto error;
62259a0bf528SMauro Carvalho Chehab 		status = MPEGTSConfigurePolarity(state);
62269a0bf528SMauro Carvalho Chehab 		if (status < 0)
62279a0bf528SMauro Carvalho Chehab 			goto error;
62289a0bf528SMauro Carvalho Chehab 		status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
62299a0bf528SMauro Carvalho Chehab 		if (status < 0)
62309a0bf528SMauro Carvalho Chehab 			goto error;
62319a0bf528SMauro Carvalho Chehab 		/* added: configure GPIO */
62329a0bf528SMauro Carvalho Chehab 		status = WriteGPIO(state);
62339a0bf528SMauro Carvalho Chehab 		if (status < 0)
62349a0bf528SMauro Carvalho Chehab 			goto error;
62359a0bf528SMauro Carvalho Chehab 
62369a0bf528SMauro Carvalho Chehab 		state->m_DrxkState = DRXK_STOPPED;
62379a0bf528SMauro Carvalho Chehab 
62389a0bf528SMauro Carvalho Chehab 		if (state->m_bPowerDown) {
62399a0bf528SMauro Carvalho Chehab 			status = PowerDownDevice(state);
62409a0bf528SMauro Carvalho Chehab 			if (status < 0)
62419a0bf528SMauro Carvalho Chehab 				goto error;
62429a0bf528SMauro Carvalho Chehab 			state->m_DrxkState = DRXK_POWERED_DOWN;
62439a0bf528SMauro Carvalho Chehab 		} else
62449a0bf528SMauro Carvalho Chehab 			state->m_DrxkState = DRXK_STOPPED;
62459a0bf528SMauro Carvalho Chehab 
62469a0bf528SMauro Carvalho Chehab 		/* Initialize the supported delivery systems */
62479a0bf528SMauro Carvalho Chehab 		n = 0;
62489a0bf528SMauro Carvalho Chehab 		if (state->m_hasDVBC) {
62499a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62509a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62519a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-C",
62529a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62539a0bf528SMauro Carvalho Chehab 		}
62549a0bf528SMauro Carvalho Chehab 		if (state->m_hasDVBT) {
62559a0bf528SMauro Carvalho Chehab 			state->frontend.ops.delsys[n++] = SYS_DVBT;
62569a0bf528SMauro Carvalho Chehab 			strlcat(state->frontend.ops.info.name, " DVB-T",
62579a0bf528SMauro Carvalho Chehab 				sizeof(state->frontend.ops.info.name));
62589a0bf528SMauro Carvalho Chehab 		}
62599a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62609a0bf528SMauro Carvalho Chehab 	}
62619a0bf528SMauro Carvalho Chehab error:
62629a0bf528SMauro Carvalho Chehab 	if (status < 0) {
62639a0bf528SMauro Carvalho Chehab 		state->m_DrxkState = DRXK_NO_DEV;
62649a0bf528SMauro Carvalho Chehab 		drxk_i2c_unlock(state);
62659a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
62669a0bf528SMauro Carvalho Chehab 	}
62679a0bf528SMauro Carvalho Chehab 
62689a0bf528SMauro Carvalho Chehab 	return status;
62699a0bf528SMauro Carvalho Chehab }
62709a0bf528SMauro Carvalho Chehab 
62719a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62729a0bf528SMauro Carvalho Chehab 			     void *context)
62739a0bf528SMauro Carvalho Chehab {
62749a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = context;
62759a0bf528SMauro Carvalho Chehab 
62769a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62779a0bf528SMauro Carvalho Chehab 	if (!fw) {
62789a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR
62799a0bf528SMauro Carvalho Chehab 		       "drxk: Could not load firmware file %s.\n",
62809a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62819a0bf528SMauro Carvalho Chehab 		printk(KERN_INFO
62829a0bf528SMauro Carvalho Chehab 		       "drxk: Copy %s to your hotplug directory!\n",
62839a0bf528SMauro Carvalho Chehab 			state->microcode_name);
62849a0bf528SMauro Carvalho Chehab 		state->microcode_name = NULL;
62859a0bf528SMauro Carvalho Chehab 
62869a0bf528SMauro Carvalho Chehab 		/*
62879a0bf528SMauro Carvalho Chehab 		 * As firmware is now load asynchronous, it is not possible
62889a0bf528SMauro Carvalho Chehab 		 * anymore to fail at frontend attach. We might silently
62899a0bf528SMauro Carvalho Chehab 		 * return here, and hope that the driver won't crash.
62909a0bf528SMauro Carvalho Chehab 		 * We might also change all DVB callbacks to return -ENODEV
62919a0bf528SMauro Carvalho Chehab 		 * if the device is not initialized.
62929a0bf528SMauro Carvalho Chehab 		 * As the DRX-K devices have their own internal firmware,
62939a0bf528SMauro Carvalho Chehab 		 * let's just hope that it will match a firmware revision
62949a0bf528SMauro Carvalho Chehab 		 * compatible with this driver and proceed.
62959a0bf528SMauro Carvalho Chehab 		 */
62969a0bf528SMauro Carvalho Chehab 	}
62979a0bf528SMauro Carvalho Chehab 	state->fw = fw;
62989a0bf528SMauro Carvalho Chehab 
62999a0bf528SMauro Carvalho Chehab 	init_drxk(state);
63009a0bf528SMauro Carvalho Chehab }
63019a0bf528SMauro Carvalho Chehab 
63029a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
63039a0bf528SMauro Carvalho Chehab {
63049a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63059a0bf528SMauro Carvalho Chehab 
63069a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63079a0bf528SMauro Carvalho Chehab 	if (state->fw)
63089a0bf528SMauro Carvalho Chehab 		release_firmware(state->fw);
63099a0bf528SMauro Carvalho Chehab 
63109a0bf528SMauro Carvalho Chehab 	kfree(state);
63119a0bf528SMauro Carvalho Chehab }
63129a0bf528SMauro Carvalho Chehab 
63139a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
63149a0bf528SMauro Carvalho Chehab {
63159a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63169a0bf528SMauro Carvalho Chehab 
63179a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63189a0bf528SMauro Carvalho Chehab 
63199a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
63209a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63219a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
63229a0bf528SMauro Carvalho Chehab 		return 0;
63239a0bf528SMauro Carvalho Chehab 
63249a0bf528SMauro Carvalho Chehab 	ShutDown(state);
63259a0bf528SMauro Carvalho Chehab 	return 0;
63269a0bf528SMauro Carvalho Chehab }
63279a0bf528SMauro Carvalho Chehab 
63289a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
63299a0bf528SMauro Carvalho Chehab {
63309a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63319a0bf528SMauro Carvalho Chehab 
63329a0bf528SMauro Carvalho Chehab 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
63339a0bf528SMauro Carvalho Chehab 
63349a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
63359a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63369a0bf528SMauro Carvalho Chehab 
63379a0bf528SMauro Carvalho Chehab 	return ConfigureI2CBridge(state, enable ? true : false);
63389a0bf528SMauro Carvalho Chehab }
63399a0bf528SMauro Carvalho Chehab 
63409a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
63419a0bf528SMauro Carvalho Chehab {
63429a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
63439a0bf528SMauro Carvalho Chehab 	u32 delsys  = p->delivery_system, old_delsys;
63449a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
63459a0bf528SMauro Carvalho Chehab 	u32 IF;
63469a0bf528SMauro Carvalho Chehab 
63479a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
63489a0bf528SMauro Carvalho Chehab 
63499a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
63509a0bf528SMauro Carvalho Chehab 		return -ENODEV;
63519a0bf528SMauro Carvalho Chehab 
63529a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
63539a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
63549a0bf528SMauro Carvalho Chehab 
63559a0bf528SMauro Carvalho Chehab 	if (!fe->ops.tuner_ops.get_if_frequency) {
63569a0bf528SMauro Carvalho Chehab 		printk(KERN_ERR
63579a0bf528SMauro Carvalho Chehab 		       "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63589a0bf528SMauro Carvalho Chehab 		return -EINVAL;
63599a0bf528SMauro Carvalho Chehab 	}
63609a0bf528SMauro Carvalho Chehab 
63619a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63629a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 1);
63639a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
63649a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
63659a0bf528SMauro Carvalho Chehab 	if (fe->ops.i2c_gate_ctrl)
63669a0bf528SMauro Carvalho Chehab 		fe->ops.i2c_gate_ctrl(fe, 0);
63679a0bf528SMauro Carvalho Chehab 
63689a0bf528SMauro Carvalho Chehab 	old_delsys = state->props.delivery_system;
63699a0bf528SMauro Carvalho Chehab 	state->props = *p;
63709a0bf528SMauro Carvalho Chehab 
63719a0bf528SMauro Carvalho Chehab 	if (old_delsys != delsys) {
63729a0bf528SMauro Carvalho Chehab 		ShutDown(state);
63739a0bf528SMauro Carvalho Chehab 		switch (delsys) {
63749a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_A:
63759a0bf528SMauro Carvalho Chehab 		case SYS_DVBC_ANNEX_C:
63769a0bf528SMauro Carvalho Chehab 			if (!state->m_hasDVBC)
63779a0bf528SMauro Carvalho Chehab 				return -EINVAL;
63789a0bf528SMauro Carvalho Chehab 			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
63799a0bf528SMauro Carvalho Chehab 			if (state->m_itut_annex_c)
63809a0bf528SMauro Carvalho Chehab 				SetOperationMode(state, OM_QAM_ITU_C);
63819a0bf528SMauro Carvalho Chehab 			else
63829a0bf528SMauro Carvalho Chehab 				SetOperationMode(state, OM_QAM_ITU_A);
63839a0bf528SMauro Carvalho Chehab 			break;
63849a0bf528SMauro Carvalho Chehab 		case SYS_DVBT:
63859a0bf528SMauro Carvalho Chehab 			if (!state->m_hasDVBT)
63869a0bf528SMauro Carvalho Chehab 				return -EINVAL;
63879a0bf528SMauro Carvalho Chehab 			SetOperationMode(state, OM_DVBT);
63889a0bf528SMauro Carvalho Chehab 			break;
63899a0bf528SMauro Carvalho Chehab 		default:
63909a0bf528SMauro Carvalho Chehab 			return -EINVAL;
63919a0bf528SMauro Carvalho Chehab 		}
63929a0bf528SMauro Carvalho Chehab 	}
63939a0bf528SMauro Carvalho Chehab 
63949a0bf528SMauro Carvalho Chehab 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
63959a0bf528SMauro Carvalho Chehab 	Start(state, 0, IF);
63969a0bf528SMauro Carvalho Chehab 
63979a0bf528SMauro Carvalho Chehab 	/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
63989a0bf528SMauro Carvalho Chehab 
63999a0bf528SMauro Carvalho Chehab 	return 0;
64009a0bf528SMauro Carvalho Chehab }
64019a0bf528SMauro Carvalho Chehab 
64029a0bf528SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
64039a0bf528SMauro Carvalho Chehab {
64049a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64059a0bf528SMauro Carvalho Chehab 	u32 stat;
64069a0bf528SMauro Carvalho Chehab 
64079a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64089a0bf528SMauro Carvalho Chehab 
64099a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
64109a0bf528SMauro Carvalho Chehab 		return -ENODEV;
64119a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
64129a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64139a0bf528SMauro Carvalho Chehab 
64149a0bf528SMauro Carvalho Chehab 	*status = 0;
64159a0bf528SMauro Carvalho Chehab 	GetLockStatus(state, &stat, 0);
64169a0bf528SMauro Carvalho Chehab 	if (stat == MPEG_LOCK)
64179a0bf528SMauro Carvalho Chehab 		*status |= 0x1f;
64189a0bf528SMauro Carvalho Chehab 	if (stat == FEC_LOCK)
64199a0bf528SMauro Carvalho Chehab 		*status |= 0x0f;
64209a0bf528SMauro Carvalho Chehab 	if (stat == DEMOD_LOCK)
64219a0bf528SMauro Carvalho Chehab 		*status |= 0x07;
64229a0bf528SMauro Carvalho Chehab 	return 0;
64239a0bf528SMauro Carvalho Chehab }
64249a0bf528SMauro Carvalho Chehab 
64259a0bf528SMauro Carvalho Chehab static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
64269a0bf528SMauro Carvalho Chehab {
64279a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64289a0bf528SMauro Carvalho Chehab 
64299a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64309a0bf528SMauro Carvalho Chehab 
64319a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
64329a0bf528SMauro Carvalho Chehab 		return -ENODEV;
64339a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
64349a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64359a0bf528SMauro Carvalho Chehab 
64369a0bf528SMauro Carvalho Chehab 	*ber = 0;
64379a0bf528SMauro Carvalho Chehab 	return 0;
64389a0bf528SMauro Carvalho Chehab }
64399a0bf528SMauro Carvalho Chehab 
64409a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
64419a0bf528SMauro Carvalho Chehab 				     u16 *strength)
64429a0bf528SMauro Carvalho Chehab {
64439a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64449a0bf528SMauro Carvalho Chehab 	u32 val = 0;
64459a0bf528SMauro Carvalho Chehab 
64469a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64479a0bf528SMauro Carvalho Chehab 
64489a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
64499a0bf528SMauro Carvalho Chehab 		return -ENODEV;
64509a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
64519a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64529a0bf528SMauro Carvalho Chehab 
64539a0bf528SMauro Carvalho Chehab 	ReadIFAgc(state, &val);
64549a0bf528SMauro Carvalho Chehab 	*strength = val & 0xffff;
64559a0bf528SMauro Carvalho Chehab 	return 0;
64569a0bf528SMauro Carvalho Chehab }
64579a0bf528SMauro Carvalho Chehab 
64589a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
64599a0bf528SMauro Carvalho Chehab {
64609a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64619a0bf528SMauro Carvalho Chehab 	s32 snr2;
64629a0bf528SMauro Carvalho Chehab 
64639a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64649a0bf528SMauro Carvalho Chehab 
64659a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
64669a0bf528SMauro Carvalho Chehab 		return -ENODEV;
64679a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
64689a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64699a0bf528SMauro Carvalho Chehab 
64709a0bf528SMauro Carvalho Chehab 	GetSignalToNoise(state, &snr2);
64719a0bf528SMauro Carvalho Chehab 	*snr = snr2 & 0xffff;
64729a0bf528SMauro Carvalho Chehab 	return 0;
64739a0bf528SMauro Carvalho Chehab }
64749a0bf528SMauro Carvalho Chehab 
64759a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
64769a0bf528SMauro Carvalho Chehab {
64779a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64789a0bf528SMauro Carvalho Chehab 	u16 err;
64799a0bf528SMauro Carvalho Chehab 
64809a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64819a0bf528SMauro Carvalho Chehab 
64829a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
64839a0bf528SMauro Carvalho Chehab 		return -ENODEV;
64849a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
64859a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
64869a0bf528SMauro Carvalho Chehab 
64879a0bf528SMauro Carvalho Chehab 	DVBTQAMGetAccPktErr(state, &err);
64889a0bf528SMauro Carvalho Chehab 	*ucblocks = (u32) err;
64899a0bf528SMauro Carvalho Chehab 	return 0;
64909a0bf528SMauro Carvalho Chehab }
64919a0bf528SMauro Carvalho Chehab 
64929a0bf528SMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
64939a0bf528SMauro Carvalho Chehab 				    *sets)
64949a0bf528SMauro Carvalho Chehab {
64959a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = fe->demodulator_priv;
64969a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
64979a0bf528SMauro Carvalho Chehab 
64989a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
64999a0bf528SMauro Carvalho Chehab 
65009a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_NO_DEV)
65019a0bf528SMauro Carvalho Chehab 		return -ENODEV;
65029a0bf528SMauro Carvalho Chehab 	if (state->m_DrxkState == DRXK_UNINITIALIZED)
65039a0bf528SMauro Carvalho Chehab 		return -EAGAIN;
65049a0bf528SMauro Carvalho Chehab 
65059a0bf528SMauro Carvalho Chehab 	switch (p->delivery_system) {
65069a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_A:
65079a0bf528SMauro Carvalho Chehab 	case SYS_DVBC_ANNEX_C:
65089a0bf528SMauro Carvalho Chehab 	case SYS_DVBT:
65099a0bf528SMauro Carvalho Chehab 		sets->min_delay_ms = 3000;
65109a0bf528SMauro Carvalho Chehab 		sets->max_drift = 0;
65119a0bf528SMauro Carvalho Chehab 		sets->step_size = 0;
65129a0bf528SMauro Carvalho Chehab 		return 0;
65139a0bf528SMauro Carvalho Chehab 	default:
65149a0bf528SMauro Carvalho Chehab 		return -EINVAL;
65159a0bf528SMauro Carvalho Chehab 	}
65169a0bf528SMauro Carvalho Chehab }
65179a0bf528SMauro Carvalho Chehab 
65189a0bf528SMauro Carvalho Chehab static struct dvb_frontend_ops drxk_ops = {
65199a0bf528SMauro Carvalho Chehab 	/* .delsys will be filled dynamically */
65209a0bf528SMauro Carvalho Chehab 	.info = {
65219a0bf528SMauro Carvalho Chehab 		.name = "DRXK",
65229a0bf528SMauro Carvalho Chehab 		.frequency_min = 47000000,
65239a0bf528SMauro Carvalho Chehab 		.frequency_max = 865000000,
65249a0bf528SMauro Carvalho Chehab 		 /* For DVB-C */
65259a0bf528SMauro Carvalho Chehab 		.symbol_rate_min = 870000,
65269a0bf528SMauro Carvalho Chehab 		.symbol_rate_max = 11700000,
65279a0bf528SMauro Carvalho Chehab 		/* For DVB-T */
65289a0bf528SMauro Carvalho Chehab 		.frequency_stepsize = 166667,
65299a0bf528SMauro Carvalho Chehab 
65309a0bf528SMauro Carvalho Chehab 		.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
65319a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
65329a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
65339a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
65349a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
65359a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
65369a0bf528SMauro Carvalho Chehab 	},
65379a0bf528SMauro Carvalho Chehab 
65389a0bf528SMauro Carvalho Chehab 	.release = drxk_release,
65399a0bf528SMauro Carvalho Chehab 	.sleep = drxk_sleep,
65409a0bf528SMauro Carvalho Chehab 	.i2c_gate_ctrl = drxk_gate_ctrl,
65419a0bf528SMauro Carvalho Chehab 
65429a0bf528SMauro Carvalho Chehab 	.set_frontend = drxk_set_parameters,
65439a0bf528SMauro Carvalho Chehab 	.get_tune_settings = drxk_get_tune_settings,
65449a0bf528SMauro Carvalho Chehab 
65459a0bf528SMauro Carvalho Chehab 	.read_status = drxk_read_status,
65469a0bf528SMauro Carvalho Chehab 	.read_ber = drxk_read_ber,
65479a0bf528SMauro Carvalho Chehab 	.read_signal_strength = drxk_read_signal_strength,
65489a0bf528SMauro Carvalho Chehab 	.read_snr = drxk_read_snr,
65499a0bf528SMauro Carvalho Chehab 	.read_ucblocks = drxk_read_ucblocks,
65509a0bf528SMauro Carvalho Chehab };
65519a0bf528SMauro Carvalho Chehab 
65529a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
65539a0bf528SMauro Carvalho Chehab 				 struct i2c_adapter *i2c)
65549a0bf528SMauro Carvalho Chehab {
65559a0bf528SMauro Carvalho Chehab 	struct drxk_state *state = NULL;
65569a0bf528SMauro Carvalho Chehab 	u8 adr = config->adr;
65579a0bf528SMauro Carvalho Chehab 	int status;
65589a0bf528SMauro Carvalho Chehab 
65599a0bf528SMauro Carvalho Chehab 	dprintk(1, "\n");
65609a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
65619a0bf528SMauro Carvalho Chehab 	if (!state)
65629a0bf528SMauro Carvalho Chehab 		return NULL;
65639a0bf528SMauro Carvalho Chehab 
65649a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
65659a0bf528SMauro Carvalho Chehab 	state->demod_address = adr;
65669a0bf528SMauro Carvalho Chehab 	state->single_master = config->single_master;
65679a0bf528SMauro Carvalho Chehab 	state->microcode_name = config->microcode_name;
65689a0bf528SMauro Carvalho Chehab 	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
65699a0bf528SMauro Carvalho Chehab 	state->no_i2c_bridge = config->no_i2c_bridge;
65709a0bf528SMauro Carvalho Chehab 	state->antenna_gpio = config->antenna_gpio;
65719a0bf528SMauro Carvalho Chehab 	state->antenna_dvbt = config->antenna_dvbt;
65729a0bf528SMauro Carvalho Chehab 	state->m_ChunkSize = config->chunk_size;
65739a0bf528SMauro Carvalho Chehab 	state->enable_merr_cfg = config->enable_merr_cfg;
65749a0bf528SMauro Carvalho Chehab 
65759a0bf528SMauro Carvalho Chehab 	if (config->dynamic_clk) {
65769a0bf528SMauro Carvalho Chehab 		state->m_DVBTStaticCLK = 0;
65779a0bf528SMauro Carvalho Chehab 		state->m_DVBCStaticCLK = 0;
65789a0bf528SMauro Carvalho Chehab 	} else {
65799a0bf528SMauro Carvalho Chehab 		state->m_DVBTStaticCLK = 1;
65809a0bf528SMauro Carvalho Chehab 		state->m_DVBCStaticCLK = 1;
65819a0bf528SMauro Carvalho Chehab 	}
65829a0bf528SMauro Carvalho Chehab 
65839a0bf528SMauro Carvalho Chehab 
65849a0bf528SMauro Carvalho Chehab 	if (config->mpeg_out_clk_strength)
65859a0bf528SMauro Carvalho Chehab 		state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
65869a0bf528SMauro Carvalho Chehab 	else
65879a0bf528SMauro Carvalho Chehab 		state->m_TSClockkStrength = 0x06;
65889a0bf528SMauro Carvalho Chehab 
65899a0bf528SMauro Carvalho Chehab 	if (config->parallel_ts)
65909a0bf528SMauro Carvalho Chehab 		state->m_enableParallel = true;
65919a0bf528SMauro Carvalho Chehab 	else
65929a0bf528SMauro Carvalho Chehab 		state->m_enableParallel = false;
65939a0bf528SMauro Carvalho Chehab 
65949a0bf528SMauro Carvalho Chehab 	/* NOTE: as more UIO bits will be used, add them to the mask */
65959a0bf528SMauro Carvalho Chehab 	state->UIO_mask = config->antenna_gpio;
65969a0bf528SMauro Carvalho Chehab 
65979a0bf528SMauro Carvalho Chehab 	/* Default gpio to DVB-C */
65989a0bf528SMauro Carvalho Chehab 	if (!state->antenna_dvbt && state->antenna_gpio)
65999a0bf528SMauro Carvalho Chehab 		state->m_GPIO |= state->antenna_gpio;
66009a0bf528SMauro Carvalho Chehab 	else
66019a0bf528SMauro Carvalho Chehab 		state->m_GPIO &= ~state->antenna_gpio;
66029a0bf528SMauro Carvalho Chehab 
66039a0bf528SMauro Carvalho Chehab 	mutex_init(&state->mutex);
66049a0bf528SMauro Carvalho Chehab 
66059a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
66069a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
66079a0bf528SMauro Carvalho Chehab 
66089a0bf528SMauro Carvalho Chehab 	init_state(state);
66099a0bf528SMauro Carvalho Chehab 
66109a0bf528SMauro Carvalho Chehab 	/* Load firmware and initialize DRX-K */
66119a0bf528SMauro Carvalho Chehab 	if (state->microcode_name) {
66128e30783bSMauro Carvalho Chehab 		if (config->load_firmware_sync) {
66138e30783bSMauro Carvalho Chehab 			const struct firmware *fw = NULL;
66148e30783bSMauro Carvalho Chehab 
66158e30783bSMauro Carvalho Chehab 			status = request_firmware(&fw, state->microcode_name,
66168e30783bSMauro Carvalho Chehab 						  state->i2c->dev.parent);
66178e30783bSMauro Carvalho Chehab 			if (status < 0)
66188e30783bSMauro Carvalho Chehab 				fw = NULL;
66198e30783bSMauro Carvalho Chehab 			load_firmware_cb(fw, state);
66208e30783bSMauro Carvalho Chehab 		} else {
66219a0bf528SMauro Carvalho Chehab 			status = request_firmware_nowait(THIS_MODULE, 1,
66229a0bf528SMauro Carvalho Chehab 					      state->microcode_name,
66239a0bf528SMauro Carvalho Chehab 					      state->i2c->dev.parent,
66249a0bf528SMauro Carvalho Chehab 					      GFP_KERNEL,
66259a0bf528SMauro Carvalho Chehab 					      state, load_firmware_cb);
66269a0bf528SMauro Carvalho Chehab 			if (status < 0) {
66279a0bf528SMauro Carvalho Chehab 				printk(KERN_ERR
66289a0bf528SMauro Carvalho Chehab 				       "drxk: failed to request a firmware\n");
66299a0bf528SMauro Carvalho Chehab 				return NULL;
66309a0bf528SMauro Carvalho Chehab 			}
66318e30783bSMauro Carvalho Chehab 		}
66329a0bf528SMauro Carvalho Chehab 	} else if (init_drxk(state) < 0)
66339a0bf528SMauro Carvalho Chehab 		goto error;
66349a0bf528SMauro Carvalho Chehab 
66359a0bf528SMauro Carvalho Chehab 	printk(KERN_INFO "drxk: frontend initialized.\n");
66369a0bf528SMauro Carvalho Chehab 	return &state->frontend;
66379a0bf528SMauro Carvalho Chehab 
66389a0bf528SMauro Carvalho Chehab error:
66399a0bf528SMauro Carvalho Chehab 	printk(KERN_ERR "drxk: not found\n");
66409a0bf528SMauro Carvalho Chehab 	kfree(state);
66419a0bf528SMauro Carvalho Chehab 	return NULL;
66429a0bf528SMauro Carvalho Chehab }
66439a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach);
66449a0bf528SMauro Carvalho Chehab 
66459a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
66469a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
66479a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6648