19a0bf528SMauro Carvalho Chehab /* 29a0bf528SMauro Carvalho Chehab * drxk_hard: DRX-K DVB-C/T demodulator driver 39a0bf528SMauro Carvalho Chehab * 49a0bf528SMauro Carvalho Chehab * Copyright (C) 2010-2011 Digital Devices GmbH 59a0bf528SMauro Carvalho Chehab * 69a0bf528SMauro Carvalho Chehab * This program is free software; you can redistribute it and/or 79a0bf528SMauro Carvalho Chehab * modify it under the terms of the GNU General Public License 89a0bf528SMauro Carvalho Chehab * version 2 only, as published by the Free Software Foundation. 99a0bf528SMauro Carvalho Chehab * 109a0bf528SMauro Carvalho Chehab * 119a0bf528SMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 129a0bf528SMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 139a0bf528SMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 149a0bf528SMauro Carvalho Chehab * GNU General Public License for more details. 159a0bf528SMauro Carvalho Chehab * 169a0bf528SMauro Carvalho Chehab * 179a0bf528SMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 189a0bf528SMauro Carvalho Chehab * along with this program; if not, write to the Free Software 199a0bf528SMauro Carvalho Chehab * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 209a0bf528SMauro Carvalho Chehab * 02110-1301, USA 219a0bf528SMauro Carvalho Chehab * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 229a0bf528SMauro Carvalho Chehab */ 239a0bf528SMauro Carvalho Chehab 243a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 253a4398f5SMauro Carvalho Chehab 269a0bf528SMauro Carvalho Chehab #include <linux/kernel.h> 279a0bf528SMauro Carvalho Chehab #include <linux/module.h> 289a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h> 299a0bf528SMauro Carvalho Chehab #include <linux/init.h> 309a0bf528SMauro Carvalho Chehab #include <linux/delay.h> 319a0bf528SMauro Carvalho Chehab #include <linux/firmware.h> 329a0bf528SMauro Carvalho Chehab #include <linux/i2c.h> 339a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h> 349a0bf528SMauro Carvalho Chehab #include <asm/div64.h> 359a0bf528SMauro Carvalho Chehab 369a0bf528SMauro Carvalho Chehab #include "dvb_frontend.h" 379a0bf528SMauro Carvalho Chehab #include "drxk.h" 389a0bf528SMauro Carvalho Chehab #include "drxk_hard.h" 39b5e9eb6fSMauro Carvalho Chehab #include "dvb_math.h" 409a0bf528SMauro Carvalho Chehab 41cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode); 42cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state); 43cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 44cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 45cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state, 46cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 47cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 48cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset); 49cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 50cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 51cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state); 52cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 53cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset); 54cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status); 55cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status); 56cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state); 57cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state); 589a0bf528SMauro Carvalho Chehab 59cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state) 609a0bf528SMauro Carvalho Chehab { 61cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_DVBT; 629a0bf528SMauro Carvalho Chehab } 639a0bf528SMauro Carvalho Chehab 64cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state) 659a0bf528SMauro Carvalho Chehab { 66cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_QAM_ITU_A || 67cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_B || 68cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_C; 699a0bf528SMauro Carvalho Chehab } 709a0bf528SMauro Carvalho Chehab 719a0bf528SMauro Carvalho Chehab #define NOA1ROM 0 729a0bf528SMauro Carvalho Chehab 739a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0) 749a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0) 759a0bf528SMauro Carvalho Chehab 769a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83 165 779a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93 250 789a0bf528SMauro Carvalho Chehab 799a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 809a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02) 819a0bf528SMauro Carvalho Chehab #endif 829a0bf528SMauro Carvalho Chehab 839a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 849a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) 859a0bf528SMauro Carvalho Chehab #endif 869a0bf528SMauro Carvalho Chehab 879a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 889a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 899a0bf528SMauro Carvalho Chehab 909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV 919a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV 4 929a0bf528SMauro Carvalho Chehab #endif 939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV 949a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV 6 959a0bf528SMauro Carvalho Chehab #endif 969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV 979a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV 7 989a0bf528SMauro Carvalho Chehab #endif 999a0bf528SMauro Carvalho Chehab 1009a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM 1019a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM 3 1029a0bf528SMauro Carvalho Chehab #endif 1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM 1049a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM 4 1059a0bf528SMauro Carvalho Chehab #endif 1069a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM 1079a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM 7 1089a0bf528SMauro Carvalho Chehab #endif 1099a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT 1109a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2) 1119a0bf528SMauro Carvalho Chehab #endif 1129a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT 1139a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2) 1149a0bf528SMauro Carvalho Chehab #endif 1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT 1169a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7) 1179a0bf528SMauro Carvalho Chehab #endif 1189a0bf528SMauro Carvalho Chehab 1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET 1209a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800) 1219a0bf528SMauro Carvalho Chehab #endif 1229a0bf528SMauro Carvalho Chehab 1239a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ 1249a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L) 1259a0bf528SMauro Carvalho Chehab #endif 1269a0bf528SMauro Carvalho Chehab 1279a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ 1289a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L) 1299a0bf528SMauro Carvalho Chehab #endif 1309a0bf528SMauro Carvalho Chehab 1319a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ 1329a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L) 1339a0bf528SMauro Carvalho Chehab #endif 1349a0bf528SMauro Carvalho Chehab 1359a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX 1369a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX (7233000) 1379a0bf528SMauro Carvalho Chehab #endif 1389a0bf528SMauro Carvalho Chehab 1399a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56 1409a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64 1419a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0 1429a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG 24 1439a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32 1449a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40 1459a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM 48 1469a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE 0 1479a0bf528SMauro Carvalho Chehab 1489a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT 100 1499a0bf528SMauro Carvalho Chehab 1509a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS 2 1519a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE 6 1529a0bf528SMauro Carvalho Chehab 1539a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS 28 1549a0bf528SMauro Carvalho Chehab 1559a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH 1569a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH (4) 1579a0bf528SMauro Carvalho Chehab #endif 1589a0bf528SMauro Carvalho Chehab 1599a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16 (40960) 1609a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32 (20480) 1619a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64 (43008) 1629a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128 (20992) 1639a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256 (43520) 1649a0bf528SMauro Carvalho Chehab 1659a0bf528SMauro Carvalho Chehab static unsigned int debug; 1669a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644); 1679a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages"); 1689a0bf528SMauro Carvalho Chehab 1699a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do { \ 1709a0bf528SMauro Carvalho Chehab if (debug >= level) \ 17152ee29feSMauro Carvalho Chehab printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ 1729a0bf528SMauro Carvalho Chehab } while (0) 1739a0bf528SMauro Carvalho Chehab 1749a0bf528SMauro Carvalho Chehab 1759a0bf528SMauro Carvalho Chehab static inline u32 MulDiv32(u32 a, u32 b, u32 c) 1769a0bf528SMauro Carvalho Chehab { 1779a0bf528SMauro Carvalho Chehab u64 tmp64; 1789a0bf528SMauro Carvalho Chehab 1799a0bf528SMauro Carvalho Chehab tmp64 = (u64) a * (u64) b; 1809a0bf528SMauro Carvalho Chehab do_div(tmp64, c); 1819a0bf528SMauro Carvalho Chehab 1829a0bf528SMauro Carvalho Chehab return (u32) tmp64; 1839a0bf528SMauro Carvalho Chehab } 1849a0bf528SMauro Carvalho Chehab 185ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c) 1869a0bf528SMauro Carvalho Chehab { 1879a0bf528SMauro Carvalho Chehab int i = 0; 1889a0bf528SMauro Carvalho Chehab u32 Q1 = 0; 1899a0bf528SMauro Carvalho Chehab u32 R0 = 0; 1909a0bf528SMauro Carvalho Chehab 1919a0bf528SMauro Carvalho Chehab R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ 192ab5060cdSMauro Carvalho Chehab Q1 = a / c; /* 193ab5060cdSMauro Carvalho Chehab * integer part, only the 4 least significant 194ab5060cdSMauro Carvalho Chehab * bits will be visible in the result 195ab5060cdSMauro Carvalho Chehab */ 1969a0bf528SMauro Carvalho Chehab 1979a0bf528SMauro Carvalho Chehab /* division using radix 16, 7 nibbles in the result */ 1989a0bf528SMauro Carvalho Chehab for (i = 0; i < 7; i++) { 1999a0bf528SMauro Carvalho Chehab Q1 = (Q1 << 4) | (R0 / c); 2009a0bf528SMauro Carvalho Chehab R0 = (R0 % c) << 4; 2019a0bf528SMauro Carvalho Chehab } 2029a0bf528SMauro Carvalho Chehab /* rounding */ 2039a0bf528SMauro Carvalho Chehab if ((R0 >> 3) >= c) 2049a0bf528SMauro Carvalho Chehab Q1++; 2059a0bf528SMauro Carvalho Chehab 2069a0bf528SMauro Carvalho Chehab return Q1; 2079a0bf528SMauro Carvalho Chehab } 2089a0bf528SMauro Carvalho Chehab 209b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value) 2109a0bf528SMauro Carvalho Chehab { 211b5e9eb6fSMauro Carvalho Chehab return (100L * intlog10(value)) >> 24; 2129a0bf528SMauro Carvalho Chehab } 2139a0bf528SMauro Carvalho Chehab 2149a0bf528SMauro Carvalho Chehab /****************************************************************************/ 2159a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/ 2169a0bf528SMauro Carvalho Chehab /****************************************************************************/ 2179a0bf528SMauro Carvalho Chehab 2189a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state) 2199a0bf528SMauro Carvalho Chehab { 2209a0bf528SMauro Carvalho Chehab i2c_lock_adapter(state->i2c); 2219a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = true; 2229a0bf528SMauro Carvalho Chehab 2239a0bf528SMauro Carvalho Chehab return 0; 2249a0bf528SMauro Carvalho Chehab } 2259a0bf528SMauro Carvalho Chehab 2269a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state) 2279a0bf528SMauro Carvalho Chehab { 2289a0bf528SMauro Carvalho Chehab if (!state->drxk_i2c_exclusive_lock) 2299a0bf528SMauro Carvalho Chehab return; 2309a0bf528SMauro Carvalho Chehab 2319a0bf528SMauro Carvalho Chehab i2c_unlock_adapter(state->i2c); 2329a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = false; 2339a0bf528SMauro Carvalho Chehab } 2349a0bf528SMauro Carvalho Chehab 2359a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, 2369a0bf528SMauro Carvalho Chehab unsigned len) 2379a0bf528SMauro Carvalho Chehab { 2389a0bf528SMauro Carvalho Chehab if (state->drxk_i2c_exclusive_lock) 2399a0bf528SMauro Carvalho Chehab return __i2c_transfer(state->i2c, msgs, len); 2409a0bf528SMauro Carvalho Chehab else 2419a0bf528SMauro Carvalho Chehab return i2c_transfer(state->i2c, msgs, len); 2429a0bf528SMauro Carvalho Chehab } 2439a0bf528SMauro Carvalho Chehab 2449a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) 2459a0bf528SMauro Carvalho Chehab { 2469a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, 2479a0bf528SMauro Carvalho Chehab .buf = val, .len = 1} 2489a0bf528SMauro Carvalho Chehab }; 2499a0bf528SMauro Carvalho Chehab 2509a0bf528SMauro Carvalho Chehab return drxk_i2c_transfer(state, msgs, 1); 2519a0bf528SMauro Carvalho Chehab } 2529a0bf528SMauro Carvalho Chehab 2539a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) 2549a0bf528SMauro Carvalho Chehab { 2559a0bf528SMauro Carvalho Chehab int status; 2569a0bf528SMauro Carvalho Chehab struct i2c_msg msg = { 2579a0bf528SMauro Carvalho Chehab .addr = adr, .flags = 0, .buf = data, .len = len }; 2589a0bf528SMauro Carvalho Chehab 2599a0bf528SMauro Carvalho Chehab dprintk(3, ":"); 2609a0bf528SMauro Carvalho Chehab if (debug > 2) { 2619a0bf528SMauro Carvalho Chehab int i; 2629a0bf528SMauro Carvalho Chehab for (i = 0; i < len; i++) 2630fb220f2SMauro Carvalho Chehab pr_cont(" %02x", data[i]); 2640fb220f2SMauro Carvalho Chehab pr_cont("\n"); 2659a0bf528SMauro Carvalho Chehab } 2669a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, &msg, 1); 2679a0bf528SMauro Carvalho Chehab if (status >= 0 && status != 1) 2689a0bf528SMauro Carvalho Chehab status = -EIO; 2699a0bf528SMauro Carvalho Chehab 2709a0bf528SMauro Carvalho Chehab if (status < 0) 2713a4398f5SMauro Carvalho Chehab pr_err("i2c write error at addr 0x%02x\n", adr); 2729a0bf528SMauro Carvalho Chehab 2739a0bf528SMauro Carvalho Chehab return status; 2749a0bf528SMauro Carvalho Chehab } 2759a0bf528SMauro Carvalho Chehab 2769a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state, 2779a0bf528SMauro Carvalho Chehab u8 adr, u8 *msg, int len, u8 *answ, int alen) 2789a0bf528SMauro Carvalho Chehab { 2799a0bf528SMauro Carvalho Chehab int status; 2809a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[2] = { 2819a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = 0, 2829a0bf528SMauro Carvalho Chehab .buf = msg, .len = len}, 2839a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = I2C_M_RD, 2849a0bf528SMauro Carvalho Chehab .buf = answ, .len = alen} 2859a0bf528SMauro Carvalho Chehab }; 2869a0bf528SMauro Carvalho Chehab 2879a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, msgs, 2); 2889a0bf528SMauro Carvalho Chehab if (status != 2) { 2899a0bf528SMauro Carvalho Chehab if (debug > 2) 2900fb220f2SMauro Carvalho Chehab pr_cont(": ERROR!\n"); 2919a0bf528SMauro Carvalho Chehab if (status >= 0) 2929a0bf528SMauro Carvalho Chehab status = -EIO; 2939a0bf528SMauro Carvalho Chehab 2943a4398f5SMauro Carvalho Chehab pr_err("i2c read error at addr 0x%02x\n", adr); 2959a0bf528SMauro Carvalho Chehab return status; 2969a0bf528SMauro Carvalho Chehab } 2979a0bf528SMauro Carvalho Chehab if (debug > 2) { 2989a0bf528SMauro Carvalho Chehab int i; 2999a0bf528SMauro Carvalho Chehab dprintk(2, ": read from"); 3009a0bf528SMauro Carvalho Chehab for (i = 0; i < len; i++) 3010fb220f2SMauro Carvalho Chehab pr_cont(" %02x", msg[i]); 3020fb220f2SMauro Carvalho Chehab pr_cont(", value = "); 3039a0bf528SMauro Carvalho Chehab for (i = 0; i < alen; i++) 3040fb220f2SMauro Carvalho Chehab pr_cont(" %02x", answ[i]); 3050fb220f2SMauro Carvalho Chehab pr_cont("\n"); 3069a0bf528SMauro Carvalho Chehab } 3079a0bf528SMauro Carvalho Chehab return 0; 3089a0bf528SMauro Carvalho Chehab } 3099a0bf528SMauro Carvalho Chehab 3109a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) 3119a0bf528SMauro Carvalho Chehab { 3129a0bf528SMauro Carvalho Chehab int status; 3139a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[2], len; 3149a0bf528SMauro Carvalho Chehab 3159a0bf528SMauro Carvalho Chehab if (state->single_master) 3169a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3179a0bf528SMauro Carvalho Chehab 3189a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3199a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01); 3209a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF); 3219a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags; 3229a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF); 3239a0bf528SMauro Carvalho Chehab len = 4; 3249a0bf528SMauro Carvalho Chehab } else { 3259a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF); 3269a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3279a0bf528SMauro Carvalho Chehab len = 2; 3289a0bf528SMauro Carvalho Chehab } 3299a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3309a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 2); 3319a0bf528SMauro Carvalho Chehab if (status < 0) 3329a0bf528SMauro Carvalho Chehab return status; 3339a0bf528SMauro Carvalho Chehab if (data) 3349a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8); 3359a0bf528SMauro Carvalho Chehab 3369a0bf528SMauro Carvalho Chehab return 0; 3379a0bf528SMauro Carvalho Chehab } 3389a0bf528SMauro Carvalho Chehab 3399a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data) 3409a0bf528SMauro Carvalho Chehab { 3419a0bf528SMauro Carvalho Chehab return read16_flags(state, reg, data, 0); 3429a0bf528SMauro Carvalho Chehab } 3439a0bf528SMauro Carvalho Chehab 3449a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) 3459a0bf528SMauro Carvalho Chehab { 3469a0bf528SMauro Carvalho Chehab int status; 3479a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[4], len; 3489a0bf528SMauro Carvalho Chehab 3499a0bf528SMauro Carvalho Chehab if (state->single_master) 3509a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3519a0bf528SMauro Carvalho Chehab 3529a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3539a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01); 3549a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF); 3559a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags; 3569a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF); 3579a0bf528SMauro Carvalho Chehab len = 4; 3589a0bf528SMauro Carvalho Chehab } else { 3599a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF); 3609a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3619a0bf528SMauro Carvalho Chehab len = 2; 3629a0bf528SMauro Carvalho Chehab } 3639a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3649a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 4); 3659a0bf528SMauro Carvalho Chehab if (status < 0) 3669a0bf528SMauro Carvalho Chehab return status; 3679a0bf528SMauro Carvalho Chehab if (data) 3689a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8) | 3699a0bf528SMauro Carvalho Chehab (mm2[2] << 16) | (mm2[3] << 24); 3709a0bf528SMauro Carvalho Chehab 3719a0bf528SMauro Carvalho Chehab return 0; 3729a0bf528SMauro Carvalho Chehab } 3739a0bf528SMauro Carvalho Chehab 3749a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data) 3759a0bf528SMauro Carvalho Chehab { 3769a0bf528SMauro Carvalho Chehab return read32_flags(state, reg, data, 0); 3779a0bf528SMauro Carvalho Chehab } 3789a0bf528SMauro Carvalho Chehab 3799a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) 3809a0bf528SMauro Carvalho Chehab { 3819a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[6], len; 3829a0bf528SMauro Carvalho Chehab 3839a0bf528SMauro Carvalho Chehab if (state->single_master) 3849a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3859a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3869a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01); 3879a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF); 3889a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags; 3899a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF); 3909a0bf528SMauro Carvalho Chehab len = 4; 3919a0bf528SMauro Carvalho Chehab } else { 3929a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF); 3939a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3949a0bf528SMauro Carvalho Chehab len = 2; 3959a0bf528SMauro Carvalho Chehab } 3969a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff; 3979a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff; 3989a0bf528SMauro Carvalho Chehab 3999a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); 4009a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 2); 4019a0bf528SMauro Carvalho Chehab } 4029a0bf528SMauro Carvalho Chehab 4039a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data) 4049a0bf528SMauro Carvalho Chehab { 4059a0bf528SMauro Carvalho Chehab return write16_flags(state, reg, data, 0); 4069a0bf528SMauro Carvalho Chehab } 4079a0bf528SMauro Carvalho Chehab 4089a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) 4099a0bf528SMauro Carvalho Chehab { 4109a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[8], len; 4119a0bf528SMauro Carvalho Chehab 4129a0bf528SMauro Carvalho Chehab if (state->single_master) 4139a0bf528SMauro Carvalho Chehab flags |= 0xC0; 4149a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 4159a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01); 4169a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF); 4179a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags; 4189a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF); 4199a0bf528SMauro Carvalho Chehab len = 4; 4209a0bf528SMauro Carvalho Chehab } else { 4219a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF); 4229a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 4239a0bf528SMauro Carvalho Chehab len = 2; 4249a0bf528SMauro Carvalho Chehab } 4259a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff; 4269a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff; 4279a0bf528SMauro Carvalho Chehab mm[len + 2] = (data >> 16) & 0xff; 4289a0bf528SMauro Carvalho Chehab mm[len + 3] = (data >> 24) & 0xff; 4299a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); 4309a0bf528SMauro Carvalho Chehab 4319a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 4); 4329a0bf528SMauro Carvalho Chehab } 4339a0bf528SMauro Carvalho Chehab 4349a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data) 4359a0bf528SMauro Carvalho Chehab { 4369a0bf528SMauro Carvalho Chehab return write32_flags(state, reg, data, 0); 4379a0bf528SMauro Carvalho Chehab } 4389a0bf528SMauro Carvalho Chehab 439cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address, 440cd7a67a4SMauro Carvalho Chehab const int block_size, const u8 p_block[]) 4419a0bf528SMauro Carvalho Chehab { 442cd7a67a4SMauro Carvalho Chehab int status = 0, blk_size = block_size; 443cd7a67a4SMauro Carvalho Chehab u8 flags = 0; 4449a0bf528SMauro Carvalho Chehab 4459a0bf528SMauro Carvalho Chehab if (state->single_master) 446cd7a67a4SMauro Carvalho Chehab flags |= 0xC0; 4479a0bf528SMauro Carvalho Chehab 448cd7a67a4SMauro Carvalho Chehab while (blk_size > 0) { 449cd7a67a4SMauro Carvalho Chehab int chunk = blk_size > state->m_chunk_size ? 450cd7a67a4SMauro Carvalho Chehab state->m_chunk_size : blk_size; 451cd7a67a4SMauro Carvalho Chehab u8 *adr_buf = &state->chunk[0]; 452cd7a67a4SMauro Carvalho Chehab u32 adr_length = 0; 4539a0bf528SMauro Carvalho Chehab 454cd7a67a4SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) { 455cd7a67a4SMauro Carvalho Chehab adr_buf[0] = (((address << 1) & 0xFF) | 0x01); 456cd7a67a4SMauro Carvalho Chehab adr_buf[1] = ((address >> 16) & 0xFF); 457cd7a67a4SMauro Carvalho Chehab adr_buf[2] = ((address >> 24) & 0xFF); 458cd7a67a4SMauro Carvalho Chehab adr_buf[3] = ((address >> 7) & 0xFF); 459cd7a67a4SMauro Carvalho Chehab adr_buf[2] |= flags; 460cd7a67a4SMauro Carvalho Chehab adr_length = 4; 461cd7a67a4SMauro Carvalho Chehab if (chunk == state->m_chunk_size) 462cd7a67a4SMauro Carvalho Chehab chunk -= 2; 4639a0bf528SMauro Carvalho Chehab } else { 464cd7a67a4SMauro Carvalho Chehab adr_buf[0] = ((address << 1) & 0xFF); 465cd7a67a4SMauro Carvalho Chehab adr_buf[1] = (((address >> 16) & 0x0F) | 466cd7a67a4SMauro Carvalho Chehab ((address >> 18) & 0xF0)); 467cd7a67a4SMauro Carvalho Chehab adr_length = 2; 4689a0bf528SMauro Carvalho Chehab } 469cd7a67a4SMauro Carvalho Chehab memcpy(&state->chunk[adr_length], p_block, chunk); 470cd7a67a4SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", address, flags); 4719a0bf528SMauro Carvalho Chehab if (debug > 1) { 4729a0bf528SMauro Carvalho Chehab int i; 473cd7a67a4SMauro Carvalho Chehab if (p_block) 474cd7a67a4SMauro Carvalho Chehab for (i = 0; i < chunk; i++) 4750fb220f2SMauro Carvalho Chehab pr_cont(" %02x", p_block[i]); 4760fb220f2SMauro Carvalho Chehab pr_cont("\n"); 4779a0bf528SMauro Carvalho Chehab } 4789a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address, 479cd7a67a4SMauro Carvalho Chehab &state->chunk[0], chunk + adr_length); 4809a0bf528SMauro Carvalho Chehab if (status < 0) { 4813a4398f5SMauro Carvalho Chehab pr_err("%s: i2c write error at addr 0x%02x\n", 482cd7a67a4SMauro Carvalho Chehab __func__, address); 4839a0bf528SMauro Carvalho Chehab break; 4849a0bf528SMauro Carvalho Chehab } 485cd7a67a4SMauro Carvalho Chehab p_block += chunk; 486cd7a67a4SMauro Carvalho Chehab address += (chunk >> 1); 487cd7a67a4SMauro Carvalho Chehab blk_size -= chunk; 4889a0bf528SMauro Carvalho Chehab } 4899a0bf528SMauro Carvalho Chehab return status; 4909a0bf528SMauro Carvalho Chehab } 4919a0bf528SMauro Carvalho Chehab 4929a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP 4939a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20 4949a0bf528SMauro Carvalho Chehab #endif 4959a0bf528SMauro Carvalho Chehab 496cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state) 4979a0bf528SMauro Carvalho Chehab { 4989a0bf528SMauro Carvalho Chehab int status; 4999a0bf528SMauro Carvalho Chehab u8 data = 0; 500cd7a67a4SMauro Carvalho Chehab u16 retry_count = 0; 5019a0bf528SMauro Carvalho Chehab 5029a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5039a0bf528SMauro Carvalho Chehab 5049a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address, &data); 5059a0bf528SMauro Carvalho Chehab if (status < 0) { 5069a0bf528SMauro Carvalho Chehab do { 5079a0bf528SMauro Carvalho Chehab data = 0; 5089a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address, 5099a0bf528SMauro Carvalho Chehab &data, 1); 510b72852baSMauro Carvalho Chehab usleep_range(10000, 11000); 511cd7a67a4SMauro Carvalho Chehab retry_count++; 5129a0bf528SMauro Carvalho Chehab if (status < 0) 5139a0bf528SMauro Carvalho Chehab continue; 5149a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address, 5159a0bf528SMauro Carvalho Chehab &data); 5169a0bf528SMauro Carvalho Chehab } while (status < 0 && 517cd7a67a4SMauro Carvalho Chehab (retry_count < DRXK_MAX_RETRIES_POWERUP)); 518cd7a67a4SMauro Carvalho Chehab if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP) 5199a0bf528SMauro Carvalho Chehab goto error; 5209a0bf528SMauro Carvalho Chehab } 5219a0bf528SMauro Carvalho Chehab 5229a0bf528SMauro Carvalho Chehab /* Make sure all clk domains are active */ 5239a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE); 5249a0bf528SMauro Carvalho Chehab if (status < 0) 5259a0bf528SMauro Carvalho Chehab goto error; 5269a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 5279a0bf528SMauro Carvalho Chehab if (status < 0) 5289a0bf528SMauro Carvalho Chehab goto error; 5299a0bf528SMauro Carvalho Chehab /* Enable pll lock tests */ 5309a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PLL_LOCK__A, 1); 5319a0bf528SMauro Carvalho Chehab if (status < 0) 5329a0bf528SMauro Carvalho Chehab goto error; 5339a0bf528SMauro Carvalho Chehab 534cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_UP; 5359a0bf528SMauro Carvalho Chehab 5369a0bf528SMauro Carvalho Chehab error: 5379a0bf528SMauro Carvalho Chehab if (status < 0) 5383a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 5399a0bf528SMauro Carvalho Chehab 5409a0bf528SMauro Carvalho Chehab return status; 5419a0bf528SMauro Carvalho Chehab } 5429a0bf528SMauro Carvalho Chehab 5439a0bf528SMauro Carvalho Chehab 5449a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state) 5459a0bf528SMauro Carvalho Chehab { 5469a0bf528SMauro Carvalho Chehab /* 5479a0bf528SMauro Carvalho Chehab * FIXME: most (all?) of the values bellow should be moved into 5489a0bf528SMauro Carvalho Chehab * struct drxk_config, as they are probably board-specific 5499a0bf528SMauro Carvalho Chehab */ 550cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; 551cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_output_level = 0; 552cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_min_level = 0; 553cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_max_level = 0x7FFF; 554cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_speed = 3; 5559a0bf528SMauro Carvalho Chehab 556cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO; 557cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_output_level = 0; 558cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_min_level = 0; 559cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_max_level = 0x7FFF; 560cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_speed = 3; 561cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_top = 9500; 562cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_cut_off_current = 4000; 5639a0bf528SMauro Carvalho Chehab 564cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO; 565cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_output_level = 0; 566cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_min_level = 0; 567cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_max_level = 0; 568cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_speed = 3; 5699a0bf528SMauro Carvalho Chehab 570cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF; 571cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_output_level = 0; 572cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_min_level = 0; 573cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_max_level = 0; 574cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_top = 9500; 575cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_cut_off_current = 4000; 576cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_speed = 3; 5779a0bf528SMauro Carvalho Chehab 5789a0bf528SMauro Carvalho Chehab u32 ulQual83 = DEFAULT_MER_83; 5799a0bf528SMauro Carvalho Chehab u32 ulQual93 = DEFAULT_MER_93; 5809a0bf528SMauro Carvalho Chehab 581cd7a67a4SMauro Carvalho Chehab u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 582cd7a67a4SMauro Carvalho Chehab u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 5839a0bf528SMauro Carvalho Chehab 5849a0bf528SMauro Carvalho Chehab /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ 5859a0bf528SMauro Carvalho Chehab /* io_pad_cfg_mode output mode is drive always */ 5869a0bf528SMauro Carvalho Chehab /* io_pad_cfg_drive is set to power 2 (23 mA) */ 587cd7a67a4SMauro Carvalho Chehab u32 ul_gpio_cfg = 0x0113; 588cd7a67a4SMauro Carvalho Chehab u32 ul_invert_ts_clock = 0; 589cd7a67a4SMauro Carvalho Chehab u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; 590cd7a67a4SMauro Carvalho Chehab u32 ul_dvbt_bitrate = 50000000; 591cd7a67a4SMauro Carvalho Chehab u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; 5929a0bf528SMauro Carvalho Chehab 593cd7a67a4SMauro Carvalho Chehab u32 ul_insert_rs_byte = 0; 5949a0bf528SMauro Carvalho Chehab 595cd7a67a4SMauro Carvalho Chehab u32 ul_rf_mirror = 1; 596cd7a67a4SMauro Carvalho Chehab u32 ul_power_down = 0; 5979a0bf528SMauro Carvalho Chehab 5989a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5999a0bf528SMauro Carvalho Chehab 600cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 601cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = false; 602cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 603cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false; 604cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 605cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 6069a0bf528SMauro Carvalho Chehab 607cd7a67a4SMauro Carvalho Chehab if (!state->m_chunk_size) 608cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = 124; 6099a0bf528SMauro Carvalho Chehab 610cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 0; 611cd7a67a4SMauro Carvalho Chehab state->m_smart_ant_inverted = false; 612cd7a67a4SMauro Carvalho Chehab state->m_b_p_down_open_bridge = false; 6139a0bf528SMauro Carvalho Chehab 6149a0bf528SMauro Carvalho Chehab /* real system clock frequency in kHz */ 615cd7a67a4SMauro Carvalho Chehab state->m_sys_clock_freq = 151875; 6169a0bf528SMauro Carvalho Chehab /* Timing div, 250ns/Psys */ 6179a0bf528SMauro Carvalho Chehab /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ 618cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) * 6199a0bf528SMauro Carvalho Chehab HI_I2C_DELAY) / 1000; 6209a0bf528SMauro Carvalho Chehab /* Clipping */ 621cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) 622cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; 623cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 6249a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */ 625cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 6269a0bf528SMauro Carvalho Chehab 627cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = (ul_power_down != 0); 6289a0bf528SMauro Carvalho Chehab 629cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = false; 6309a0bf528SMauro Carvalho Chehab 6319a0bf528SMauro Carvalho Chehab /* Init AGC and PGA parameters */ 6329a0bf528SMauro Carvalho Chehab /* VSB IF */ 633949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode; 634949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level; 635949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level; 636949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level; 637949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed; 638cd7a67a4SMauro Carvalho Chehab state->m_vsb_pga_cfg = 140; 6399a0bf528SMauro Carvalho Chehab 6409a0bf528SMauro Carvalho Chehab /* VSB RF */ 641949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode; 642949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level; 643949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level; 644949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level; 645949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed; 646949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top; 647949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current; 648cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.reference = 0x07; 649cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.use_pre_saw = true; 6509a0bf528SMauro Carvalho Chehab 6519a0bf528SMauro Carvalho Chehab state->m_Quality83percent = DEFAULT_MER_83; 6529a0bf528SMauro Carvalho Chehab state->m_Quality93percent = DEFAULT_MER_93; 6539a0bf528SMauro Carvalho Chehab if (ulQual93 <= 500 && ulQual83 < ulQual93) { 6549a0bf528SMauro Carvalho Chehab state->m_Quality83percent = ulQual83; 6559a0bf528SMauro Carvalho Chehab state->m_Quality93percent = ulQual93; 6569a0bf528SMauro Carvalho Chehab } 6579a0bf528SMauro Carvalho Chehab 6589a0bf528SMauro Carvalho Chehab /* ATV IF */ 659949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode; 660949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level; 661949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level; 662949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level; 663949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed; 6649a0bf528SMauro Carvalho Chehab 6659a0bf528SMauro Carvalho Chehab /* ATV RF */ 666949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode; 667949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level; 668949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level; 669949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level; 670949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed; 671949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top; 672949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current; 673cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.reference = 0x04; 674cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.use_pre_saw = true; 6759a0bf528SMauro Carvalho Chehab 6769a0bf528SMauro Carvalho Chehab 6779a0bf528SMauro Carvalho Chehab /* DVBT RF */ 678cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 679cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.output_level = 0; 680cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.min_output_level = 0; 681cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF; 682cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.top = 0x2100; 683cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.cut_off_current = 4000; 684cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.speed = 1; 6859a0bf528SMauro Carvalho Chehab 6869a0bf528SMauro Carvalho Chehab 6879a0bf528SMauro Carvalho Chehab /* DVBT IF */ 688cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 689cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.output_level = 0; 690cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.min_output_level = 0; 691cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.max_output_level = 9000; 692cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.top = 13424; 693cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.cut_off_current = 0; 694cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.speed = 3; 695cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30; 696cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000; 6979a0bf528SMauro Carvalho Chehab /* state->m_dvbtPgaCfg = 140; */ 6989a0bf528SMauro Carvalho Chehab 699cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.reference = 4; 700cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.use_pre_saw = false; 7019a0bf528SMauro Carvalho Chehab 7029a0bf528SMauro Carvalho Chehab /* QAM RF */ 703cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 704cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.output_level = 0; 705cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.min_output_level = 6023; 706cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.max_output_level = 27000; 707cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.top = 0x2380; 708cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.cut_off_current = 4000; 709cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.speed = 3; 7109a0bf528SMauro Carvalho Chehab 7119a0bf528SMauro Carvalho Chehab /* QAM IF */ 712cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 713cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.output_level = 0; 714cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.min_output_level = 0; 715cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.max_output_level = 9000; 716cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.top = 0x0511; 717cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.cut_off_current = 0; 718cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.speed = 3; 719cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ingain_tgt_max = 5119; 720cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50; 7219a0bf528SMauro Carvalho Chehab 722cd7a67a4SMauro Carvalho Chehab state->m_qam_pga_cfg = 140; 723cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.reference = 4; 724cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.use_pre_saw = false; 7259a0bf528SMauro Carvalho Chehab 726cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 727cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_UNINITIALIZED; 7289a0bf528SMauro Carvalho Chehab 7299a0bf528SMauro Carvalho Chehab /* MPEG output configuration */ 730cd7a67a4SMauro Carvalho Chehab state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */ 731cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */ 732cd7a67a4SMauro Carvalho Chehab state->m_invert_data = false; /* If TRUE; invert DATA signals */ 733cd7a67a4SMauro Carvalho Chehab state->m_invert_err = false; /* If TRUE; invert ERR signal */ 734cd7a67a4SMauro Carvalho Chehab state->m_invert_str = false; /* If TRUE; invert STR signals */ 735cd7a67a4SMauro Carvalho Chehab state->m_invert_val = false; /* If TRUE; invert VAL signals */ 736cd7a67a4SMauro Carvalho Chehab state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */ 7379a0bf528SMauro Carvalho Chehab 7389a0bf528SMauro Carvalho Chehab /* If TRUE; static MPEG clockrate will be used; 7399a0bf528SMauro Carvalho Chehab otherwise clockrate will adapt to the bitrate of the TS */ 7409a0bf528SMauro Carvalho Chehab 741cd7a67a4SMauro Carvalho Chehab state->m_dvbt_bitrate = ul_dvbt_bitrate; 742cd7a67a4SMauro Carvalho Chehab state->m_dvbc_bitrate = ul_dvbc_bitrate; 7439a0bf528SMauro Carvalho Chehab 744cd7a67a4SMauro Carvalho Chehab state->m_ts_data_strength = (ul_ts_data_strength & 0x07); 7459a0bf528SMauro Carvalho Chehab 7469a0bf528SMauro Carvalho Chehab /* Maximum bitrate in b/s in case static clockrate is selected */ 747cd7a67a4SMauro Carvalho Chehab state->m_mpeg_ts_static_bitrate = 19392658; 748cd7a67a4SMauro Carvalho Chehab state->m_disable_te_ihandling = false; 7499a0bf528SMauro Carvalho Chehab 750cd7a67a4SMauro Carvalho Chehab if (ul_insert_rs_byte) 751cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = true; 7529a0bf528SMauro Carvalho Chehab 753cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 754cd7a67a4SMauro Carvalho Chehab if (ul_mpeg_lock_time_out < 10000) 755cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out; 756cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 757cd7a67a4SMauro Carvalho Chehab if (ul_demod_lock_time_out < 10000) 758cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = ul_demod_lock_time_out; 7599a0bf528SMauro Carvalho Chehab 7609a0bf528SMauro Carvalho Chehab /* QAM defaults */ 761cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_AUTO; 762cd7a67a4SMauro Carvalho Chehab state->m_qam_interleave_mode = DRXK_QAM_I12_J17; 763cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */ 764cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_prescale = 1; 7659a0bf528SMauro Carvalho Chehab 766cd7a67a4SMauro Carvalho Chehab state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM; 767cd7a67a4SMauro Carvalho Chehab state->m_agcfast_clip_ctrl_delay = 0; 7689a0bf528SMauro Carvalho Chehab 769949dd08dSMauro Carvalho Chehab state->m_gpio_cfg = ul_gpio_cfg; 7709a0bf528SMauro Carvalho Chehab 771cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = false; 772cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_DOWN; 7739a0bf528SMauro Carvalho Chehab 774cd7a67a4SMauro Carvalho Chehab state->m_rfmirror = (ul_rf_mirror == 0); 775cd7a67a4SMauro Carvalho Chehab state->m_if_agc_pol = false; 7769a0bf528SMauro Carvalho Chehab return 0; 7779a0bf528SMauro Carvalho Chehab } 7789a0bf528SMauro Carvalho Chehab 779cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state) 7809a0bf528SMauro Carvalho Chehab { 7819a0bf528SMauro Carvalho Chehab int status = 0; 7829a0bf528SMauro Carvalho Chehab u32 jtag = 0; 7839a0bf528SMauro Carvalho Chehab u16 bid = 0; 7849a0bf528SMauro Carvalho Chehab u16 key = 0; 7859a0bf528SMauro Carvalho Chehab 7869a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 7879a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 788ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 789ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 7909a0bf528SMauro Carvalho Chehab if (status < 0) 7919a0bf528SMauro Carvalho Chehab goto error; 7929a0bf528SMauro Carvalho Chehab /* Check device id */ 7939a0bf528SMauro Carvalho Chehab status = read16(state, SIO_TOP_COMM_KEY__A, &key); 7949a0bf528SMauro Carvalho Chehab if (status < 0) 7959a0bf528SMauro Carvalho Chehab goto error; 7969a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 7979a0bf528SMauro Carvalho Chehab if (status < 0) 7989a0bf528SMauro Carvalho Chehab goto error; 7999a0bf528SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag); 8009a0bf528SMauro Carvalho Chehab if (status < 0) 8019a0bf528SMauro Carvalho Chehab goto error; 8029a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid); 8039a0bf528SMauro Carvalho Chehab if (status < 0) 8049a0bf528SMauro Carvalho Chehab goto error; 8059a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, key); 8069a0bf528SMauro Carvalho Chehab error: 8079a0bf528SMauro Carvalho Chehab if (status < 0) 8083a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 8099a0bf528SMauro Carvalho Chehab return status; 8109a0bf528SMauro Carvalho Chehab } 8119a0bf528SMauro Carvalho Chehab 812cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state) 8139a0bf528SMauro Carvalho Chehab { 814cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_ohw_cfg = 0; 815cd7a67a4SMauro Carvalho Chehab u32 sio_top_jtagid_lo = 0; 8169a0bf528SMauro Carvalho Chehab int status; 8179a0bf528SMauro Carvalho Chehab const char *spin = ""; 8189a0bf528SMauro Carvalho Chehab 8199a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 8209a0bf528SMauro Carvalho Chehab 8219a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 8229a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 823ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 824ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 8259a0bf528SMauro Carvalho Chehab if (status < 0) 8269a0bf528SMauro Carvalho Chehab goto error; 8278418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 8289a0bf528SMauro Carvalho Chehab if (status < 0) 8299a0bf528SMauro Carvalho Chehab goto error; 830cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg); 8319a0bf528SMauro Carvalho Chehab if (status < 0) 8329a0bf528SMauro Carvalho Chehab goto error; 8339a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 8349a0bf528SMauro Carvalho Chehab if (status < 0) 8359a0bf528SMauro Carvalho Chehab goto error; 8369a0bf528SMauro Carvalho Chehab 837cd7a67a4SMauro Carvalho Chehab switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { 8389a0bf528SMauro Carvalho Chehab case 0: 8399a0bf528SMauro Carvalho Chehab /* ignore (bypass ?) */ 8409a0bf528SMauro Carvalho Chehab break; 8419a0bf528SMauro Carvalho Chehab case 1: 8429a0bf528SMauro Carvalho Chehab /* 27 MHz */ 843cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 27000; 8449a0bf528SMauro Carvalho Chehab break; 8459a0bf528SMauro Carvalho Chehab case 2: 8469a0bf528SMauro Carvalho Chehab /* 20.25 MHz */ 847cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250; 8489a0bf528SMauro Carvalho Chehab break; 8499a0bf528SMauro Carvalho Chehab case 3: 8509a0bf528SMauro Carvalho Chehab /* 4 MHz */ 851cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250; 8529a0bf528SMauro Carvalho Chehab break; 8539a0bf528SMauro Carvalho Chehab default: 8543a4398f5SMauro Carvalho Chehab pr_err("Clock Frequency is unknown\n"); 8559a0bf528SMauro Carvalho Chehab return -EINVAL; 8569a0bf528SMauro Carvalho Chehab } 8579a0bf528SMauro Carvalho Chehab /* 8589a0bf528SMauro Carvalho Chehab Determine device capabilities 8599a0bf528SMauro Carvalho Chehab Based on pinning v14 8609a0bf528SMauro Carvalho Chehab */ 861cd7a67a4SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo); 8629a0bf528SMauro Carvalho Chehab if (status < 0) 8639a0bf528SMauro Carvalho Chehab goto error; 8649a0bf528SMauro Carvalho Chehab 8653a4398f5SMauro Carvalho Chehab pr_info("status = 0x%08x\n", sio_top_jtagid_lo); 8669a0bf528SMauro Carvalho Chehab 8679a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 868cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 29) & 0xF) { 8699a0bf528SMauro Carvalho Chehab case 0: 870cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A1; 8719a0bf528SMauro Carvalho Chehab spin = "A1"; 8729a0bf528SMauro Carvalho Chehab break; 8739a0bf528SMauro Carvalho Chehab case 2: 874cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A2; 8759a0bf528SMauro Carvalho Chehab spin = "A2"; 8769a0bf528SMauro Carvalho Chehab break; 8779a0bf528SMauro Carvalho Chehab case 3: 878cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A3; 8799a0bf528SMauro Carvalho Chehab spin = "A3"; 8809a0bf528SMauro Carvalho Chehab break; 8819a0bf528SMauro Carvalho Chehab default: 882cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_UNKNOWN; 8839a0bf528SMauro Carvalho Chehab status = -EINVAL; 8843a4398f5SMauro Carvalho Chehab pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF); 8859a0bf528SMauro Carvalho Chehab goto error2; 8869a0bf528SMauro Carvalho Chehab } 887cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 12) & 0xFF) { 8889a0bf528SMauro Carvalho Chehab case 0x13: 8899a0bf528SMauro Carvalho Chehab /* typeId = DRX3913K_TYPE_ID */ 890cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 891cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 892cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false; 893cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 894cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 895cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 896cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 897cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = false; 898cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = false; 899cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9009a0bf528SMauro Carvalho Chehab break; 9019a0bf528SMauro Carvalho Chehab case 0x15: 9029a0bf528SMauro Carvalho Chehab /* typeId = DRX3915K_TYPE_ID */ 903cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 904cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 905cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 906cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 907cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 908cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 909cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 910cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 911cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 912cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9139a0bf528SMauro Carvalho Chehab break; 9149a0bf528SMauro Carvalho Chehab case 0x16: 9159a0bf528SMauro Carvalho Chehab /* typeId = DRX3916K_TYPE_ID */ 916cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 917cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 918cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 919cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 920cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 921cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 922cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 923cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 924cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 925cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9269a0bf528SMauro Carvalho Chehab break; 9279a0bf528SMauro Carvalho Chehab case 0x18: 9289a0bf528SMauro Carvalho Chehab /* typeId = DRX3918K_TYPE_ID */ 929cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 930cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 931cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 932cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 933cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 934cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 935cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 936cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 937cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 938cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9399a0bf528SMauro Carvalho Chehab break; 9409a0bf528SMauro Carvalho Chehab case 0x21: 9419a0bf528SMauro Carvalho Chehab /* typeId = DRX3921K_TYPE_ID */ 942cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 943cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 944cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 945cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 946cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 947cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 948cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 949cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 950cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 951cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9529a0bf528SMauro Carvalho Chehab break; 9539a0bf528SMauro Carvalho Chehab case 0x23: 9549a0bf528SMauro Carvalho Chehab /* typeId = DRX3923K_TYPE_ID */ 955cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 956cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 957cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 958cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 959cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 960cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 961cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 962cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 963cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 964cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9659a0bf528SMauro Carvalho Chehab break; 9669a0bf528SMauro Carvalho Chehab case 0x25: 9679a0bf528SMauro Carvalho Chehab /* typeId = DRX3925K_TYPE_ID */ 968cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 969cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 970cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 971cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 972cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 973cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 974cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 975cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 976cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 977cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9789a0bf528SMauro Carvalho Chehab break; 9799a0bf528SMauro Carvalho Chehab case 0x26: 9809a0bf528SMauro Carvalho Chehab /* typeId = DRX3926K_TYPE_ID */ 981cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 982cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 983cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 984cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 985cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 986cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 987cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 988cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 989cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 990cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9919a0bf528SMauro Carvalho Chehab break; 9929a0bf528SMauro Carvalho Chehab default: 9933a4398f5SMauro Carvalho Chehab pr_err("DeviceID 0x%02x not supported\n", 994cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF)); 9959a0bf528SMauro Carvalho Chehab status = -EINVAL; 9969a0bf528SMauro Carvalho Chehab goto error2; 9979a0bf528SMauro Carvalho Chehab } 9989a0bf528SMauro Carvalho Chehab 9993a4398f5SMauro Carvalho Chehab pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", 1000cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF), spin, 1001cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq / 1000, 1002cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq % 1000); 10039a0bf528SMauro Carvalho Chehab 10049a0bf528SMauro Carvalho Chehab error: 10059a0bf528SMauro Carvalho Chehab if (status < 0) 10063a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 10079a0bf528SMauro Carvalho Chehab 10089a0bf528SMauro Carvalho Chehab error2: 10099a0bf528SMauro Carvalho Chehab return status; 10109a0bf528SMauro Carvalho Chehab } 10119a0bf528SMauro Carvalho Chehab 1012cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) 10139a0bf528SMauro Carvalho Chehab { 10149a0bf528SMauro Carvalho Chehab int status; 10159a0bf528SMauro Carvalho Chehab bool powerdown_cmd; 10169a0bf528SMauro Carvalho Chehab 10179a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 10189a0bf528SMauro Carvalho Chehab 10199a0bf528SMauro Carvalho Chehab /* Write command */ 10209a0bf528SMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd); 10219a0bf528SMauro Carvalho Chehab if (status < 0) 10229a0bf528SMauro Carvalho Chehab goto error; 10239a0bf528SMauro Carvalho Chehab if (cmd == SIO_HI_RA_RAM_CMD_RESET) 1024b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 10259a0bf528SMauro Carvalho Chehab 10269a0bf528SMauro Carvalho Chehab powerdown_cmd = 10279a0bf528SMauro Carvalho Chehab (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && 1028cd7a67a4SMauro Carvalho Chehab ((state->m_hi_cfg_ctrl) & 10299a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == 10309a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); 10315a7f7b79SMauro Carvalho Chehab if (!powerdown_cmd) { 10329a0bf528SMauro Carvalho Chehab /* Wait until command rdy */ 1033cd7a67a4SMauro Carvalho Chehab u32 retry_count = 0; 1034cd7a67a4SMauro Carvalho Chehab u16 wait_cmd; 10359a0bf528SMauro Carvalho Chehab 10369a0bf528SMauro Carvalho Chehab do { 1037b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1038cd7a67a4SMauro Carvalho Chehab retry_count += 1; 10399a0bf528SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_CMD__A, 1040cd7a67a4SMauro Carvalho Chehab &wait_cmd); 1041cd7a67a4SMauro Carvalho Chehab } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES) 1042cd7a67a4SMauro Carvalho Chehab && (wait_cmd != 0)); 10439a0bf528SMauro Carvalho Chehab if (status < 0) 10449a0bf528SMauro Carvalho Chehab goto error; 1045cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_RES__A, p_result); 10469a0bf528SMauro Carvalho Chehab } 10479a0bf528SMauro Carvalho Chehab error: 10489a0bf528SMauro Carvalho Chehab if (status < 0) 10493a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 10509a0bf528SMauro Carvalho Chehab 10519a0bf528SMauro Carvalho Chehab return status; 10529a0bf528SMauro Carvalho Chehab } 10539a0bf528SMauro Carvalho Chehab 1054cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state) 10559a0bf528SMauro Carvalho Chehab { 10569a0bf528SMauro Carvalho Chehab int status; 10579a0bf528SMauro Carvalho Chehab 10589a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 10599a0bf528SMauro Carvalho Chehab 10609a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 10619a0bf528SMauro Carvalho Chehab 1062ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_6__A, 1063ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timeout); 10649a0bf528SMauro Carvalho Chehab if (status < 0) 10659a0bf528SMauro Carvalho Chehab goto error; 1066ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_5__A, 1067ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_ctrl); 10689a0bf528SMauro Carvalho Chehab if (status < 0) 10699a0bf528SMauro Carvalho Chehab goto error; 1070ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_4__A, 1071ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_wake_up_key); 10729a0bf528SMauro Carvalho Chehab if (status < 0) 10739a0bf528SMauro Carvalho Chehab goto error; 1074ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_3__A, 1075ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_bridge_delay); 10769a0bf528SMauro Carvalho Chehab if (status < 0) 10779a0bf528SMauro Carvalho Chehab goto error; 1078ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 1079ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timing_div); 10809a0bf528SMauro Carvalho Chehab if (status < 0) 10819a0bf528SMauro Carvalho Chehab goto error; 1082ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 1083ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 10849a0bf528SMauro Carvalho Chehab if (status < 0) 10859a0bf528SMauro Carvalho Chehab goto error; 1086b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); 10879a0bf528SMauro Carvalho Chehab if (status < 0) 10889a0bf528SMauro Carvalho Chehab goto error; 10899a0bf528SMauro Carvalho Chehab 1090cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 10919a0bf528SMauro Carvalho Chehab error: 10929a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 10939a0bf528SMauro Carvalho Chehab if (status < 0) 10943a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 10959a0bf528SMauro Carvalho Chehab return status; 10969a0bf528SMauro Carvalho Chehab } 10979a0bf528SMauro Carvalho Chehab 1098cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state) 10999a0bf528SMauro Carvalho Chehab { 11009a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 11019a0bf528SMauro Carvalho Chehab 1102cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 1103cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timeout = 0x96FF; 11049a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */ 1105cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 11069a0bf528SMauro Carvalho Chehab 1107cd7a67a4SMauro Carvalho Chehab return hi_cfg_command(state); 11089a0bf528SMauro Carvalho Chehab } 11099a0bf528SMauro Carvalho Chehab 1110cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) 11119a0bf528SMauro Carvalho Chehab { 11129a0bf528SMauro Carvalho Chehab int status = -1; 1113cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mclk_cfg = 0; 1114cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mdx_cfg = 0; 11159a0bf528SMauro Carvalho Chehab u16 err_cfg = 0; 11169a0bf528SMauro Carvalho Chehab 11179a0bf528SMauro Carvalho Chehab dprintk(1, ": mpeg %s, %s mode\n", 1118cd7a67a4SMauro Carvalho Chehab mpeg_enable ? "enable" : "disable", 1119cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel ? "parallel" : "serial"); 11209a0bf528SMauro Carvalho Chehab 11219a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 1122ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 1123ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 11249a0bf528SMauro Carvalho Chehab if (status < 0) 11259a0bf528SMauro Carvalho Chehab goto error; 11269a0bf528SMauro Carvalho Chehab 11279a0bf528SMauro Carvalho Chehab /* MPEG TS pad configuration */ 11288418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 11299a0bf528SMauro Carvalho Chehab if (status < 0) 11309a0bf528SMauro Carvalho Chehab goto error; 11319a0bf528SMauro Carvalho Chehab 11325a7f7b79SMauro Carvalho Chehab if (!mpeg_enable) { 11339a0bf528SMauro Carvalho Chehab /* Set MPEG TS pads to inputmode */ 11349a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000); 11359a0bf528SMauro Carvalho Chehab if (status < 0) 11369a0bf528SMauro Carvalho Chehab goto error; 11379a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); 11389a0bf528SMauro Carvalho Chehab if (status < 0) 11399a0bf528SMauro Carvalho Chehab goto error; 11409a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000); 11419a0bf528SMauro Carvalho Chehab if (status < 0) 11429a0bf528SMauro Carvalho Chehab goto error; 11439a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); 11449a0bf528SMauro Carvalho Chehab if (status < 0) 11459a0bf528SMauro Carvalho Chehab goto error; 11469a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000); 11479a0bf528SMauro Carvalho Chehab if (status < 0) 11489a0bf528SMauro Carvalho Chehab goto error; 11499a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 11509a0bf528SMauro Carvalho Chehab if (status < 0) 11519a0bf528SMauro Carvalho Chehab goto error; 11529a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 11539a0bf528SMauro Carvalho Chehab if (status < 0) 11549a0bf528SMauro Carvalho Chehab goto error; 11559a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 11569a0bf528SMauro Carvalho Chehab if (status < 0) 11579a0bf528SMauro Carvalho Chehab goto error; 11589a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 11599a0bf528SMauro Carvalho Chehab if (status < 0) 11609a0bf528SMauro Carvalho Chehab goto error; 11619a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 11629a0bf528SMauro Carvalho Chehab if (status < 0) 11639a0bf528SMauro Carvalho Chehab goto error; 11649a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 11659a0bf528SMauro Carvalho Chehab if (status < 0) 11669a0bf528SMauro Carvalho Chehab goto error; 11679a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 11689a0bf528SMauro Carvalho Chehab if (status < 0) 11699a0bf528SMauro Carvalho Chehab goto error; 11709a0bf528SMauro Carvalho Chehab } else { 11719a0bf528SMauro Carvalho Chehab /* Enable MPEG output */ 1172cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg = 1173cd7a67a4SMauro Carvalho Chehab ((state->m_ts_data_strength << 11749a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003); 1175cd7a67a4SMauro Carvalho Chehab sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength << 11769a0bf528SMauro Carvalho Chehab SIO_PDR_MCLK_CFG_DRIVE__B) | 11779a0bf528SMauro Carvalho Chehab 0x0003); 11789a0bf528SMauro Carvalho Chehab 1179cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg); 11809a0bf528SMauro Carvalho Chehab if (status < 0) 11819a0bf528SMauro Carvalho Chehab goto error; 11829a0bf528SMauro Carvalho Chehab 11839a0bf528SMauro Carvalho Chehab if (state->enable_merr_cfg) 1184cd7a67a4SMauro Carvalho Chehab err_cfg = sio_pdr_mdx_cfg; 11859a0bf528SMauro Carvalho Chehab 11869a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); 11879a0bf528SMauro Carvalho Chehab if (status < 0) 11889a0bf528SMauro Carvalho Chehab goto error; 11899a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); 11909a0bf528SMauro Carvalho Chehab if (status < 0) 11919a0bf528SMauro Carvalho Chehab goto error; 11929a0bf528SMauro Carvalho Chehab 11935a7f7b79SMauro Carvalho Chehab if (state->m_enable_parallel) { 119439c1cb2bSJonathan McCrohan /* parallel -> enable MD1 to MD7 */ 1195ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 1196ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11979a0bf528SMauro Carvalho Chehab if (status < 0) 11989a0bf528SMauro Carvalho Chehab goto error; 1199ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 1200ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12019a0bf528SMauro Carvalho Chehab if (status < 0) 12029a0bf528SMauro Carvalho Chehab goto error; 1203ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 1204ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12059a0bf528SMauro Carvalho Chehab if (status < 0) 12069a0bf528SMauro Carvalho Chehab goto error; 1207ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 1208ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12099a0bf528SMauro Carvalho Chehab if (status < 0) 12109a0bf528SMauro Carvalho Chehab goto error; 1211ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 1212ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12139a0bf528SMauro Carvalho Chehab if (status < 0) 12149a0bf528SMauro Carvalho Chehab goto error; 1215ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 1216ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12179a0bf528SMauro Carvalho Chehab if (status < 0) 12189a0bf528SMauro Carvalho Chehab goto error; 1219ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 1220ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 12219a0bf528SMauro Carvalho Chehab if (status < 0) 12229a0bf528SMauro Carvalho Chehab goto error; 12239a0bf528SMauro Carvalho Chehab } else { 1224cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg = ((state->m_ts_data_strength << 12259a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B) 12269a0bf528SMauro Carvalho Chehab | 0x0003); 12279a0bf528SMauro Carvalho Chehab /* serial -> disable MD1 to MD7 */ 12289a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 12299a0bf528SMauro Carvalho Chehab if (status < 0) 12309a0bf528SMauro Carvalho Chehab goto error; 12319a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 12329a0bf528SMauro Carvalho Chehab if (status < 0) 12339a0bf528SMauro Carvalho Chehab goto error; 12349a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 12359a0bf528SMauro Carvalho Chehab if (status < 0) 12369a0bf528SMauro Carvalho Chehab goto error; 12379a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 12389a0bf528SMauro Carvalho Chehab if (status < 0) 12399a0bf528SMauro Carvalho Chehab goto error; 12409a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 12419a0bf528SMauro Carvalho Chehab if (status < 0) 12429a0bf528SMauro Carvalho Chehab goto error; 12439a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 12449a0bf528SMauro Carvalho Chehab if (status < 0) 12459a0bf528SMauro Carvalho Chehab goto error; 12469a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 12479a0bf528SMauro Carvalho Chehab if (status < 0) 12489a0bf528SMauro Carvalho Chehab goto error; 12499a0bf528SMauro Carvalho Chehab } 1250cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg); 12519a0bf528SMauro Carvalho Chehab if (status < 0) 12529a0bf528SMauro Carvalho Chehab goto error; 1253cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg); 12549a0bf528SMauro Carvalho Chehab if (status < 0) 12559a0bf528SMauro Carvalho Chehab goto error; 12569a0bf528SMauro Carvalho Chehab } 12579a0bf528SMauro Carvalho Chehab /* Enable MB output over MPEG pads and ctl input */ 12589a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MON_CFG__A, 0x0000); 12599a0bf528SMauro Carvalho Chehab if (status < 0) 12609a0bf528SMauro Carvalho Chehab goto error; 12619a0bf528SMauro Carvalho Chehab /* Write nomagic word to enable pdr reg write */ 12629a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 12639a0bf528SMauro Carvalho Chehab error: 12649a0bf528SMauro Carvalho Chehab if (status < 0) 12653a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 12669a0bf528SMauro Carvalho Chehab return status; 12679a0bf528SMauro Carvalho Chehab } 12689a0bf528SMauro Carvalho Chehab 1269cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state) 12709a0bf528SMauro Carvalho Chehab { 12719a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 12729a0bf528SMauro Carvalho Chehab 1273cd7a67a4SMauro Carvalho Chehab return mpegts_configure_pins(state, false); 12749a0bf528SMauro Carvalho Chehab } 12759a0bf528SMauro Carvalho Chehab 1276cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state, 1277cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out) 12789a0bf528SMauro Carvalho Chehab { 1279cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0; 12809a0bf528SMauro Carvalho Chehab int status; 12819a0bf528SMauro Carvalho Chehab unsigned long end; 12829a0bf528SMauro Carvalho Chehab 12839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 12849a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 12859a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN); 12869a0bf528SMauro Carvalho Chehab if (status < 0) 12879a0bf528SMauro Carvalho Chehab goto error; 1288cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset); 12899a0bf528SMauro Carvalho Chehab if (status < 0) 12909a0bf528SMauro Carvalho Chehab goto error; 1291cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements); 12929a0bf528SMauro Carvalho Chehab if (status < 0) 12939a0bf528SMauro Carvalho Chehab goto error; 12949a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 12959a0bf528SMauro Carvalho Chehab if (status < 0) 12969a0bf528SMauro Carvalho Chehab goto error; 12979a0bf528SMauro Carvalho Chehab 1298cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out); 12999a0bf528SMauro Carvalho Chehab do { 1300b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1301cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status); 13029a0bf528SMauro Carvalho Chehab if (status < 0) 13039a0bf528SMauro Carvalho Chehab goto error; 1304cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) && 13059a0bf528SMauro Carvalho Chehab ((time_is_after_jiffies(end)))); 13069a0bf528SMauro Carvalho Chehab 1307cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) { 13083a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 13099a0bf528SMauro Carvalho Chehab status = -EINVAL; 13109a0bf528SMauro Carvalho Chehab goto error2; 13119a0bf528SMauro Carvalho Chehab } 13129a0bf528SMauro Carvalho Chehab error: 13139a0bf528SMauro Carvalho Chehab if (status < 0) 13143a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 13159a0bf528SMauro Carvalho Chehab error2: 13169a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 13179a0bf528SMauro Carvalho Chehab return status; 13189a0bf528SMauro Carvalho Chehab } 13199a0bf528SMauro Carvalho Chehab 13209a0bf528SMauro Carvalho Chehab 1321cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state, 1322cd7a67a4SMauro Carvalho Chehab const u8 p_mc_image[], u32 length) 13239a0bf528SMauro Carvalho Chehab { 1324cd7a67a4SMauro Carvalho Chehab const u8 *p_src = p_mc_image; 1325cd7a67a4SMauro Carvalho Chehab u32 address; 1326cd7a67a4SMauro Carvalho Chehab u16 n_blocks; 1327cd7a67a4SMauro Carvalho Chehab u16 block_size; 13289a0bf528SMauro Carvalho Chehab u32 offset = 0; 13299a0bf528SMauro Carvalho Chehab u32 i; 13309a0bf528SMauro Carvalho Chehab int status = 0; 13319a0bf528SMauro Carvalho Chehab 13329a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 13339a0bf528SMauro Carvalho Chehab 13349a0bf528SMauro Carvalho Chehab /* down the drain (we don't care about MAGIC_WORD) */ 13359a0bf528SMauro Carvalho Chehab #if 0 13369a0bf528SMauro Carvalho Chehab /* For future reference */ 1337cd7a67a4SMauro Carvalho Chehab drain = (p_src[0] << 8) | p_src[1]; 13389a0bf528SMauro Carvalho Chehab #endif 1339cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13409a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 1341cd7a67a4SMauro Carvalho Chehab n_blocks = (p_src[0] << 8) | p_src[1]; 1342cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13439a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13449a0bf528SMauro Carvalho Chehab 1345cd7a67a4SMauro Carvalho Chehab for (i = 0; i < n_blocks; i += 1) { 1346cd7a67a4SMauro Carvalho Chehab address = (p_src[0] << 24) | (p_src[1] << 16) | 1347cd7a67a4SMauro Carvalho Chehab (p_src[2] << 8) | p_src[3]; 1348cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u32); 13499a0bf528SMauro Carvalho Chehab offset += sizeof(u32); 13509a0bf528SMauro Carvalho Chehab 1351cd7a67a4SMauro Carvalho Chehab block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16); 1352cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13539a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13549a0bf528SMauro Carvalho Chehab 13559a0bf528SMauro Carvalho Chehab #if 0 13569a0bf528SMauro Carvalho Chehab /* For future reference */ 1357cd7a67a4SMauro Carvalho Chehab flags = (p_src[0] << 8) | p_src[1]; 13589a0bf528SMauro Carvalho Chehab #endif 1359cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13609a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13619a0bf528SMauro Carvalho Chehab 13629a0bf528SMauro Carvalho Chehab #if 0 13639a0bf528SMauro Carvalho Chehab /* For future reference */ 1364cd7a67a4SMauro Carvalho Chehab block_crc = (p_src[0] << 8) | p_src[1]; 13659a0bf528SMauro Carvalho Chehab #endif 1366cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13679a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13689a0bf528SMauro Carvalho Chehab 1369cd7a67a4SMauro Carvalho Chehab if (offset + block_size > length) { 13703a4398f5SMauro Carvalho Chehab pr_err("Firmware is corrupted.\n"); 13719a0bf528SMauro Carvalho Chehab return -EINVAL; 13729a0bf528SMauro Carvalho Chehab } 13739a0bf528SMauro Carvalho Chehab 1374cd7a67a4SMauro Carvalho Chehab status = write_block(state, address, block_size, p_src); 13759a0bf528SMauro Carvalho Chehab if (status < 0) { 13763a4398f5SMauro Carvalho Chehab pr_err("Error %d while loading firmware\n", status); 13779a0bf528SMauro Carvalho Chehab break; 13789a0bf528SMauro Carvalho Chehab } 1379cd7a67a4SMauro Carvalho Chehab p_src += block_size; 1380cd7a67a4SMauro Carvalho Chehab offset += block_size; 13819a0bf528SMauro Carvalho Chehab } 13829a0bf528SMauro Carvalho Chehab return status; 13839a0bf528SMauro Carvalho Chehab } 13849a0bf528SMauro Carvalho Chehab 1385cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable) 13869a0bf528SMauro Carvalho Chehab { 13879a0bf528SMauro Carvalho Chehab int status; 13889a0bf528SMauro Carvalho Chehab u16 data = 0; 1389cd7a67a4SMauro Carvalho Chehab u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; 1390cd7a67a4SMauro Carvalho Chehab u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; 13919a0bf528SMauro Carvalho Chehab unsigned long end; 13929a0bf528SMauro Carvalho Chehab 13939a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 13949a0bf528SMauro Carvalho Chehab 13955a7f7b79SMauro Carvalho Chehab if (!enable) { 1396cd7a67a4SMauro Carvalho Chehab desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; 1397cd7a67a4SMauro Carvalho Chehab desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; 13989a0bf528SMauro Carvalho Chehab } 13999a0bf528SMauro Carvalho Chehab 14009a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 1401cd7a67a4SMauro Carvalho Chehab if (status >= 0 && data == desired_status) { 14029a0bf528SMauro Carvalho Chehab /* tokenring already has correct status */ 14039a0bf528SMauro Carvalho Chehab return status; 14049a0bf528SMauro Carvalho Chehab } 14059a0bf528SMauro Carvalho Chehab /* Disable/enable dvbt tokenring bridge */ 1406cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl); 14079a0bf528SMauro Carvalho Chehab 14089a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT); 14099a0bf528SMauro Carvalho Chehab do { 14109a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 1411ab5060cdSMauro Carvalho Chehab if ((status >= 0 && data == desired_status) 1412ab5060cdSMauro Carvalho Chehab || time_is_after_jiffies(end)) 14139a0bf528SMauro Carvalho Chehab break; 1414b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 14159a0bf528SMauro Carvalho Chehab } while (1); 1416cd7a67a4SMauro Carvalho Chehab if (data != desired_status) { 14173a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 14189a0bf528SMauro Carvalho Chehab return -EINVAL; 14199a0bf528SMauro Carvalho Chehab } 14209a0bf528SMauro Carvalho Chehab return status; 14219a0bf528SMauro Carvalho Chehab } 14229a0bf528SMauro Carvalho Chehab 1423cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state) 14249a0bf528SMauro Carvalho Chehab { 14259a0bf528SMauro Carvalho Chehab int status = 0; 1426cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0; 1427cd7a67a4SMauro Carvalho Chehab u16 fec_oc_ipr_mode = 0; 14289a0bf528SMauro Carvalho Chehab 14299a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 14309a0bf528SMauro Carvalho Chehab 143139c1cb2bSJonathan McCrohan /* Graceful shutdown (byte boundaries) */ 1432cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 14339a0bf528SMauro Carvalho Chehab if (status < 0) 14349a0bf528SMauro Carvalho Chehab goto error; 1435cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M; 1436cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 14379a0bf528SMauro Carvalho Chehab if (status < 0) 14389a0bf528SMauro Carvalho Chehab goto error; 14399a0bf528SMauro Carvalho Chehab 14409a0bf528SMauro Carvalho Chehab /* Suppress MCLK during absence of data */ 1441cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode); 14429a0bf528SMauro Carvalho Chehab if (status < 0) 14439a0bf528SMauro Carvalho Chehab goto error; 1444cd7a67a4SMauro Carvalho Chehab fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; 1445cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode); 14469a0bf528SMauro Carvalho Chehab 14479a0bf528SMauro Carvalho Chehab error: 14489a0bf528SMauro Carvalho Chehab if (status < 0) 14493a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 14509a0bf528SMauro Carvalho Chehab 14519a0bf528SMauro Carvalho Chehab return status; 14529a0bf528SMauro Carvalho Chehab } 14539a0bf528SMauro Carvalho Chehab 14549a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state, 1455cd7a67a4SMauro Carvalho Chehab u16 cmd, u8 parameter_len, 1456cd7a67a4SMauro Carvalho Chehab u16 *parameter, u8 result_len, u16 *result) 14579a0bf528SMauro Carvalho Chehab { 14589a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15 14599a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine! 14609a0bf528SMauro Carvalho Chehab #endif 1461cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0; 14629a0bf528SMauro Carvalho Chehab int status = -EINVAL; 14639a0bf528SMauro Carvalho Chehab unsigned long end; 14649a0bf528SMauro Carvalho Chehab u8 buffer[34]; 14659a0bf528SMauro Carvalho Chehab int cnt = 0, ii; 14669a0bf528SMauro Carvalho Chehab const char *p; 14679a0bf528SMauro Carvalho Chehab char errname[30]; 14689a0bf528SMauro Carvalho Chehab 14699a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 14709a0bf528SMauro Carvalho Chehab 1471cd7a67a4SMauro Carvalho Chehab if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) || 1472cd7a67a4SMauro Carvalho Chehab ((result_len > 0) && (result == NULL))) { 14733a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 14749a0bf528SMauro Carvalho Chehab return status; 14759a0bf528SMauro Carvalho Chehab } 14769a0bf528SMauro Carvalho Chehab 14779a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 14789a0bf528SMauro Carvalho Chehab 14799a0bf528SMauro Carvalho Chehab /* assume that the command register is ready 14809a0bf528SMauro Carvalho Chehab since it is checked afterwards */ 1481cd7a67a4SMauro Carvalho Chehab for (ii = parameter_len - 1; ii >= 0; ii -= 1) { 14829a0bf528SMauro Carvalho Chehab buffer[cnt++] = (parameter[ii] & 0xFF); 14839a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF); 14849a0bf528SMauro Carvalho Chehab } 14859a0bf528SMauro Carvalho Chehab buffer[cnt++] = (cmd & 0xFF); 14869a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((cmd >> 8) & 0xFF); 14879a0bf528SMauro Carvalho Chehab 14889a0bf528SMauro Carvalho Chehab write_block(state, SCU_RAM_PARAM_0__A - 1489cd7a67a4SMauro Carvalho Chehab (parameter_len - 1), cnt, buffer); 14909a0bf528SMauro Carvalho Chehab /* Wait until SCU has processed command */ 14919a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME); 14929a0bf528SMauro Carvalho Chehab do { 1493b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1494cd7a67a4SMauro Carvalho Chehab status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd); 14959a0bf528SMauro Carvalho Chehab if (status < 0) 14969a0bf528SMauro Carvalho Chehab goto error; 1497cd7a67a4SMauro Carvalho Chehab } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); 1498cd7a67a4SMauro Carvalho Chehab if (cur_cmd != DRX_SCU_READY) { 14993a4398f5SMauro Carvalho Chehab pr_err("SCU not ready\n"); 15009a0bf528SMauro Carvalho Chehab status = -EIO; 15019a0bf528SMauro Carvalho Chehab goto error2; 15029a0bf528SMauro Carvalho Chehab } 15039a0bf528SMauro Carvalho Chehab /* read results */ 1504cd7a67a4SMauro Carvalho Chehab if ((result_len > 0) && (result != NULL)) { 15059a0bf528SMauro Carvalho Chehab s16 err; 15069a0bf528SMauro Carvalho Chehab int ii; 15079a0bf528SMauro Carvalho Chehab 1508cd7a67a4SMauro Carvalho Chehab for (ii = result_len - 1; ii >= 0; ii -= 1) { 1509ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_PARAM_0__A - ii, 1510ab5060cdSMauro Carvalho Chehab &result[ii]); 15119a0bf528SMauro Carvalho Chehab if (status < 0) 15129a0bf528SMauro Carvalho Chehab goto error; 15139a0bf528SMauro Carvalho Chehab } 15149a0bf528SMauro Carvalho Chehab 15159a0bf528SMauro Carvalho Chehab /* Check if an error was reported by SCU */ 15169a0bf528SMauro Carvalho Chehab err = (s16)result[0]; 15179a0bf528SMauro Carvalho Chehab if (err >= 0) 15189a0bf528SMauro Carvalho Chehab goto error; 15199a0bf528SMauro Carvalho Chehab 15209a0bf528SMauro Carvalho Chehab /* check for the known error codes */ 15219a0bf528SMauro Carvalho Chehab switch (err) { 15229a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKCMD: 15239a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKCMD"; 15249a0bf528SMauro Carvalho Chehab break; 15259a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKSTD: 15269a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKSTD"; 15279a0bf528SMauro Carvalho Chehab break; 15289a0bf528SMauro Carvalho Chehab case SCU_RESULT_SIZE: 15299a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_SIZE"; 15309a0bf528SMauro Carvalho Chehab break; 15319a0bf528SMauro Carvalho Chehab case SCU_RESULT_INVPAR: 15329a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_INVPAR"; 15339a0bf528SMauro Carvalho Chehab break; 15349a0bf528SMauro Carvalho Chehab default: /* Other negative values are errors */ 15359a0bf528SMauro Carvalho Chehab sprintf(errname, "ERROR: %d\n", err); 15369a0bf528SMauro Carvalho Chehab p = errname; 15379a0bf528SMauro Carvalho Chehab } 15383a4398f5SMauro Carvalho Chehab pr_err("%s while sending cmd 0x%04x with params:", p, cmd); 15399a0bf528SMauro Carvalho Chehab print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt); 15409a0bf528SMauro Carvalho Chehab status = -EINVAL; 15419a0bf528SMauro Carvalho Chehab goto error2; 15429a0bf528SMauro Carvalho Chehab } 15439a0bf528SMauro Carvalho Chehab 15449a0bf528SMauro Carvalho Chehab error: 15459a0bf528SMauro Carvalho Chehab if (status < 0) 15463a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 15479a0bf528SMauro Carvalho Chehab error2: 15489a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 15499a0bf528SMauro Carvalho Chehab return status; 15509a0bf528SMauro Carvalho Chehab } 15519a0bf528SMauro Carvalho Chehab 1552cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active) 15539a0bf528SMauro Carvalho Chehab { 15549a0bf528SMauro Carvalho Chehab u16 data = 0; 15559a0bf528SMauro Carvalho Chehab int status; 15569a0bf528SMauro Carvalho Chehab 15579a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 15589a0bf528SMauro Carvalho Chehab 15599a0bf528SMauro Carvalho Chehab /* Configure IQM */ 15609a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 15619a0bf528SMauro Carvalho Chehab if (status < 0) 15629a0bf528SMauro Carvalho Chehab goto error; 15639a0bf528SMauro Carvalho Chehab 15649a0bf528SMauro Carvalho Chehab if (!active) { 15659a0bf528SMauro Carvalho Chehab data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY 15669a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_AMP_STANDBY 15679a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_PD_STANDBY 15689a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY 15699a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY); 15709a0bf528SMauro Carvalho Chehab } else { 15719a0bf528SMauro Carvalho Chehab data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY) 15729a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_AMP_STANDBY) 15739a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_PD_STANDBY) 15749a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY) 15759a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY) 15769a0bf528SMauro Carvalho Chehab ); 15779a0bf528SMauro Carvalho Chehab } 15789a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 15799a0bf528SMauro Carvalho Chehab 15809a0bf528SMauro Carvalho Chehab error: 15819a0bf528SMauro Carvalho Chehab if (status < 0) 15823a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 15839a0bf528SMauro Carvalho Chehab return status; 15849a0bf528SMauro Carvalho Chehab } 15859a0bf528SMauro Carvalho Chehab 1586cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) 15879a0bf528SMauro Carvalho Chehab { 15889a0bf528SMauro Carvalho Chehab int status = 0; 1589cd7a67a4SMauro Carvalho Chehab u16 sio_cc_pwd_mode = 0; 15909a0bf528SMauro Carvalho Chehab 15919a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 15929a0bf528SMauro Carvalho Chehab 15939a0bf528SMauro Carvalho Chehab /* Check arguments */ 15949a0bf528SMauro Carvalho Chehab if (mode == NULL) 15959a0bf528SMauro Carvalho Chehab return -EINVAL; 15969a0bf528SMauro Carvalho Chehab 15979a0bf528SMauro Carvalho Chehab switch (*mode) { 15989a0bf528SMauro Carvalho Chehab case DRX_POWER_UP: 1599cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; 16009a0bf528SMauro Carvalho Chehab break; 16019a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_OFDM: 1602cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM; 16039a0bf528SMauro Carvalho Chehab break; 16049a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_CORE: 1605cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; 16069a0bf528SMauro Carvalho Chehab break; 16079a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_PLL: 1608cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; 16099a0bf528SMauro Carvalho Chehab break; 16109a0bf528SMauro Carvalho Chehab case DRX_POWER_DOWN: 1611cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; 16129a0bf528SMauro Carvalho Chehab break; 16139a0bf528SMauro Carvalho Chehab default: 16149a0bf528SMauro Carvalho Chehab /* Unknow sleep mode */ 16159a0bf528SMauro Carvalho Chehab return -EINVAL; 16169a0bf528SMauro Carvalho Chehab } 16179a0bf528SMauro Carvalho Chehab 16189a0bf528SMauro Carvalho Chehab /* If already in requested power mode, do nothing */ 1619cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode == *mode) 16209a0bf528SMauro Carvalho Chehab return 0; 16219a0bf528SMauro Carvalho Chehab 16229a0bf528SMauro Carvalho Chehab /* For next steps make sure to start from DRX_POWER_UP mode */ 1623cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode != DRX_POWER_UP) { 1624cd7a67a4SMauro Carvalho Chehab status = power_up_device(state); 16259a0bf528SMauro Carvalho Chehab if (status < 0) 16269a0bf528SMauro Carvalho Chehab goto error; 1627cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, true); 16289a0bf528SMauro Carvalho Chehab if (status < 0) 16299a0bf528SMauro Carvalho Chehab goto error; 16309a0bf528SMauro Carvalho Chehab } 16319a0bf528SMauro Carvalho Chehab 16329a0bf528SMauro Carvalho Chehab if (*mode == DRX_POWER_UP) { 16339a0bf528SMauro Carvalho Chehab /* Restore analog & pin configuartion */ 16349a0bf528SMauro Carvalho Chehab } else { 16359a0bf528SMauro Carvalho Chehab /* Power down to requested mode */ 16369a0bf528SMauro Carvalho Chehab /* Backup some register settings */ 16379a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected 16389a0bf528SMauro Carvalho Chehab to them in input mode */ 16399a0bf528SMauro Carvalho Chehab /* Analog power down */ 16409a0bf528SMauro Carvalho Chehab /* ADC power down */ 16419a0bf528SMauro Carvalho Chehab /* Power down device */ 16429a0bf528SMauro Carvalho Chehab /* stop all comm_exec */ 16439a0bf528SMauro Carvalho Chehab /* Stop and power down previous standard */ 1644cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 16459a0bf528SMauro Carvalho Chehab case OM_DVBT: 1646cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 16479a0bf528SMauro Carvalho Chehab if (status < 0) 16489a0bf528SMauro Carvalho Chehab goto error; 1649cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, false); 16509a0bf528SMauro Carvalho Chehab if (status < 0) 16519a0bf528SMauro Carvalho Chehab goto error; 16529a0bf528SMauro Carvalho Chehab break; 16539a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 16549a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1655cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 16569a0bf528SMauro Carvalho Chehab if (status < 0) 16579a0bf528SMauro Carvalho Chehab goto error; 1658cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state); 16599a0bf528SMauro Carvalho Chehab if (status < 0) 16609a0bf528SMauro Carvalho Chehab goto error; 16619a0bf528SMauro Carvalho Chehab break; 16629a0bf528SMauro Carvalho Chehab default: 16639a0bf528SMauro Carvalho Chehab break; 16649a0bf528SMauro Carvalho Chehab } 1665cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false); 16669a0bf528SMauro Carvalho Chehab if (status < 0) 16679a0bf528SMauro Carvalho Chehab goto error; 1668cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode); 16699a0bf528SMauro Carvalho Chehab if (status < 0) 16709a0bf528SMauro Carvalho Chehab goto error; 16719a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 16729a0bf528SMauro Carvalho Chehab if (status < 0) 16739a0bf528SMauro Carvalho Chehab goto error; 16749a0bf528SMauro Carvalho Chehab 16759a0bf528SMauro Carvalho Chehab if (*mode != DRXK_POWER_DOWN_OFDM) { 1676cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |= 16779a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 1678cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state); 16799a0bf528SMauro Carvalho Chehab if (status < 0) 16809a0bf528SMauro Carvalho Chehab goto error; 16819a0bf528SMauro Carvalho Chehab } 16829a0bf528SMauro Carvalho Chehab } 1683cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = *mode; 16849a0bf528SMauro Carvalho Chehab 16859a0bf528SMauro Carvalho Chehab error: 16869a0bf528SMauro Carvalho Chehab if (status < 0) 16873a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 16889a0bf528SMauro Carvalho Chehab 16899a0bf528SMauro Carvalho Chehab return status; 16909a0bf528SMauro Carvalho Chehab } 16919a0bf528SMauro Carvalho Chehab 1692cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) 16939a0bf528SMauro Carvalho Chehab { 1694cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 1695cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 16969a0bf528SMauro Carvalho Chehab u16 data = 0; 16979a0bf528SMauro Carvalho Chehab int status; 16989a0bf528SMauro Carvalho Chehab 16999a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 17009a0bf528SMauro Carvalho Chehab 17019a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data); 17029a0bf528SMauro Carvalho Chehab if (status < 0) 17039a0bf528SMauro Carvalho Chehab goto error; 17049a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) { 17059a0bf528SMauro Carvalho Chehab /* Send OFDM stop command */ 1706ab5060cdSMauro Carvalho Chehab status = scu_command(state, 1707ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 1708ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 1709ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 17109a0bf528SMauro Carvalho Chehab if (status < 0) 17119a0bf528SMauro Carvalho Chehab goto error; 17129a0bf528SMauro Carvalho Chehab /* Send OFDM reset command */ 1713ab5060cdSMauro Carvalho Chehab status = scu_command(state, 1714ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 1715ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 1716ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 17179a0bf528SMauro Carvalho Chehab if (status < 0) 17189a0bf528SMauro Carvalho Chehab goto error; 17199a0bf528SMauro Carvalho Chehab } 17209a0bf528SMauro Carvalho Chehab 17219a0bf528SMauro Carvalho Chehab /* Reset datapath for OFDM, processors first */ 17229a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 17239a0bf528SMauro Carvalho Chehab if (status < 0) 17249a0bf528SMauro Carvalho Chehab goto error; 17259a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 17269a0bf528SMauro Carvalho Chehab if (status < 0) 17279a0bf528SMauro Carvalho Chehab goto error; 17289a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 17299a0bf528SMauro Carvalho Chehab if (status < 0) 17309a0bf528SMauro Carvalho Chehab goto error; 17319a0bf528SMauro Carvalho Chehab 17329a0bf528SMauro Carvalho Chehab /* powerdown AFE */ 1733cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false); 17349a0bf528SMauro Carvalho Chehab if (status < 0) 17359a0bf528SMauro Carvalho Chehab goto error; 17369a0bf528SMauro Carvalho Chehab 17379a0bf528SMauro Carvalho Chehab /* powerdown to OFDM mode */ 1738cd7a67a4SMauro Carvalho Chehab if (set_power_mode) { 1739cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 17409a0bf528SMauro Carvalho Chehab if (status < 0) 17419a0bf528SMauro Carvalho Chehab goto error; 17429a0bf528SMauro Carvalho Chehab } 17439a0bf528SMauro Carvalho Chehab error: 17449a0bf528SMauro Carvalho Chehab if (status < 0) 17453a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 17469a0bf528SMauro Carvalho Chehab return status; 17479a0bf528SMauro Carvalho Chehab } 17489a0bf528SMauro Carvalho Chehab 1749cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state, 1750cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 17519a0bf528SMauro Carvalho Chehab { 17529a0bf528SMauro Carvalho Chehab int status = 0; 17539a0bf528SMauro Carvalho Chehab 17549a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 17559a0bf528SMauro Carvalho Chehab /* 17569a0bf528SMauro Carvalho Chehab Stop and power down previous standard 17579a0bf528SMauro Carvalho Chehab TODO investigate total power down instead of partial 17589a0bf528SMauro Carvalho Chehab power down depending on "previous" standard. 17599a0bf528SMauro Carvalho Chehab */ 17609a0bf528SMauro Carvalho Chehab 17619a0bf528SMauro Carvalho Chehab /* disable HW lock indicator */ 1762ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 1763ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 17649a0bf528SMauro Carvalho Chehab if (status < 0) 17659a0bf528SMauro Carvalho Chehab goto error; 17669a0bf528SMauro Carvalho Chehab 17679a0bf528SMauro Carvalho Chehab /* Device is already at the required mode */ 1768cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == o_mode) 17699a0bf528SMauro Carvalho Chehab return 0; 17709a0bf528SMauro Carvalho Chehab 1771cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 17729a0bf528SMauro Carvalho Chehab /* OM_NONE was added for start up */ 17739a0bf528SMauro Carvalho Chehab case OM_NONE: 17749a0bf528SMauro Carvalho Chehab break; 17759a0bf528SMauro Carvalho Chehab case OM_DVBT: 1776cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 17779a0bf528SMauro Carvalho Chehab if (status < 0) 17789a0bf528SMauro Carvalho Chehab goto error; 1779cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, true); 17809a0bf528SMauro Carvalho Chehab if (status < 0) 17819a0bf528SMauro Carvalho Chehab goto error; 1782cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 17839a0bf528SMauro Carvalho Chehab break; 17849a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: /* fallthrough */ 17859a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1786cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 17879a0bf528SMauro Carvalho Chehab if (status < 0) 17889a0bf528SMauro Carvalho Chehab goto error; 1789cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state); 17909a0bf528SMauro Carvalho Chehab if (status < 0) 17919a0bf528SMauro Carvalho Chehab goto error; 1792cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 17939a0bf528SMauro Carvalho Chehab break; 17949a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 17959a0bf528SMauro Carvalho Chehab default: 17969a0bf528SMauro Carvalho Chehab status = -EINVAL; 17979a0bf528SMauro Carvalho Chehab goto error; 17989a0bf528SMauro Carvalho Chehab } 17999a0bf528SMauro Carvalho Chehab 18009a0bf528SMauro Carvalho Chehab /* 18019a0bf528SMauro Carvalho Chehab Power up new standard 18029a0bf528SMauro Carvalho Chehab */ 1803cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 18049a0bf528SMauro Carvalho Chehab case OM_DVBT: 18059a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-T\n"); 1806cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode; 1807cd7a67a4SMauro Carvalho Chehab status = set_dvbt_standard(state, o_mode); 18089a0bf528SMauro Carvalho Chehab if (status < 0) 18099a0bf528SMauro Carvalho Chehab goto error; 18109a0bf528SMauro Carvalho Chehab break; 18119a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: /* fallthrough */ 18129a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 18139a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-C Annex %c\n", 1814cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C'); 1815cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode; 1816cd7a67a4SMauro Carvalho Chehab status = set_qam_standard(state, o_mode); 18179a0bf528SMauro Carvalho Chehab if (status < 0) 18189a0bf528SMauro Carvalho Chehab goto error; 18199a0bf528SMauro Carvalho Chehab break; 18209a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 18219a0bf528SMauro Carvalho Chehab default: 18229a0bf528SMauro Carvalho Chehab status = -EINVAL; 18239a0bf528SMauro Carvalho Chehab } 18249a0bf528SMauro Carvalho Chehab error: 18259a0bf528SMauro Carvalho Chehab if (status < 0) 18263a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 18279a0bf528SMauro Carvalho Chehab return status; 18289a0bf528SMauro Carvalho Chehab } 18299a0bf528SMauro Carvalho Chehab 1830cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq, 1831cd7a67a4SMauro Carvalho Chehab s32 intermediate_frequency) 18329a0bf528SMauro Carvalho Chehab { 18339a0bf528SMauro Carvalho Chehab int status = -EINVAL; 18349a0bf528SMauro Carvalho Chehab 1835cd7a67a4SMauro Carvalho Chehab u16 i_freqk_hz; 1836cd7a67a4SMauro Carvalho Chehab s32 offsetk_hz = offset_freq / 1000; 18379a0bf528SMauro Carvalho Chehab 18389a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 1839cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state != DRXK_STOPPED && 1840cd7a67a4SMauro Carvalho Chehab state->m_drxk_state != DRXK_DTV_STARTED) 18419a0bf528SMauro Carvalho Chehab goto error; 18429a0bf528SMauro Carvalho Chehab 1843cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON); 18449a0bf528SMauro Carvalho Chehab 1845cd7a67a4SMauro Carvalho Chehab if (intermediate_frequency < 0) { 1846cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect; 1847cd7a67a4SMauro Carvalho Chehab intermediate_frequency = -intermediate_frequency; 18489a0bf528SMauro Carvalho Chehab } 18499a0bf528SMauro Carvalho Chehab 1850cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 18519a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 18529a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1853cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000); 1854cd7a67a4SMauro Carvalho Chehab status = set_qam(state, i_freqk_hz, offsetk_hz); 18559a0bf528SMauro Carvalho Chehab if (status < 0) 18569a0bf528SMauro Carvalho Chehab goto error; 1857cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED; 18589a0bf528SMauro Carvalho Chehab break; 18599a0bf528SMauro Carvalho Chehab case OM_DVBT: 1860cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000); 1861cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 18629a0bf528SMauro Carvalho Chehab if (status < 0) 18639a0bf528SMauro Carvalho Chehab goto error; 1864cd7a67a4SMauro Carvalho Chehab status = set_dvbt(state, i_freqk_hz, offsetk_hz); 18659a0bf528SMauro Carvalho Chehab if (status < 0) 18669a0bf528SMauro Carvalho Chehab goto error; 1867cd7a67a4SMauro Carvalho Chehab status = dvbt_start(state); 18689a0bf528SMauro Carvalho Chehab if (status < 0) 18699a0bf528SMauro Carvalho Chehab goto error; 1870cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED; 18719a0bf528SMauro Carvalho Chehab break; 18729a0bf528SMauro Carvalho Chehab default: 18739a0bf528SMauro Carvalho Chehab break; 18749a0bf528SMauro Carvalho Chehab } 18759a0bf528SMauro Carvalho Chehab error: 18769a0bf528SMauro Carvalho Chehab if (status < 0) 18773a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 18789a0bf528SMauro Carvalho Chehab return status; 18799a0bf528SMauro Carvalho Chehab } 18809a0bf528SMauro Carvalho Chehab 1881cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state) 18829a0bf528SMauro Carvalho Chehab { 18839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 18849a0bf528SMauro Carvalho Chehab 1885cd7a67a4SMauro Carvalho Chehab mpegts_stop(state); 18869a0bf528SMauro Carvalho Chehab return 0; 18879a0bf528SMauro Carvalho Chehab } 18889a0bf528SMauro Carvalho Chehab 1889cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status) 18909a0bf528SMauro Carvalho Chehab { 18919a0bf528SMauro Carvalho Chehab int status = -EINVAL; 18929a0bf528SMauro Carvalho Chehab 18939a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 18949a0bf528SMauro Carvalho Chehab 1895cd7a67a4SMauro Carvalho Chehab if (p_lock_status == NULL) 18969a0bf528SMauro Carvalho Chehab goto error; 18979a0bf528SMauro Carvalho Chehab 1898cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 18999a0bf528SMauro Carvalho Chehab 19009a0bf528SMauro Carvalho Chehab /* define the SCU command code */ 1901cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 19029a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 19039a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 19049a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1905cd7a67a4SMauro Carvalho Chehab status = get_qam_lock_status(state, p_lock_status); 19069a0bf528SMauro Carvalho Chehab break; 19079a0bf528SMauro Carvalho Chehab case OM_DVBT: 1908cd7a67a4SMauro Carvalho Chehab status = get_dvbt_lock_status(state, p_lock_status); 19099a0bf528SMauro Carvalho Chehab break; 19109a0bf528SMauro Carvalho Chehab default: 19119a0bf528SMauro Carvalho Chehab break; 19129a0bf528SMauro Carvalho Chehab } 19139a0bf528SMauro Carvalho Chehab error: 19149a0bf528SMauro Carvalho Chehab if (status < 0) 19153a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 19169a0bf528SMauro Carvalho Chehab return status; 19179a0bf528SMauro Carvalho Chehab } 19189a0bf528SMauro Carvalho Chehab 1919cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state) 19209a0bf528SMauro Carvalho Chehab { 19219a0bf528SMauro Carvalho Chehab int status; 19229a0bf528SMauro Carvalho Chehab 1923cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0; 19249a0bf528SMauro Carvalho Chehab 19259a0bf528SMauro Carvalho Chehab /* Allow OC to sync again */ 1926cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 19279a0bf528SMauro Carvalho Chehab if (status < 0) 19289a0bf528SMauro Carvalho Chehab goto error; 1929cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; 1930cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 19319a0bf528SMauro Carvalho Chehab if (status < 0) 19329a0bf528SMauro Carvalho Chehab goto error; 19339a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_UNLOCK__A, 1); 19349a0bf528SMauro Carvalho Chehab error: 19359a0bf528SMauro Carvalho Chehab if (status < 0) 19363a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 19379a0bf528SMauro Carvalho Chehab return status; 19389a0bf528SMauro Carvalho Chehab } 19399a0bf528SMauro Carvalho Chehab 1940cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state) 19419a0bf528SMauro Carvalho Chehab { 19429a0bf528SMauro Carvalho Chehab int status; 19439a0bf528SMauro Carvalho Chehab 19449a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 19459a0bf528SMauro Carvalho Chehab 19469a0bf528SMauro Carvalho Chehab /* Rate integration settings */ 19479a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000); 19489a0bf528SMauro Carvalho Chehab if (status < 0) 19499a0bf528SMauro Carvalho Chehab goto error; 19509a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C); 19519a0bf528SMauro Carvalho Chehab if (status < 0) 19529a0bf528SMauro Carvalho Chehab goto error; 19539a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A); 19549a0bf528SMauro Carvalho Chehab if (status < 0) 19559a0bf528SMauro Carvalho Chehab goto error; 19569a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008); 19579a0bf528SMauro Carvalho Chehab if (status < 0) 19589a0bf528SMauro Carvalho Chehab goto error; 19599a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006); 19609a0bf528SMauro Carvalho Chehab if (status < 0) 19619a0bf528SMauro Carvalho Chehab goto error; 19629a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680); 19639a0bf528SMauro Carvalho Chehab if (status < 0) 19649a0bf528SMauro Carvalho Chehab goto error; 19659a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080); 19669a0bf528SMauro Carvalho Chehab if (status < 0) 19679a0bf528SMauro Carvalho Chehab goto error; 19689a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4); 19699a0bf528SMauro Carvalho Chehab if (status < 0) 19709a0bf528SMauro Carvalho Chehab goto error; 19719a0bf528SMauro Carvalho Chehab 19729a0bf528SMauro Carvalho Chehab /* Additional configuration */ 19739a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_OCR_INVERT__A, 0); 19749a0bf528SMauro Carvalho Chehab if (status < 0) 19759a0bf528SMauro Carvalho Chehab goto error; 19769a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_LWM__A, 2); 19779a0bf528SMauro Carvalho Chehab if (status < 0) 19789a0bf528SMauro Carvalho Chehab goto error; 19799a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_HWM__A, 12); 19809a0bf528SMauro Carvalho Chehab error: 19819a0bf528SMauro Carvalho Chehab if (status < 0) 19823a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 19839a0bf528SMauro Carvalho Chehab 19849a0bf528SMauro Carvalho Chehab return status; 19859a0bf528SMauro Carvalho Chehab } 19869a0bf528SMauro Carvalho Chehab 1987cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state, 1988cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 19899a0bf528SMauro Carvalho Chehab { 19909a0bf528SMauro Carvalho Chehab int status; 19919a0bf528SMauro Carvalho Chehab 1992cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */ 1993cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */ 1994cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */ 1995cd7a67a4SMauro Carvalho Chehab u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */ 1996cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */ 1997cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */ 1998cd7a67a4SMauro Carvalho Chehab u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */ 1999cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_mode = 0; 2000cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_int_upd_rate = 0; 2001cd7a67a4SMauro Carvalho Chehab u32 max_bit_rate = 0; 2002cd7a67a4SMauro Carvalho Chehab bool static_clk = false; 20039a0bf528SMauro Carvalho Chehab 20049a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 20059a0bf528SMauro Carvalho Chehab 20069a0bf528SMauro Carvalho Chehab /* Check insertion of the Reed-Solomon parity bytes */ 2007cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode); 20089a0bf528SMauro Carvalho Chehab if (status < 0) 20099a0bf528SMauro Carvalho Chehab goto error; 2010cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode); 20119a0bf528SMauro Carvalho Chehab if (status < 0) 20129a0bf528SMauro Carvalho Chehab goto error; 2013cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M); 2014cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); 20155a7f7b79SMauro Carvalho Chehab if (state->m_insert_rs_byte) { 20169a0bf528SMauro Carvalho Chehab /* enable parity symbol forward */ 2017cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M; 20189a0bf528SMauro Carvalho Chehab /* MVAL disable during parity bytes */ 2019cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; 20209a0bf528SMauro Carvalho Chehab /* TS burst length to 204 */ 2021cd7a67a4SMauro Carvalho Chehab fec_oc_dto_burst_len = 204; 20229a0bf528SMauro Carvalho Chehab } 20239a0bf528SMauro Carvalho Chehab 202439c1cb2bSJonathan McCrohan /* Check serial or parallel output */ 2025cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); 20265a7f7b79SMauro Carvalho Chehab if (!state->m_enable_parallel) { 20279a0bf528SMauro Carvalho Chehab /* MPEG data output is serial -> set ipr_mode[0] */ 2028cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; 20299a0bf528SMauro Carvalho Chehab } 20309a0bf528SMauro Carvalho Chehab 2031cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 20329a0bf528SMauro Carvalho Chehab case OM_DVBT: 2033cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbt_bitrate; 2034cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 3; 2035cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xC00000; 2036cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbt_static_clk; 20379a0bf528SMauro Carvalho Chehab break; 20389a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: /* fallthrough */ 20399a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 2040cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 0x0004; 2041cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */ 2042cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbc_bitrate; 2043cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbc_static_clk; 20449a0bf528SMauro Carvalho Chehab break; 20459a0bf528SMauro Carvalho Chehab default: 20469a0bf528SMauro Carvalho Chehab status = -EINVAL; 20479a0bf528SMauro Carvalho Chehab } /* switch (standard) */ 20489a0bf528SMauro Carvalho Chehab if (status < 0) 20499a0bf528SMauro Carvalho Chehab goto error; 20509a0bf528SMauro Carvalho Chehab 20519a0bf528SMauro Carvalho Chehab /* Configure DTO's */ 2052cd7a67a4SMauro Carvalho Chehab if (static_clk) { 2053cd7a67a4SMauro Carvalho Chehab u32 bit_rate = 0; 20549a0bf528SMauro Carvalho Chehab 20559a0bf528SMauro Carvalho Chehab /* Rational DTO for MCLK source (static MCLK rate), 20569a0bf528SMauro Carvalho Chehab Dynamic DTO for optimal grouping 20579a0bf528SMauro Carvalho Chehab (avoid intra-packet gaps), 20589a0bf528SMauro Carvalho Chehab DTO offset enable to sync TS burst with MSTRT */ 2059cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M | 20609a0bf528SMauro Carvalho Chehab FEC_OC_DTO_MODE_OFFSET_ENABLE__M); 2061cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M | 20629a0bf528SMauro Carvalho Chehab FEC_OC_FCT_MODE_VIRT_ENA__M); 20639a0bf528SMauro Carvalho Chehab 20649a0bf528SMauro Carvalho Chehab /* Check user defined bitrate */ 2065cd7a67a4SMauro Carvalho Chehab bit_rate = max_bit_rate; 2066cd7a67a4SMauro Carvalho Chehab if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */ 2067cd7a67a4SMauro Carvalho Chehab bit_rate = 75900000UL; 20689a0bf528SMauro Carvalho Chehab } 20699a0bf528SMauro Carvalho Chehab /* Rational DTO period: 20709a0bf528SMauro Carvalho Chehab dto_period = (Fsys / bitrate) - 2 20719a0bf528SMauro Carvalho Chehab 2072cd7a67a4SMauro Carvalho Chehab result should be floored, 20739a0bf528SMauro Carvalho Chehab to make sure >= requested bitrate 20749a0bf528SMauro Carvalho Chehab */ 2075cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = (u16) (((state->m_sys_clock_freq) 2076cd7a67a4SMauro Carvalho Chehab * 1000) / bit_rate); 2077cd7a67a4SMauro Carvalho Chehab if (fec_oc_dto_period <= 2) 2078cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = 0; 20799a0bf528SMauro Carvalho Chehab else 2080cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period -= 2; 2081cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 8; 20829a0bf528SMauro Carvalho Chehab } else { 2083cd7a67a4SMauro Carvalho Chehab /* (commonAttr->static_clk == false) => dynamic mode */ 2084cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M; 2085cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE; 2086cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 5; 20879a0bf528SMauro Carvalho Chehab } 20889a0bf528SMauro Carvalho Chehab 20899a0bf528SMauro Carvalho Chehab /* Write appropriate registers with requested configuration */ 2090cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len); 20919a0bf528SMauro Carvalho Chehab if (status < 0) 20929a0bf528SMauro Carvalho Chehab goto error; 2093cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period); 20949a0bf528SMauro Carvalho Chehab if (status < 0) 20959a0bf528SMauro Carvalho Chehab goto error; 2096cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode); 20979a0bf528SMauro Carvalho Chehab if (status < 0) 20989a0bf528SMauro Carvalho Chehab goto error; 2099cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode); 21009a0bf528SMauro Carvalho Chehab if (status < 0) 21019a0bf528SMauro Carvalho Chehab goto error; 2102cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode); 21039a0bf528SMauro Carvalho Chehab if (status < 0) 21049a0bf528SMauro Carvalho Chehab goto error; 2105cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode); 21069a0bf528SMauro Carvalho Chehab if (status < 0) 21079a0bf528SMauro Carvalho Chehab goto error; 21089a0bf528SMauro Carvalho Chehab 21099a0bf528SMauro Carvalho Chehab /* Rate integration settings */ 2110cd7a67a4SMauro Carvalho Chehab status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate); 21119a0bf528SMauro Carvalho Chehab if (status < 0) 21129a0bf528SMauro Carvalho Chehab goto error; 2113ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, 2114ab5060cdSMauro Carvalho Chehab fec_oc_tmd_int_upd_rate); 21159a0bf528SMauro Carvalho Chehab if (status < 0) 21169a0bf528SMauro Carvalho Chehab goto error; 2117cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode); 21189a0bf528SMauro Carvalho Chehab error: 21199a0bf528SMauro Carvalho Chehab if (status < 0) 21203a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 21219a0bf528SMauro Carvalho Chehab return status; 21229a0bf528SMauro Carvalho Chehab } 21239a0bf528SMauro Carvalho Chehab 2124cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state) 21259a0bf528SMauro Carvalho Chehab { 2126cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_invert = 0; 21279a0bf528SMauro Carvalho Chehab 21289a0bf528SMauro Carvalho Chehab /* Data mask for the output data byte */ 2129cd7a67a4SMauro Carvalho Chehab u16 invert_data_mask = 21309a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M | 21319a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M | 21329a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M | 21339a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M; 21349a0bf528SMauro Carvalho Chehab 21359a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 21369a0bf528SMauro Carvalho Chehab 21379a0bf528SMauro Carvalho Chehab /* Control selective inversion of output bits */ 2138cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(invert_data_mask)); 21395a7f7b79SMauro Carvalho Chehab if (state->m_invert_data) 2140cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= invert_data_mask; 2141cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M)); 21425a7f7b79SMauro Carvalho Chehab if (state->m_invert_err) 2143cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M; 2144cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); 21455a7f7b79SMauro Carvalho Chehab if (state->m_invert_str) 2146cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M; 2147cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); 21485a7f7b79SMauro Carvalho Chehab if (state->m_invert_val) 2149cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M; 2150cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); 21515a7f7b79SMauro Carvalho Chehab if (state->m_invert_clk) 2152cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M; 21539a0bf528SMauro Carvalho Chehab 2154cd7a67a4SMauro Carvalho Chehab return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert); 21559a0bf528SMauro Carvalho Chehab } 21569a0bf528SMauro Carvalho Chehab 21579a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000 21589a0bf528SMauro Carvalho Chehab 2159cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state, 2160cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv) 21619a0bf528SMauro Carvalho Chehab { 21629a0bf528SMauro Carvalho Chehab int status = -EINVAL; 21639a0bf528SMauro Carvalho Chehab u16 data = 0; 2164cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_if_agc_settings; 21659a0bf528SMauro Carvalho Chehab 21669a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 21679a0bf528SMauro Carvalho Chehab 2168cd7a67a4SMauro Carvalho Chehab if (p_agc_cfg == NULL) 21699a0bf528SMauro Carvalho Chehab goto error; 21709a0bf528SMauro Carvalho Chehab 2171cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) { 21729a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO: 21739a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */ 21749a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 21759a0bf528SMauro Carvalho Chehab if (status < 0) 21769a0bf528SMauro Carvalho Chehab goto error; 21779a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 21789a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 21799a0bf528SMauro Carvalho Chehab if (status < 0) 21809a0bf528SMauro Carvalho Chehab goto error; 21819a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 21829a0bf528SMauro Carvalho Chehab if (status < 0) 21839a0bf528SMauro Carvalho Chehab goto error; 21849a0bf528SMauro Carvalho Chehab 21859a0bf528SMauro Carvalho Chehab /* Enable SCU RF AGC loop */ 21869a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 21879a0bf528SMauro Carvalho Chehab 21889a0bf528SMauro Carvalho Chehab /* Polarity */ 2189cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol) 21909a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21919a0bf528SMauro Carvalho Chehab else 21929a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 21949a0bf528SMauro Carvalho Chehab if (status < 0) 21959a0bf528SMauro Carvalho Chehab goto error; 21969a0bf528SMauro Carvalho Chehab 21979a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */ 21989a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 21999a0bf528SMauro Carvalho Chehab if (status < 0) 22009a0bf528SMauro Carvalho Chehab goto error; 22019a0bf528SMauro Carvalho Chehab 22029a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M; 2203cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed << 22049a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_RAGC_RED__B) 22059a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_RAGC_RED__M); 22069a0bf528SMauro Carvalho Chehab 22079a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 22089a0bf528SMauro Carvalho Chehab if (status < 0) 22099a0bf528SMauro Carvalho Chehab goto error; 22109a0bf528SMauro Carvalho Chehab 2211cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state)) 2212cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_dvbt_if_agc_cfg; 2213cd7a67a4SMauro Carvalho Chehab else if (is_qam(state)) 2214cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_qam_if_agc_cfg; 22159a0bf528SMauro Carvalho Chehab else 2216cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_atv_if_agc_cfg; 2217cd7a67a4SMauro Carvalho Chehab if (p_if_agc_settings == NULL) { 22189a0bf528SMauro Carvalho Chehab status = -EINVAL; 22199a0bf528SMauro Carvalho Chehab goto error; 22209a0bf528SMauro Carvalho Chehab } 22219a0bf528SMauro Carvalho Chehab 22229a0bf528SMauro Carvalho Chehab /* Set TOP, only if IF-AGC is in AUTO mode */ 222389fffac8SMauro Carvalho Chehab if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) { 2224ab5060cdSMauro Carvalho Chehab status = write16(state, 2225ab5060cdSMauro Carvalho Chehab SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2226ab5060cdSMauro Carvalho Chehab p_agc_cfg->top); 22279a0bf528SMauro Carvalho Chehab if (status < 0) 22289a0bf528SMauro Carvalho Chehab goto error; 222989fffac8SMauro Carvalho Chehab } 22309a0bf528SMauro Carvalho Chehab 22319a0bf528SMauro Carvalho Chehab /* Cut-Off current */ 2232ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 2233ab5060cdSMauro Carvalho Chehab p_agc_cfg->cut_off_current); 22349a0bf528SMauro Carvalho Chehab if (status < 0) 22359a0bf528SMauro Carvalho Chehab goto error; 22369a0bf528SMauro Carvalho Chehab 22379a0bf528SMauro Carvalho Chehab /* Max. output level */ 2238ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_MAX__A, 2239ab5060cdSMauro Carvalho Chehab p_agc_cfg->max_output_level); 22409a0bf528SMauro Carvalho Chehab if (status < 0) 22419a0bf528SMauro Carvalho Chehab goto error; 22429a0bf528SMauro Carvalho Chehab 22439a0bf528SMauro Carvalho Chehab break; 22449a0bf528SMauro Carvalho Chehab 22459a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER: 22469a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */ 22479a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 22489a0bf528SMauro Carvalho Chehab if (status < 0) 22499a0bf528SMauro Carvalho Chehab goto error; 22509a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22519a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 22529a0bf528SMauro Carvalho Chehab if (status < 0) 22539a0bf528SMauro Carvalho Chehab goto error; 22549a0bf528SMauro Carvalho Chehab 22559a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */ 22569a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22579a0bf528SMauro Carvalho Chehab if (status < 0) 22589a0bf528SMauro Carvalho Chehab goto error; 22599a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 2260cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol) 22619a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22629a0bf528SMauro Carvalho Chehab else 22639a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22659a0bf528SMauro Carvalho Chehab if (status < 0) 22669a0bf528SMauro Carvalho Chehab goto error; 22679a0bf528SMauro Carvalho Chehab 22689a0bf528SMauro Carvalho Chehab /* SCU c.o.c. to 0, enabling full control range */ 22699a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0); 22709a0bf528SMauro Carvalho Chehab if (status < 0) 22719a0bf528SMauro Carvalho Chehab goto error; 22729a0bf528SMauro Carvalho Chehab 22739a0bf528SMauro Carvalho Chehab /* Write value to output pin */ 2274ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 2275ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level); 22769a0bf528SMauro Carvalho Chehab if (status < 0) 22779a0bf528SMauro Carvalho Chehab goto error; 22789a0bf528SMauro Carvalho Chehab break; 22799a0bf528SMauro Carvalho Chehab 22809a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF: 22819a0bf528SMauro Carvalho Chehab /* Disable RF AGC DAC */ 22829a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 22839a0bf528SMauro Carvalho Chehab if (status < 0) 22849a0bf528SMauro Carvalho Chehab goto error; 22859a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22869a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 22879a0bf528SMauro Carvalho Chehab if (status < 0) 22889a0bf528SMauro Carvalho Chehab goto error; 22899a0bf528SMauro Carvalho Chehab 22909a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */ 22919a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22929a0bf528SMauro Carvalho Chehab if (status < 0) 22939a0bf528SMauro Carvalho Chehab goto error; 22949a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 22959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22969a0bf528SMauro Carvalho Chehab if (status < 0) 22979a0bf528SMauro Carvalho Chehab goto error; 22989a0bf528SMauro Carvalho Chehab break; 22999a0bf528SMauro Carvalho Chehab 23009a0bf528SMauro Carvalho Chehab default: 23019a0bf528SMauro Carvalho Chehab status = -EINVAL; 23029a0bf528SMauro Carvalho Chehab 23039a0bf528SMauro Carvalho Chehab } 23049a0bf528SMauro Carvalho Chehab error: 23059a0bf528SMauro Carvalho Chehab if (status < 0) 23063a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 23079a0bf528SMauro Carvalho Chehab return status; 23089a0bf528SMauro Carvalho Chehab } 23099a0bf528SMauro Carvalho Chehab 23109a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000 23119a0bf528SMauro Carvalho Chehab 2312cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state, 2313cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv) 23149a0bf528SMauro Carvalho Chehab { 23159a0bf528SMauro Carvalho Chehab u16 data = 0; 23169a0bf528SMauro Carvalho Chehab int status = 0; 2317cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_rf_agc_settings; 23189a0bf528SMauro Carvalho Chehab 23199a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 23209a0bf528SMauro Carvalho Chehab 2321cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) { 23229a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO: 23239a0bf528SMauro Carvalho Chehab 23249a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */ 23259a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 23269a0bf528SMauro Carvalho Chehab if (status < 0) 23279a0bf528SMauro Carvalho Chehab goto error; 23289a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23299a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 23309a0bf528SMauro Carvalho Chehab if (status < 0) 23319a0bf528SMauro Carvalho Chehab goto error; 23329a0bf528SMauro Carvalho Chehab 23339a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23349a0bf528SMauro Carvalho Chehab if (status < 0) 23359a0bf528SMauro Carvalho Chehab goto error; 23369a0bf528SMauro Carvalho Chehab 23379a0bf528SMauro Carvalho Chehab /* Enable SCU IF AGC loop */ 23389a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23399a0bf528SMauro Carvalho Chehab 23409a0bf528SMauro Carvalho Chehab /* Polarity */ 2341cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol) 23429a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23439a0bf528SMauro Carvalho Chehab else 23449a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23469a0bf528SMauro Carvalho Chehab if (status < 0) 23479a0bf528SMauro Carvalho Chehab goto error; 23489a0bf528SMauro Carvalho Chehab 23499a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */ 23509a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 23519a0bf528SMauro Carvalho Chehab if (status < 0) 23529a0bf528SMauro Carvalho Chehab goto error; 23539a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M; 2354cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed << 23559a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_IAGC_RED__B) 23569a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_IAGC_RED__M); 23579a0bf528SMauro Carvalho Chehab 23589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 23599a0bf528SMauro Carvalho Chehab if (status < 0) 23609a0bf528SMauro Carvalho Chehab goto error; 23619a0bf528SMauro Carvalho Chehab 2362cd7a67a4SMauro Carvalho Chehab if (is_qam(state)) 2363cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_qam_rf_agc_cfg; 23649a0bf528SMauro Carvalho Chehab else 2365cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_atv_rf_agc_cfg; 2366cd7a67a4SMauro Carvalho Chehab if (p_rf_agc_settings == NULL) 23679a0bf528SMauro Carvalho Chehab return -1; 23689a0bf528SMauro Carvalho Chehab /* Restore TOP */ 2369ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2370ab5060cdSMauro Carvalho Chehab p_rf_agc_settings->top); 23719a0bf528SMauro Carvalho Chehab if (status < 0) 23729a0bf528SMauro Carvalho Chehab goto error; 23739a0bf528SMauro Carvalho Chehab break; 23749a0bf528SMauro Carvalho Chehab 23759a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER: 23769a0bf528SMauro Carvalho Chehab 23779a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */ 23789a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 23799a0bf528SMauro Carvalho Chehab if (status < 0) 23809a0bf528SMauro Carvalho Chehab goto error; 23819a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23829a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 23839a0bf528SMauro Carvalho Chehab if (status < 0) 23849a0bf528SMauro Carvalho Chehab goto error; 23859a0bf528SMauro Carvalho Chehab 23869a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23879a0bf528SMauro Carvalho Chehab if (status < 0) 23889a0bf528SMauro Carvalho Chehab goto error; 23899a0bf528SMauro Carvalho Chehab 23909a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */ 23919a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23929a0bf528SMauro Carvalho Chehab 23939a0bf528SMauro Carvalho Chehab /* Polarity */ 2394cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol) 23959a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23969a0bf528SMauro Carvalho Chehab else 23979a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23999a0bf528SMauro Carvalho Chehab if (status < 0) 24009a0bf528SMauro Carvalho Chehab goto error; 24019a0bf528SMauro Carvalho Chehab 24029a0bf528SMauro Carvalho Chehab /* Write value to output pin */ 2403ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2404ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level); 24059a0bf528SMauro Carvalho Chehab if (status < 0) 24069a0bf528SMauro Carvalho Chehab goto error; 24079a0bf528SMauro Carvalho Chehab break; 24089a0bf528SMauro Carvalho Chehab 24099a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF: 24109a0bf528SMauro Carvalho Chehab 24119a0bf528SMauro Carvalho Chehab /* Disable If AGC DAC */ 24129a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 24139a0bf528SMauro Carvalho Chehab if (status < 0) 24149a0bf528SMauro Carvalho Chehab goto error; 24159a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 24169a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 24179a0bf528SMauro Carvalho Chehab if (status < 0) 24189a0bf528SMauro Carvalho Chehab goto error; 24199a0bf528SMauro Carvalho Chehab 24209a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */ 24219a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 24229a0bf528SMauro Carvalho Chehab if (status < 0) 24239a0bf528SMauro Carvalho Chehab goto error; 24249a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 24259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 24269a0bf528SMauro Carvalho Chehab if (status < 0) 24279a0bf528SMauro Carvalho Chehab goto error; 24289a0bf528SMauro Carvalho Chehab break; 2429cd7a67a4SMauro Carvalho Chehab } /* switch (agcSettingsIf->ctrl_mode) */ 24309a0bf528SMauro Carvalho Chehab 24319a0bf528SMauro Carvalho Chehab /* always set the top to support 24329a0bf528SMauro Carvalho Chehab configurations without if-loop */ 2433cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top); 24349a0bf528SMauro Carvalho Chehab error: 24359a0bf528SMauro Carvalho Chehab if (status < 0) 24363a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 24379a0bf528SMauro Carvalho Chehab return status; 24389a0bf528SMauro Carvalho Chehab } 24399a0bf528SMauro Carvalho Chehab 2440cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state, 2441cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise) 24429a0bf528SMauro Carvalho Chehab { 24439a0bf528SMauro Carvalho Chehab int status = 0; 2444cd7a67a4SMauro Carvalho Chehab u16 qam_sl_err_power = 0; /* accum. error between 24459a0bf528SMauro Carvalho Chehab raw and sliced symbols */ 2446cd7a67a4SMauro Carvalho Chehab u32 qam_sl_sig_power = 0; /* used for MER, depends of 24479a0bf528SMauro Carvalho Chehab QAM modulation */ 2448cd7a67a4SMauro Carvalho Chehab u32 qam_sl_mer = 0; /* QAM MER */ 24499a0bf528SMauro Carvalho Chehab 24509a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 24519a0bf528SMauro Carvalho Chehab 24529a0bf528SMauro Carvalho Chehab /* MER calculation */ 24539a0bf528SMauro Carvalho Chehab 24549a0bf528SMauro Carvalho Chehab /* get the register value needed for MER */ 2455cd7a67a4SMauro Carvalho Chehab status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power); 24569a0bf528SMauro Carvalho Chehab if (status < 0) { 24573a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 24589a0bf528SMauro Carvalho Chehab return -EINVAL; 24599a0bf528SMauro Carvalho Chehab } 24609a0bf528SMauro Carvalho Chehab 24619a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 24629a0bf528SMauro Carvalho Chehab case QAM_16: 2463cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; 24649a0bf528SMauro Carvalho Chehab break; 24659a0bf528SMauro Carvalho Chehab case QAM_32: 2466cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; 24679a0bf528SMauro Carvalho Chehab break; 24689a0bf528SMauro Carvalho Chehab case QAM_64: 2469cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; 24709a0bf528SMauro Carvalho Chehab break; 24719a0bf528SMauro Carvalho Chehab case QAM_128: 2472cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; 24739a0bf528SMauro Carvalho Chehab break; 24749a0bf528SMauro Carvalho Chehab default: 24759a0bf528SMauro Carvalho Chehab case QAM_256: 2476cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; 24779a0bf528SMauro Carvalho Chehab break; 24789a0bf528SMauro Carvalho Chehab } 24799a0bf528SMauro Carvalho Chehab 2480cd7a67a4SMauro Carvalho Chehab if (qam_sl_err_power > 0) { 2481cd7a67a4SMauro Carvalho Chehab qam_sl_mer = log10times100(qam_sl_sig_power) - 2482cd7a67a4SMauro Carvalho Chehab log10times100((u32) qam_sl_err_power); 24839a0bf528SMauro Carvalho Chehab } 2484cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = qam_sl_mer; 24859a0bf528SMauro Carvalho Chehab 24869a0bf528SMauro Carvalho Chehab return status; 24879a0bf528SMauro Carvalho Chehab } 24889a0bf528SMauro Carvalho Chehab 2489cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state, 2490cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise) 24919a0bf528SMauro Carvalho Chehab { 24929a0bf528SMauro Carvalho Chehab int status; 2493cd7a67a4SMauro Carvalho Chehab u16 reg_data = 0; 2494cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_i = 0; 2495cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_q = 0; 2496cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_sqr_err_exp = 0; 2497cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_tps_pwr_ofs = 0; 2498cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_req_smb_cnt = 0; 2499cd7a67a4SMauro Carvalho Chehab u32 tps_cnt = 0; 2500cd7a67a4SMauro Carvalho Chehab u32 sqr_err_iq = 0; 25019a0bf528SMauro Carvalho Chehab u32 a = 0; 25029a0bf528SMauro Carvalho Chehab u32 b = 0; 25039a0bf528SMauro Carvalho Chehab u32 c = 0; 2504cd7a67a4SMauro Carvalho Chehab u32 i_mer = 0; 2505cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0; 25069a0bf528SMauro Carvalho Chehab 25079a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 25089a0bf528SMauro Carvalho Chehab 2509ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, 2510ab5060cdSMauro Carvalho Chehab &eq_reg_td_tps_pwr_ofs); 25119a0bf528SMauro Carvalho Chehab if (status < 0) 25129a0bf528SMauro Carvalho Chehab goto error; 2513ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, 2514ab5060cdSMauro Carvalho Chehab &eq_reg_td_req_smb_cnt); 25159a0bf528SMauro Carvalho Chehab if (status < 0) 25169a0bf528SMauro Carvalho Chehab goto error; 2517ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, 2518ab5060cdSMauro Carvalho Chehab &eq_reg_td_sqr_err_exp); 25199a0bf528SMauro Carvalho Chehab if (status < 0) 25209a0bf528SMauro Carvalho Chehab goto error; 2521ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, 2522ab5060cdSMauro Carvalho Chehab ®_data); 25239a0bf528SMauro Carvalho Chehab if (status < 0) 25249a0bf528SMauro Carvalho Chehab goto error; 25259a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_I operational range */ 2526cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i = (u32) reg_data; 2527cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) && 2528cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_i < 0x00000FFFUL)) { 2529cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i += 0x00010000UL; 25309a0bf528SMauro Carvalho Chehab } 2531cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data); 25329a0bf528SMauro Carvalho Chehab if (status < 0) 25339a0bf528SMauro Carvalho Chehab goto error; 25349a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_Q operational range */ 2535cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q = (u32) reg_data; 2536cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) && 2537cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_q < 0x00000FFFUL)) 2538cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q += 0x00010000UL; 25399a0bf528SMauro Carvalho Chehab 2540ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, 2541ab5060cdSMauro Carvalho Chehab &transmission_params); 25429a0bf528SMauro Carvalho Chehab if (status < 0) 25439a0bf528SMauro Carvalho Chehab goto error; 25449a0bf528SMauro Carvalho Chehab 25459a0bf528SMauro Carvalho Chehab /* Check input data for MER */ 25469a0bf528SMauro Carvalho Chehab 25479a0bf528SMauro Carvalho Chehab /* MER calculation (in 0.1 dB) without math.h */ 2548cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0)) 2549cd7a67a4SMauro Carvalho Chehab i_mer = 0; 2550cd7a67a4SMauro Carvalho Chehab else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) { 25519a0bf528SMauro Carvalho Chehab /* No error at all, this must be the HW reset value 25529a0bf528SMauro Carvalho Chehab * Apparently no first measurement yet 25539a0bf528SMauro Carvalho Chehab * Set MER to 0.0 */ 2554cd7a67a4SMauro Carvalho Chehab i_mer = 0; 25559a0bf528SMauro Carvalho Chehab } else { 2556cd7a67a4SMauro Carvalho Chehab sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) << 2557cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_exp; 2558cd7a67a4SMauro Carvalho Chehab if ((transmission_params & 25599a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_PARAM_MODE__M) 25609a0bf528SMauro Carvalho Chehab == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K) 2561cd7a67a4SMauro Carvalho Chehab tps_cnt = 17; 25629a0bf528SMauro Carvalho Chehab else 2563cd7a67a4SMauro Carvalho Chehab tps_cnt = 68; 25649a0bf528SMauro Carvalho Chehab 25659a0bf528SMauro Carvalho Chehab /* IMER = 100 * log10 (x) 2566cd7a67a4SMauro Carvalho Chehab where x = (eq_reg_td_tps_pwr_ofs^2 * 2567cd7a67a4SMauro Carvalho Chehab eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq 25689a0bf528SMauro Carvalho Chehab 25699a0bf528SMauro Carvalho Chehab => IMER = a + b -c 2570cd7a67a4SMauro Carvalho Chehab where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2) 2571cd7a67a4SMauro Carvalho Chehab b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt) 2572cd7a67a4SMauro Carvalho Chehab c = 100 * log10 (sqr_err_iq) 25739a0bf528SMauro Carvalho Chehab */ 25749a0bf528SMauro Carvalho Chehab 25759a0bf528SMauro Carvalho Chehab /* log(x) x = 9bits * 9bits->18 bits */ 2576cd7a67a4SMauro Carvalho Chehab a = log10times100(eq_reg_td_tps_pwr_ofs * 2577cd7a67a4SMauro Carvalho Chehab eq_reg_td_tps_pwr_ofs); 25789a0bf528SMauro Carvalho Chehab /* log(x) x = 16bits * 7bits->23 bits */ 2579cd7a67a4SMauro Carvalho Chehab b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt); 25809a0bf528SMauro Carvalho Chehab /* log(x) x = (16bits + 16bits) << 15 ->32 bits */ 2581cd7a67a4SMauro Carvalho Chehab c = log10times100(sqr_err_iq); 25829a0bf528SMauro Carvalho Chehab 2583cd7a67a4SMauro Carvalho Chehab i_mer = a + b - c; 25849a0bf528SMauro Carvalho Chehab } 2585cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = i_mer; 25869a0bf528SMauro Carvalho Chehab 25879a0bf528SMauro Carvalho Chehab error: 25889a0bf528SMauro Carvalho Chehab if (status < 0) 25893a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 25909a0bf528SMauro Carvalho Chehab return status; 25919a0bf528SMauro Carvalho Chehab } 25929a0bf528SMauro Carvalho Chehab 2593cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) 25949a0bf528SMauro Carvalho Chehab { 25959a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 25969a0bf528SMauro Carvalho Chehab 2597cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = 0; 2598cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 25999a0bf528SMauro Carvalho Chehab case OM_DVBT: 2600cd7a67a4SMauro Carvalho Chehab return get_dvbt_signal_to_noise(state, p_signal_to_noise); 26019a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 26029a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 2603cd7a67a4SMauro Carvalho Chehab return get_qam_signal_to_noise(state, p_signal_to_noise); 26049a0bf528SMauro Carvalho Chehab default: 26059a0bf528SMauro Carvalho Chehab break; 26069a0bf528SMauro Carvalho Chehab } 26079a0bf528SMauro Carvalho Chehab return 0; 26089a0bf528SMauro Carvalho Chehab } 26099a0bf528SMauro Carvalho Chehab 26109a0bf528SMauro Carvalho Chehab #if 0 2611cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) 26129a0bf528SMauro Carvalho Chehab { 26139a0bf528SMauro Carvalho Chehab /* SNR Values for quasi errorfree reception rom Nordig 2.2 */ 26149a0bf528SMauro Carvalho Chehab int status = 0; 26159a0bf528SMauro Carvalho Chehab 26169a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 26179a0bf528SMauro Carvalho Chehab 26189a0bf528SMauro Carvalho Chehab static s32 QE_SN[] = { 26199a0bf528SMauro Carvalho Chehab 51, /* QPSK 1/2 */ 26209a0bf528SMauro Carvalho Chehab 69, /* QPSK 2/3 */ 26219a0bf528SMauro Carvalho Chehab 79, /* QPSK 3/4 */ 26229a0bf528SMauro Carvalho Chehab 89, /* QPSK 5/6 */ 26239a0bf528SMauro Carvalho Chehab 97, /* QPSK 7/8 */ 26249a0bf528SMauro Carvalho Chehab 108, /* 16-QAM 1/2 */ 26259a0bf528SMauro Carvalho Chehab 131, /* 16-QAM 2/3 */ 26269a0bf528SMauro Carvalho Chehab 146, /* 16-QAM 3/4 */ 26279a0bf528SMauro Carvalho Chehab 156, /* 16-QAM 5/6 */ 26289a0bf528SMauro Carvalho Chehab 160, /* 16-QAM 7/8 */ 26299a0bf528SMauro Carvalho Chehab 165, /* 64-QAM 1/2 */ 26309a0bf528SMauro Carvalho Chehab 187, /* 64-QAM 2/3 */ 26319a0bf528SMauro Carvalho Chehab 202, /* 64-QAM 3/4 */ 26329a0bf528SMauro Carvalho Chehab 216, /* 64-QAM 5/6 */ 26339a0bf528SMauro Carvalho Chehab 225, /* 64-QAM 7/8 */ 26349a0bf528SMauro Carvalho Chehab }; 26359a0bf528SMauro Carvalho Chehab 2636cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 26379a0bf528SMauro Carvalho Chehab 26389a0bf528SMauro Carvalho Chehab do { 2639cd7a67a4SMauro Carvalho Chehab s32 signal_to_noise = 0; 2640cd7a67a4SMauro Carvalho Chehab u16 constellation = 0; 2641cd7a67a4SMauro Carvalho Chehab u16 code_rate = 0; 2642cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel; 2643cd7a67a4SMauro Carvalho Chehab u32 ber_quality; 26449a0bf528SMauro Carvalho Chehab 2645cd7a67a4SMauro Carvalho Chehab status = get_dvbt_signal_to_noise(state, &signal_to_noise); 26469a0bf528SMauro Carvalho Chehab if (status < 0) 26479a0bf528SMauro Carvalho Chehab break; 2648ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, 2649ab5060cdSMauro Carvalho Chehab &constellation); 26509a0bf528SMauro Carvalho Chehab if (status < 0) 26519a0bf528SMauro Carvalho Chehab break; 2652cd7a67a4SMauro Carvalho Chehab constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; 26539a0bf528SMauro Carvalho Chehab 2654ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, 2655ab5060cdSMauro Carvalho Chehab &code_rate); 26569a0bf528SMauro Carvalho Chehab if (status < 0) 26579a0bf528SMauro Carvalho Chehab break; 2658cd7a67a4SMauro Carvalho Chehab code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; 26599a0bf528SMauro Carvalho Chehab 2660cd7a67a4SMauro Carvalho Chehab if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || 2661cd7a67a4SMauro Carvalho Chehab code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) 26629a0bf528SMauro Carvalho Chehab break; 2663cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 2664cd7a67a4SMauro Carvalho Chehab QE_SN[constellation * 5 + code_rate]; 2665cd7a67a4SMauro Carvalho Chehab ber_quality = 100; 26669a0bf528SMauro Carvalho Chehab 2667cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70) 2668cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 2669cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30) 2670cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) * 2671cd7a67a4SMauro Carvalho Chehab ber_quality) / 100; 26729a0bf528SMauro Carvalho Chehab else 2673cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality; 26749a0bf528SMauro Carvalho Chehab } while (0); 26759a0bf528SMauro Carvalho Chehab return 0; 26769a0bf528SMauro Carvalho Chehab }; 26779a0bf528SMauro Carvalho Chehab 2678cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality) 26799a0bf528SMauro Carvalho Chehab { 26809a0bf528SMauro Carvalho Chehab int status = 0; 2681cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 26829a0bf528SMauro Carvalho Chehab 26839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 26849a0bf528SMauro Carvalho Chehab 26859a0bf528SMauro Carvalho Chehab do { 2686cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise = 0; 2687cd7a67a4SMauro Carvalho Chehab u32 ber_quality = 100; 2688cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel = 0; 26899a0bf528SMauro Carvalho Chehab 2690cd7a67a4SMauro Carvalho Chehab status = get_qam_signal_to_noise(state, &signal_to_noise); 26919a0bf528SMauro Carvalho Chehab if (status < 0) 26929a0bf528SMauro Carvalho Chehab break; 26939a0bf528SMauro Carvalho Chehab 26949a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 26959a0bf528SMauro Carvalho Chehab case QAM_16: 2696cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 200; 26979a0bf528SMauro Carvalho Chehab break; 26989a0bf528SMauro Carvalho Chehab case QAM_32: 2699cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 230; 27009a0bf528SMauro Carvalho Chehab break; /* Not in NorDig */ 27019a0bf528SMauro Carvalho Chehab case QAM_64: 2702cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 260; 27039a0bf528SMauro Carvalho Chehab break; 27049a0bf528SMauro Carvalho Chehab case QAM_128: 2705cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 290; 27069a0bf528SMauro Carvalho Chehab break; 27079a0bf528SMauro Carvalho Chehab default: 27089a0bf528SMauro Carvalho Chehab case QAM_256: 2709cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 320; 27109a0bf528SMauro Carvalho Chehab break; 27119a0bf528SMauro Carvalho Chehab } 27129a0bf528SMauro Carvalho Chehab 2713cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70) 2714cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 2715cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30) 2716cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) * 2717cd7a67a4SMauro Carvalho Chehab ber_quality) / 100; 27189a0bf528SMauro Carvalho Chehab else 2719cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality; 27209a0bf528SMauro Carvalho Chehab } while (0); 27219a0bf528SMauro Carvalho Chehab 27229a0bf528SMauro Carvalho Chehab return status; 27239a0bf528SMauro Carvalho Chehab } 27249a0bf528SMauro Carvalho Chehab 2725cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality) 27269a0bf528SMauro Carvalho Chehab { 27279a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27289a0bf528SMauro Carvalho Chehab 2729cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 27309a0bf528SMauro Carvalho Chehab case OM_DVBT: 2731cd7a67a4SMauro Carvalho Chehab return get_dvbt_quality(state, p_quality); 27329a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 2733cd7a67a4SMauro Carvalho Chehab return get_dvbc_quality(state, p_quality); 27349a0bf528SMauro Carvalho Chehab default: 27359a0bf528SMauro Carvalho Chehab break; 27369a0bf528SMauro Carvalho Chehab } 27379a0bf528SMauro Carvalho Chehab 27389a0bf528SMauro Carvalho Chehab return 0; 27399a0bf528SMauro Carvalho Chehab } 27409a0bf528SMauro Carvalho Chehab #endif 27419a0bf528SMauro Carvalho Chehab 27429a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */ 27439a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040 27449a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A 0x420060 27459a0bf528SMauro Carvalho Chehab 27469a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A) 27479a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7) 27489a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ 27499a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE 27509a0bf528SMauro Carvalho Chehab 27519a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F) 27529a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F) 27539a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF) 27549a0bf528SMauro Carvalho Chehab 2755cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) 27569a0bf528SMauro Carvalho Chehab { 27579a0bf528SMauro Carvalho Chehab int status = -EINVAL; 27589a0bf528SMauro Carvalho Chehab 27599a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27609a0bf528SMauro Carvalho Chehab 2761cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 27629a0bf528SMauro Carvalho Chehab return 0; 2763cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_POWERED_DOWN) 27649a0bf528SMauro Carvalho Chehab goto error; 27659a0bf528SMauro Carvalho Chehab 27669a0bf528SMauro Carvalho Chehab if (state->no_i2c_bridge) 27679a0bf528SMauro Carvalho Chehab return 0; 27689a0bf528SMauro Carvalho Chehab 2769ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 2770ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 27719a0bf528SMauro Carvalho Chehab if (status < 0) 27729a0bf528SMauro Carvalho Chehab goto error; 2773cd7a67a4SMauro Carvalho Chehab if (b_enable_bridge) { 2774ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 2775ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); 27769a0bf528SMauro Carvalho Chehab if (status < 0) 27779a0bf528SMauro Carvalho Chehab goto error; 27789a0bf528SMauro Carvalho Chehab } else { 2779ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 2780ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); 27819a0bf528SMauro Carvalho Chehab if (status < 0) 27829a0bf528SMauro Carvalho Chehab goto error; 27839a0bf528SMauro Carvalho Chehab } 27849a0bf528SMauro Carvalho Chehab 2785b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); 27869a0bf528SMauro Carvalho Chehab 27879a0bf528SMauro Carvalho Chehab error: 27889a0bf528SMauro Carvalho Chehab if (status < 0) 27893a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 27909a0bf528SMauro Carvalho Chehab return status; 27919a0bf528SMauro Carvalho Chehab } 27929a0bf528SMauro Carvalho Chehab 2793cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state, 2794cd7a67a4SMauro Carvalho Chehab struct s_cfg_pre_saw *p_pre_saw_cfg) 27959a0bf528SMauro Carvalho Chehab { 27969a0bf528SMauro Carvalho Chehab int status = -EINVAL; 27979a0bf528SMauro Carvalho Chehab 27989a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27999a0bf528SMauro Carvalho Chehab 2800cd7a67a4SMauro Carvalho Chehab if ((p_pre_saw_cfg == NULL) 2801cd7a67a4SMauro Carvalho Chehab || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M)) 28029a0bf528SMauro Carvalho Chehab goto error; 28039a0bf528SMauro Carvalho Chehab 2804cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference); 28059a0bf528SMauro Carvalho Chehab error: 28069a0bf528SMauro Carvalho Chehab if (status < 0) 28073a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 28089a0bf528SMauro Carvalho Chehab return status; 28099a0bf528SMauro Carvalho Chehab } 28109a0bf528SMauro Carvalho Chehab 2811cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, 2812cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out) 28139a0bf528SMauro Carvalho Chehab { 2814cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0; 2815cd7a67a4SMauro Carvalho Chehab u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF); 2816cd7a67a4SMauro Carvalho Chehab u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF); 28179a0bf528SMauro Carvalho Chehab int status; 28189a0bf528SMauro Carvalho Chehab unsigned long end; 28199a0bf528SMauro Carvalho Chehab 28209a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 28219a0bf528SMauro Carvalho Chehab 28229a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 28239a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT); 28249a0bf528SMauro Carvalho Chehab if (status < 0) 28259a0bf528SMauro Carvalho Chehab goto error; 28269a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_HDR__A, blockbank); 28279a0bf528SMauro Carvalho Chehab if (status < 0) 28289a0bf528SMauro Carvalho Chehab goto error; 28299a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_ADDR__A, offset); 28309a0bf528SMauro Carvalho Chehab if (status < 0) 28319a0bf528SMauro Carvalho Chehab goto error; 2832cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset); 28339a0bf528SMauro Carvalho Chehab if (status < 0) 28349a0bf528SMauro Carvalho Chehab goto error; 2835cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements); 28369a0bf528SMauro Carvalho Chehab if (status < 0) 28379a0bf528SMauro Carvalho Chehab goto error; 28389a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 28399a0bf528SMauro Carvalho Chehab if (status < 0) 28409a0bf528SMauro Carvalho Chehab goto error; 28419a0bf528SMauro Carvalho Chehab 2842cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out); 28439a0bf528SMauro Carvalho Chehab do { 2844cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status); 28459a0bf528SMauro Carvalho Chehab if (status < 0) 28469a0bf528SMauro Carvalho Chehab goto error; 2847cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) && time_is_after_jiffies(end)); 2848cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) { 28493a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 28509a0bf528SMauro Carvalho Chehab status = -EINVAL; 28519a0bf528SMauro Carvalho Chehab goto error2; 28529a0bf528SMauro Carvalho Chehab } 28539a0bf528SMauro Carvalho Chehab error: 28549a0bf528SMauro Carvalho Chehab if (status < 0) 28553a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 28569a0bf528SMauro Carvalho Chehab error2: 28579a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 28589a0bf528SMauro Carvalho Chehab return status; 28599a0bf528SMauro Carvalho Chehab 28609a0bf528SMauro Carvalho Chehab } 28619a0bf528SMauro Carvalho Chehab 2862cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count) 28639a0bf528SMauro Carvalho Chehab { 28649a0bf528SMauro Carvalho Chehab u16 data = 0; 28659a0bf528SMauro Carvalho Chehab int status; 28669a0bf528SMauro Carvalho Chehab 28679a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 28689a0bf528SMauro Carvalho Chehab 2869cd7a67a4SMauro Carvalho Chehab /* start measurement */ 28709a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE); 28719a0bf528SMauro Carvalho Chehab if (status < 0) 28729a0bf528SMauro Carvalho Chehab goto error; 28739a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 1); 28749a0bf528SMauro Carvalho Chehab if (status < 0) 28759a0bf528SMauro Carvalho Chehab goto error; 28769a0bf528SMauro Carvalho Chehab 28779a0bf528SMauro Carvalho Chehab *count = 0; 28789a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE0__A, &data); 28799a0bf528SMauro Carvalho Chehab if (status < 0) 28809a0bf528SMauro Carvalho Chehab goto error; 28819a0bf528SMauro Carvalho Chehab if (data == 127) 28829a0bf528SMauro Carvalho Chehab *count = *count + 1; 28839a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE1__A, &data); 28849a0bf528SMauro Carvalho Chehab if (status < 0) 28859a0bf528SMauro Carvalho Chehab goto error; 28869a0bf528SMauro Carvalho Chehab if (data == 127) 28879a0bf528SMauro Carvalho Chehab *count = *count + 1; 28889a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE2__A, &data); 28899a0bf528SMauro Carvalho Chehab if (status < 0) 28909a0bf528SMauro Carvalho Chehab goto error; 28919a0bf528SMauro Carvalho Chehab if (data == 127) 28929a0bf528SMauro Carvalho Chehab *count = *count + 1; 28939a0bf528SMauro Carvalho Chehab 28949a0bf528SMauro Carvalho Chehab error: 28959a0bf528SMauro Carvalho Chehab if (status < 0) 28963a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 28979a0bf528SMauro Carvalho Chehab return status; 28989a0bf528SMauro Carvalho Chehab } 28999a0bf528SMauro Carvalho Chehab 2900cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state) 29019a0bf528SMauro Carvalho Chehab { 29029a0bf528SMauro Carvalho Chehab u16 count = 0; 29039a0bf528SMauro Carvalho Chehab int status; 29049a0bf528SMauro Carvalho Chehab 29059a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 29069a0bf528SMauro Carvalho Chehab 2907cd7a67a4SMauro Carvalho Chehab status = adc_sync_measurement(state, &count); 29089a0bf528SMauro Carvalho Chehab if (status < 0) 29099a0bf528SMauro Carvalho Chehab goto error; 29109a0bf528SMauro Carvalho Chehab 29119a0bf528SMauro Carvalho Chehab if (count == 1) { 291239c1cb2bSJonathan McCrohan /* Try sampling on a different edge */ 2913cd7a67a4SMauro Carvalho Chehab u16 clk_neg = 0; 29149a0bf528SMauro Carvalho Chehab 2915cd7a67a4SMauro Carvalho Chehab status = read16(state, IQM_AF_CLKNEG__A, &clk_neg); 29169a0bf528SMauro Carvalho Chehab if (status < 0) 29179a0bf528SMauro Carvalho Chehab goto error; 2918cd7a67a4SMauro Carvalho Chehab if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) == 29199a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { 2920cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 2921cd7a67a4SMauro Carvalho Chehab clk_neg |= 29229a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG; 29239a0bf528SMauro Carvalho Chehab } else { 2924cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 2925cd7a67a4SMauro Carvalho Chehab clk_neg |= 29269a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS; 29279a0bf528SMauro Carvalho Chehab } 2928cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_CLKNEG__A, clk_neg); 29299a0bf528SMauro Carvalho Chehab if (status < 0) 29309a0bf528SMauro Carvalho Chehab goto error; 2931cd7a67a4SMauro Carvalho Chehab status = adc_sync_measurement(state, &count); 29329a0bf528SMauro Carvalho Chehab if (status < 0) 29339a0bf528SMauro Carvalho Chehab goto error; 29349a0bf528SMauro Carvalho Chehab } 29359a0bf528SMauro Carvalho Chehab 29369a0bf528SMauro Carvalho Chehab if (count < 2) 29379a0bf528SMauro Carvalho Chehab status = -EINVAL; 29389a0bf528SMauro Carvalho Chehab error: 29399a0bf528SMauro Carvalho Chehab if (status < 0) 29403a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 29419a0bf528SMauro Carvalho Chehab return status; 29429a0bf528SMauro Carvalho Chehab } 29439a0bf528SMauro Carvalho Chehab 2944cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state, 2945cd7a67a4SMauro Carvalho Chehab u16 intermediate_freqk_hz, 2946cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset, bool is_dtv) 29479a0bf528SMauro Carvalho Chehab { 2948cd7a67a4SMauro Carvalho Chehab bool select_pos_image = false; 2949cd7a67a4SMauro Carvalho Chehab u32 rf_freq_residual = tuner_freq_offset; 2950cd7a67a4SMauro Carvalho Chehab u32 fm_frequency_shift = 0; 2951cd7a67a4SMauro Carvalho Chehab bool tuner_mirror = !state->m_b_mirror_freq_spect; 2952cd7a67a4SMauro Carvalho Chehab u32 adc_freq; 2953cd7a67a4SMauro Carvalho Chehab bool adc_flip; 29549a0bf528SMauro Carvalho Chehab int status; 2955cd7a67a4SMauro Carvalho Chehab u32 if_freq_actual; 2956cd7a67a4SMauro Carvalho Chehab u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3); 2957cd7a67a4SMauro Carvalho Chehab u32 frequency_shift; 2958cd7a67a4SMauro Carvalho Chehab bool image_to_select; 29599a0bf528SMauro Carvalho Chehab 29609a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 29619a0bf528SMauro Carvalho Chehab 29629a0bf528SMauro Carvalho Chehab /* 29639a0bf528SMauro Carvalho Chehab Program frequency shifter 29649a0bf528SMauro Carvalho Chehab No need to account for mirroring on RF 29659a0bf528SMauro Carvalho Chehab */ 2966cd7a67a4SMauro Carvalho Chehab if (is_dtv) { 2967cd7a67a4SMauro Carvalho Chehab if ((state->m_operation_mode == OM_QAM_ITU_A) || 2968cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_C) || 2969cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_DVBT)) 2970cd7a67a4SMauro Carvalho Chehab select_pos_image = true; 29719a0bf528SMauro Carvalho Chehab else 2972cd7a67a4SMauro Carvalho Chehab select_pos_image = false; 29739a0bf528SMauro Carvalho Chehab } 2974cd7a67a4SMauro Carvalho Chehab if (tuner_mirror) 29759a0bf528SMauro Carvalho Chehab /* tuner doesn't mirror */ 2976cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz + 2977cd7a67a4SMauro Carvalho Chehab rf_freq_residual + fm_frequency_shift; 29789a0bf528SMauro Carvalho Chehab else 29799a0bf528SMauro Carvalho Chehab /* tuner mirrors */ 2980cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz - 2981cd7a67a4SMauro Carvalho Chehab rf_freq_residual - fm_frequency_shift; 2982cd7a67a4SMauro Carvalho Chehab if (if_freq_actual > sampling_frequency / 2) { 29839a0bf528SMauro Carvalho Chehab /* adc mirrors */ 2984cd7a67a4SMauro Carvalho Chehab adc_freq = sampling_frequency - if_freq_actual; 2985cd7a67a4SMauro Carvalho Chehab adc_flip = true; 29869a0bf528SMauro Carvalho Chehab } else { 29879a0bf528SMauro Carvalho Chehab /* adc doesn't mirror */ 2988cd7a67a4SMauro Carvalho Chehab adc_freq = if_freq_actual; 2989cd7a67a4SMauro Carvalho Chehab adc_flip = false; 29909a0bf528SMauro Carvalho Chehab } 29919a0bf528SMauro Carvalho Chehab 2992cd7a67a4SMauro Carvalho Chehab frequency_shift = adc_freq; 2993cd7a67a4SMauro Carvalho Chehab image_to_select = state->m_rfmirror ^ tuner_mirror ^ 2994cd7a67a4SMauro Carvalho Chehab adc_flip ^ select_pos_image; 2995cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs = 2996cd7a67a4SMauro Carvalho Chehab Frac28a((frequency_shift), sampling_frequency); 29979a0bf528SMauro Carvalho Chehab 2998cd7a67a4SMauro Carvalho Chehab if (image_to_select) 2999cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1; 30009a0bf528SMauro Carvalho Chehab 30019a0bf528SMauro Carvalho Chehab /* Program frequency shifter with tuner offset compensation */ 3002cd7a67a4SMauro Carvalho Chehab /* frequency_shift += tuner_freq_offset; TODO */ 30039a0bf528SMauro Carvalho Chehab status = write32(state, IQM_FS_RATE_OFS_LO__A, 3004cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs); 30059a0bf528SMauro Carvalho Chehab if (status < 0) 30063a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 30079a0bf528SMauro Carvalho Chehab return status; 30089a0bf528SMauro Carvalho Chehab } 30099a0bf528SMauro Carvalho Chehab 3010cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv) 30119a0bf528SMauro Carvalho Chehab { 3012cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt = 0; 3013cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_min = 0; 3014cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_max = 0; 3015cd7a67a4SMauro Carvalho Chehab u16 clp_cyclen = 0; 3016cd7a67a4SMauro Carvalho Chehab u16 clp_sum_min = 0; 3017cd7a67a4SMauro Carvalho Chehab u16 clp_dir_to = 0; 3018cd7a67a4SMauro Carvalho Chehab u16 sns_sum_min = 0; 3019cd7a67a4SMauro Carvalho Chehab u16 sns_sum_max = 0; 3020cd7a67a4SMauro Carvalho Chehab u16 clp_sum_max = 0; 3021cd7a67a4SMauro Carvalho Chehab u16 sns_dir_to = 0; 3022cd7a67a4SMauro Carvalho Chehab u16 ki_innergain_min = 0; 3023cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt = 0; 3024cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_min = 0; 3025cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_max = 0; 30269a0bf528SMauro Carvalho Chehab u16 data = 0; 3027cd7a67a4SMauro Carvalho Chehab u16 fast_clp_ctrl_delay = 0; 3028cd7a67a4SMauro Carvalho Chehab u16 clp_ctrl_mode = 0; 30299a0bf528SMauro Carvalho Chehab int status = 0; 30309a0bf528SMauro Carvalho Chehab 30319a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 30329a0bf528SMauro Carvalho Chehab 30339a0bf528SMauro Carvalho Chehab /* Common settings */ 3034cd7a67a4SMauro Carvalho Chehab sns_sum_max = 1023; 3035cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_min = 2047; 3036cd7a67a4SMauro Carvalho Chehab clp_cyclen = 500; 3037cd7a67a4SMauro Carvalho Chehab clp_sum_max = 1023; 30389a0bf528SMauro Carvalho Chehab 30399a0bf528SMauro Carvalho Chehab /* AGCInit() not available for DVBT; init done in microcode */ 3040cd7a67a4SMauro Carvalho Chehab if (!is_qam(state)) { 30413a4398f5SMauro Carvalho Chehab pr_err("%s: mode %d is not DVB-C\n", 30423a4398f5SMauro Carvalho Chehab __func__, state->m_operation_mode); 30439a0bf528SMauro Carvalho Chehab return -EINVAL; 30449a0bf528SMauro Carvalho Chehab } 30459a0bf528SMauro Carvalho Chehab 30469a0bf528SMauro Carvalho Chehab /* FIXME: Analog TV AGC require different settings */ 30479a0bf528SMauro Carvalho Chehab 30489a0bf528SMauro Carvalho Chehab /* Standard specific settings */ 3049cd7a67a4SMauro Carvalho Chehab clp_sum_min = 8; 3050cd7a67a4SMauro Carvalho Chehab clp_dir_to = (u16) -9; 3051cd7a67a4SMauro Carvalho Chehab clp_ctrl_mode = 0; 3052cd7a67a4SMauro Carvalho Chehab sns_sum_min = 8; 3053cd7a67a4SMauro Carvalho Chehab sns_dir_to = (u16) -9; 3054cd7a67a4SMauro Carvalho Chehab ki_innergain_min = (u16) -1030; 3055cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_max = 0x2380; 3056cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt = 0x2380; 3057cd7a67a4SMauro Carvalho Chehab ingain_tgt_min = 0x0511; 3058cd7a67a4SMauro Carvalho Chehab ingain_tgt = 0x0511; 3059cd7a67a4SMauro Carvalho Chehab ingain_tgt_max = 5119; 3060cd7a67a4SMauro Carvalho Chehab fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay; 30619a0bf528SMauro Carvalho Chehab 3062ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 3063ab5060cdSMauro Carvalho Chehab fast_clp_ctrl_delay); 30649a0bf528SMauro Carvalho Chehab if (status < 0) 30659a0bf528SMauro Carvalho Chehab goto error; 30669a0bf528SMauro Carvalho Chehab 3067cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode); 30689a0bf528SMauro Carvalho Chehab if (status < 0) 30699a0bf528SMauro Carvalho Chehab goto error; 3070cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt); 30719a0bf528SMauro Carvalho Chehab if (status < 0) 30729a0bf528SMauro Carvalho Chehab goto error; 3073cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min); 30749a0bf528SMauro Carvalho Chehab if (status < 0) 30759a0bf528SMauro Carvalho Chehab goto error; 3076cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max); 30779a0bf528SMauro Carvalho Chehab if (status < 0) 30789a0bf528SMauro Carvalho Chehab goto error; 3079ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, 3080ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_min); 30819a0bf528SMauro Carvalho Chehab if (status < 0) 30829a0bf528SMauro Carvalho Chehab goto error; 3083ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 3084ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_max); 30859a0bf528SMauro Carvalho Chehab if (status < 0) 30869a0bf528SMauro Carvalho Chehab goto error; 30879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0); 30889a0bf528SMauro Carvalho Chehab if (status < 0) 30899a0bf528SMauro Carvalho Chehab goto error; 30909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0); 30919a0bf528SMauro Carvalho Chehab if (status < 0) 30929a0bf528SMauro Carvalho Chehab goto error; 30939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0); 30949a0bf528SMauro Carvalho Chehab if (status < 0) 30959a0bf528SMauro Carvalho Chehab goto error; 30969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0); 30979a0bf528SMauro Carvalho Chehab if (status < 0) 30989a0bf528SMauro Carvalho Chehab goto error; 3099cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max); 31009a0bf528SMauro Carvalho Chehab if (status < 0) 31019a0bf528SMauro Carvalho Chehab goto error; 3102cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max); 31039a0bf528SMauro Carvalho Chehab if (status < 0) 31049a0bf528SMauro Carvalho Chehab goto error; 31059a0bf528SMauro Carvalho Chehab 3106ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, 3107ab5060cdSMauro Carvalho Chehab ki_innergain_min); 31089a0bf528SMauro Carvalho Chehab if (status < 0) 31099a0bf528SMauro Carvalho Chehab goto error; 3110ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 3111ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt); 31129a0bf528SMauro Carvalho Chehab if (status < 0) 31139a0bf528SMauro Carvalho Chehab goto error; 3114cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen); 31159a0bf528SMauro Carvalho Chehab if (status < 0) 31169a0bf528SMauro Carvalho Chehab goto error; 31179a0bf528SMauro Carvalho Chehab 31189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023); 31199a0bf528SMauro Carvalho Chehab if (status < 0) 31209a0bf528SMauro Carvalho Chehab goto error; 31219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023); 31229a0bf528SMauro Carvalho Chehab if (status < 0) 31239a0bf528SMauro Carvalho Chehab goto error; 31249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50); 31259a0bf528SMauro Carvalho Chehab if (status < 0) 31269a0bf528SMauro Carvalho Chehab goto error; 31279a0bf528SMauro Carvalho Chehab 31289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20); 31299a0bf528SMauro Carvalho Chehab if (status < 0) 31309a0bf528SMauro Carvalho Chehab goto error; 3131cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min); 31329a0bf528SMauro Carvalho Chehab if (status < 0) 31339a0bf528SMauro Carvalho Chehab goto error; 3134cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min); 31359a0bf528SMauro Carvalho Chehab if (status < 0) 31369a0bf528SMauro Carvalho Chehab goto error; 3137cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to); 31389a0bf528SMauro Carvalho Chehab if (status < 0) 31399a0bf528SMauro Carvalho Chehab goto error; 3140cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to); 31419a0bf528SMauro Carvalho Chehab if (status < 0) 31429a0bf528SMauro Carvalho Chehab goto error; 31439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff); 31449a0bf528SMauro Carvalho Chehab if (status < 0) 31459a0bf528SMauro Carvalho Chehab goto error; 31469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0); 31479a0bf528SMauro Carvalho Chehab if (status < 0) 31489a0bf528SMauro Carvalho Chehab goto error; 31499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117); 31509a0bf528SMauro Carvalho Chehab if (status < 0) 31519a0bf528SMauro Carvalho Chehab goto error; 31529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657); 31539a0bf528SMauro Carvalho Chehab if (status < 0) 31549a0bf528SMauro Carvalho Chehab goto error; 31559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0); 31569a0bf528SMauro Carvalho Chehab if (status < 0) 31579a0bf528SMauro Carvalho Chehab goto error; 31589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0); 31599a0bf528SMauro Carvalho Chehab if (status < 0) 31609a0bf528SMauro Carvalho Chehab goto error; 31619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0); 31629a0bf528SMauro Carvalho Chehab if (status < 0) 31639a0bf528SMauro Carvalho Chehab goto error; 31649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1); 31659a0bf528SMauro Carvalho Chehab if (status < 0) 31669a0bf528SMauro Carvalho Chehab goto error; 31679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0); 31689a0bf528SMauro Carvalho Chehab if (status < 0) 31699a0bf528SMauro Carvalho Chehab goto error; 31709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0); 31719a0bf528SMauro Carvalho Chehab if (status < 0) 31729a0bf528SMauro Carvalho Chehab goto error; 31739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0); 31749a0bf528SMauro Carvalho Chehab if (status < 0) 31759a0bf528SMauro Carvalho Chehab goto error; 31769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1); 31779a0bf528SMauro Carvalho Chehab if (status < 0) 31789a0bf528SMauro Carvalho Chehab goto error; 31799a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500); 31809a0bf528SMauro Carvalho Chehab if (status < 0) 31819a0bf528SMauro Carvalho Chehab goto error; 31829a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500); 31839a0bf528SMauro Carvalho Chehab if (status < 0) 31849a0bf528SMauro Carvalho Chehab goto error; 31859a0bf528SMauro Carvalho Chehab 31869a0bf528SMauro Carvalho Chehab /* Initialize inner-loop KI gain factors */ 31879a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI__A, &data); 31889a0bf528SMauro Carvalho Chehab if (status < 0) 31899a0bf528SMauro Carvalho Chehab goto error; 31909a0bf528SMauro Carvalho Chehab 31919a0bf528SMauro Carvalho Chehab data = 0x0657; 31929a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RF__M; 31939a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B); 31949a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_IF__M; 31959a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B); 31969a0bf528SMauro Carvalho Chehab 31979a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI__A, data); 31989a0bf528SMauro Carvalho Chehab error: 31999a0bf528SMauro Carvalho Chehab if (status < 0) 32003a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 32019a0bf528SMauro Carvalho Chehab return status; 32029a0bf528SMauro Carvalho Chehab } 32039a0bf528SMauro Carvalho Chehab 3204cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err) 32059a0bf528SMauro Carvalho Chehab { 32069a0bf528SMauro Carvalho Chehab int status; 32079a0bf528SMauro Carvalho Chehab 32089a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3209cd7a67a4SMauro Carvalho Chehab if (packet_err == NULL) 32109a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 32119a0bf528SMauro Carvalho Chehab else 3212ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 3213ab5060cdSMauro Carvalho Chehab packet_err); 32149a0bf528SMauro Carvalho Chehab if (status < 0) 32153a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 32169a0bf528SMauro Carvalho Chehab return status; 32179a0bf528SMauro Carvalho Chehab } 32189a0bf528SMauro Carvalho Chehab 3219cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state, 32209a0bf528SMauro Carvalho Chehab u16 cmd, u16 subcmd, 32219a0bf528SMauro Carvalho Chehab u16 param0, u16 param1, u16 param2, 32229a0bf528SMauro Carvalho Chehab u16 param3, u16 param4) 32239a0bf528SMauro Carvalho Chehab { 3224cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0; 3225cd7a67a4SMauro Carvalho Chehab u16 err_code = 0; 3226cd7a67a4SMauro Carvalho Chehab u16 retry_cnt = 0; 3227cd7a67a4SMauro Carvalho Chehab u16 sc_exec = 0; 32289a0bf528SMauro Carvalho Chehab int status; 32299a0bf528SMauro Carvalho Chehab 32309a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3231cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec); 3232cd7a67a4SMauro Carvalho Chehab if (sc_exec != 1) { 32339a0bf528SMauro Carvalho Chehab /* SC is not running */ 32349a0bf528SMauro Carvalho Chehab status = -EINVAL; 32359a0bf528SMauro Carvalho Chehab } 32369a0bf528SMauro Carvalho Chehab if (status < 0) 32379a0bf528SMauro Carvalho Chehab goto error; 32389a0bf528SMauro Carvalho Chehab 32399a0bf528SMauro Carvalho Chehab /* Wait until sc is ready to receive command */ 3240cd7a67a4SMauro Carvalho Chehab retry_cnt = 0; 32419a0bf528SMauro Carvalho Chehab do { 3242b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 3243cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 3244cd7a67a4SMauro Carvalho Chehab retry_cnt++; 3245cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 3246cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32479a0bf528SMauro Carvalho Chehab goto error; 32489a0bf528SMauro Carvalho Chehab 32499a0bf528SMauro Carvalho Chehab /* Write sub-command */ 32509a0bf528SMauro Carvalho Chehab switch (cmd) { 32519a0bf528SMauro Carvalho Chehab /* All commands using sub-cmd */ 32529a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 32539a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32549a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32559a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd); 32569a0bf528SMauro Carvalho Chehab if (status < 0) 32579a0bf528SMauro Carvalho Chehab goto error; 32589a0bf528SMauro Carvalho Chehab break; 32599a0bf528SMauro Carvalho Chehab default: 32609a0bf528SMauro Carvalho Chehab /* Do nothing */ 32619a0bf528SMauro Carvalho Chehab break; 32629a0bf528SMauro Carvalho Chehab } 32639a0bf528SMauro Carvalho Chehab 32649a0bf528SMauro Carvalho Chehab /* Write needed parameters and the command */ 32659a0bf528SMauro Carvalho Chehab switch (cmd) { 32669a0bf528SMauro Carvalho Chehab /* All commands using 5 parameters */ 32679a0bf528SMauro Carvalho Chehab /* All commands using 4 parameters */ 32689a0bf528SMauro Carvalho Chehab /* All commands using 3 parameters */ 32699a0bf528SMauro Carvalho Chehab /* All commands using 2 parameters */ 32709a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 32719a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32729a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32739a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1); 32749a0bf528SMauro Carvalho Chehab /* All commands using 1 parameters */ 32759a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 32769a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO: 32779a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0); 32789a0bf528SMauro Carvalho Chehab /* All commands using 0 parameters */ 32799a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 32809a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL: 32819a0bf528SMauro Carvalho Chehab /* Write command */ 32829a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd); 32839a0bf528SMauro Carvalho Chehab break; 32849a0bf528SMauro Carvalho Chehab default: 32859a0bf528SMauro Carvalho Chehab /* Unknown command */ 32869a0bf528SMauro Carvalho Chehab status = -EINVAL; 32879a0bf528SMauro Carvalho Chehab } 32889a0bf528SMauro Carvalho Chehab if (status < 0) 32899a0bf528SMauro Carvalho Chehab goto error; 32909a0bf528SMauro Carvalho Chehab 32919a0bf528SMauro Carvalho Chehab /* Wait until sc is ready processing command */ 3292cd7a67a4SMauro Carvalho Chehab retry_cnt = 0; 32939a0bf528SMauro Carvalho Chehab do { 3294b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 3295cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 3296cd7a67a4SMauro Carvalho Chehab retry_cnt++; 3297cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 3298cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32999a0bf528SMauro Carvalho Chehab goto error; 33009a0bf528SMauro Carvalho Chehab 33019a0bf528SMauro Carvalho Chehab /* Check for illegal cmd */ 3302cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code); 3303cd7a67a4SMauro Carvalho Chehab if (err_code == 0xFFFF) { 33049a0bf528SMauro Carvalho Chehab /* illegal command */ 33059a0bf528SMauro Carvalho Chehab status = -EINVAL; 33069a0bf528SMauro Carvalho Chehab } 33079a0bf528SMauro Carvalho Chehab if (status < 0) 33089a0bf528SMauro Carvalho Chehab goto error; 33099a0bf528SMauro Carvalho Chehab 331039c1cb2bSJonathan McCrohan /* Retrieve results parameters from SC */ 33119a0bf528SMauro Carvalho Chehab switch (cmd) { 33129a0bf528SMauro Carvalho Chehab /* All commands yielding 5 results */ 33139a0bf528SMauro Carvalho Chehab /* All commands yielding 4 results */ 33149a0bf528SMauro Carvalho Chehab /* All commands yielding 3 results */ 33159a0bf528SMauro Carvalho Chehab /* All commands yielding 2 results */ 33169a0bf528SMauro Carvalho Chehab /* All commands yielding 1 result */ 33179a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO: 33189a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 33199a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0)); 33209a0bf528SMauro Carvalho Chehab /* All commands yielding 0 results */ 33219a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 33229a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_TIMER: 33239a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 33249a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 33259a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 33269a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL: 33279a0bf528SMauro Carvalho Chehab break; 33289a0bf528SMauro Carvalho Chehab default: 33299a0bf528SMauro Carvalho Chehab /* Unknown command */ 33309a0bf528SMauro Carvalho Chehab status = -EINVAL; 33319a0bf528SMauro Carvalho Chehab break; 33329a0bf528SMauro Carvalho Chehab } /* switch (cmd->cmd) */ 33339a0bf528SMauro Carvalho Chehab error: 33349a0bf528SMauro Carvalho Chehab if (status < 0) 33353a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33369a0bf528SMauro Carvalho Chehab return status; 33379a0bf528SMauro Carvalho Chehab } 33389a0bf528SMauro Carvalho Chehab 3339cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state) 33409a0bf528SMauro Carvalho Chehab { 3341cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRX_POWER_UP; 33429a0bf528SMauro Carvalho Chehab int status; 33439a0bf528SMauro Carvalho Chehab 33449a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3345cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 33469a0bf528SMauro Carvalho Chehab if (status < 0) 33473a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33489a0bf528SMauro Carvalho Chehab return status; 33499a0bf528SMauro Carvalho Chehab } 33509a0bf528SMauro Carvalho Chehab 3351cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled) 33529a0bf528SMauro Carvalho Chehab { 33539a0bf528SMauro Carvalho Chehab int status; 33549a0bf528SMauro Carvalho Chehab 33559a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33565a7f7b79SMauro Carvalho Chehab if (*enabled) 33579a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 0); 33589a0bf528SMauro Carvalho Chehab else 33599a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1); 33609a0bf528SMauro Carvalho Chehab if (status < 0) 33613a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33629a0bf528SMauro Carvalho Chehab return status; 33639a0bf528SMauro Carvalho Chehab } 33649a0bf528SMauro Carvalho Chehab 33659a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K 4000 3366cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) 33679a0bf528SMauro Carvalho Chehab { 33689a0bf528SMauro Carvalho Chehab 33699a0bf528SMauro Carvalho Chehab int status; 33709a0bf528SMauro Carvalho Chehab 33719a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33725a7f7b79SMauro Carvalho Chehab if (*enabled) { 33739a0bf528SMauro Carvalho Chehab /* write mask to 1 */ 33749a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 33759a0bf528SMauro Carvalho Chehab DEFAULT_FR_THRES_8K); 33769a0bf528SMauro Carvalho Chehab } else { 33779a0bf528SMauro Carvalho Chehab /* write mask to 0 */ 33789a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0); 33799a0bf528SMauro Carvalho Chehab } 33809a0bf528SMauro Carvalho Chehab if (status < 0) 33813a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33829a0bf528SMauro Carvalho Chehab 33839a0bf528SMauro Carvalho Chehab return status; 33849a0bf528SMauro Carvalho Chehab } 33859a0bf528SMauro Carvalho Chehab 3386cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, 3387cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t *echo_thres) 33889a0bf528SMauro Carvalho Chehab { 33899a0bf528SMauro Carvalho Chehab u16 data = 0; 33909a0bf528SMauro Carvalho Chehab int status; 33919a0bf528SMauro Carvalho Chehab 33929a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33939a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data); 33949a0bf528SMauro Carvalho Chehab if (status < 0) 33959a0bf528SMauro Carvalho Chehab goto error; 33969a0bf528SMauro Carvalho Chehab 3397cd7a67a4SMauro Carvalho Chehab switch (echo_thres->fft_mode) { 33989a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_2K: 33999a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M; 3400cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold << 34019a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_2K__B) 34029a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M)); 34039a0bf528SMauro Carvalho Chehab break; 34049a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_8K: 34059a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M; 3406cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold << 34079a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_8K__B) 34089a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M)); 34099a0bf528SMauro Carvalho Chehab break; 34109a0bf528SMauro Carvalho Chehab default: 34119a0bf528SMauro Carvalho Chehab return -EINVAL; 34129a0bf528SMauro Carvalho Chehab } 34139a0bf528SMauro Carvalho Chehab 34149a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data); 34159a0bf528SMauro Carvalho Chehab error: 34169a0bf528SMauro Carvalho Chehab if (status < 0) 34173a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 34189a0bf528SMauro Carvalho Chehab return status; 34199a0bf528SMauro Carvalho Chehab } 34209a0bf528SMauro Carvalho Chehab 3421cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, 3422cd7a67a4SMauro Carvalho Chehab enum drxk_cfg_dvbt_sqi_speed *speed) 34239a0bf528SMauro Carvalho Chehab { 34249a0bf528SMauro Carvalho Chehab int status = -EINVAL; 34259a0bf528SMauro Carvalho Chehab 34269a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 34279a0bf528SMauro Carvalho Chehab 34289a0bf528SMauro Carvalho Chehab switch (*speed) { 34299a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_FAST: 34309a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_MEDIUM: 34319a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_SLOW: 34329a0bf528SMauro Carvalho Chehab break; 34339a0bf528SMauro Carvalho Chehab default: 34349a0bf528SMauro Carvalho Chehab goto error; 34359a0bf528SMauro Carvalho Chehab } 34369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A, 34379a0bf528SMauro Carvalho Chehab (u16) *speed); 34389a0bf528SMauro Carvalho Chehab error: 34399a0bf528SMauro Carvalho Chehab if (status < 0) 34403a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 34419a0bf528SMauro Carvalho Chehab return status; 34429a0bf528SMauro Carvalho Chehab } 34439a0bf528SMauro Carvalho Chehab 34449a0bf528SMauro Carvalho Chehab /*============================================================================*/ 34459a0bf528SMauro Carvalho Chehab 34469a0bf528SMauro Carvalho Chehab /** 34479a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets 34489a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 34499a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 34509a0bf528SMauro Carvalho Chehab * 34519a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard 34529a0bf528SMauro Carvalho Chehab * 34539a0bf528SMauro Carvalho Chehab */ 3454cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state) 34559a0bf528SMauro Carvalho Chehab { 34569a0bf528SMauro Carvalho Chehab int status; 34579a0bf528SMauro Carvalho Chehab bool setincenable = false; 34589a0bf528SMauro Carvalho Chehab bool setfrenable = true; 34599a0bf528SMauro Carvalho Chehab 3460cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K }; 3461cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K }; 34629a0bf528SMauro Carvalho Chehab 34639a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3464cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_inc_enable(state, &setincenable); 34659a0bf528SMauro Carvalho Chehab if (status < 0) 34669a0bf528SMauro Carvalho Chehab goto error; 3467cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_fr_enable(state, &setfrenable); 34689a0bf528SMauro Carvalho Chehab if (status < 0) 34699a0bf528SMauro Carvalho Chehab goto error; 3470cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k); 34719a0bf528SMauro Carvalho Chehab if (status < 0) 34729a0bf528SMauro Carvalho Chehab goto error; 3473cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k); 34749a0bf528SMauro Carvalho Chehab if (status < 0) 34759a0bf528SMauro Carvalho Chehab goto error; 3476ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, 3477ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max); 34789a0bf528SMauro Carvalho Chehab error: 34799a0bf528SMauro Carvalho Chehab if (status < 0) 34803a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 34819a0bf528SMauro Carvalho Chehab return status; 34829a0bf528SMauro Carvalho Chehab } 34839a0bf528SMauro Carvalho Chehab 34849a0bf528SMauro Carvalho Chehab /*============================================================================*/ 34859a0bf528SMauro Carvalho Chehab 34869a0bf528SMauro Carvalho Chehab /** 34879a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT. 34889a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 34899a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 34909a0bf528SMauro Carvalho Chehab * 34919a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode 34929a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used. 34939a0bf528SMauro Carvalho Chehab */ 3494cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 3495cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 34969a0bf528SMauro Carvalho Chehab { 3497cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 34989a0bf528SMauro Carvalho Chehab u16 data = 0; 34999a0bf528SMauro Carvalho Chehab int status; 35009a0bf528SMauro Carvalho Chehab 35019a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 35029a0bf528SMauro Carvalho Chehab 3503cd7a67a4SMauro Carvalho Chehab power_up_dvbt(state); 35049a0bf528SMauro Carvalho Chehab /* added antenna switch */ 3505cd7a67a4SMauro Carvalho Chehab switch_antenna_to_dvbt(state); 35069a0bf528SMauro Carvalho Chehab /* send OFDM reset command */ 3507ab5060cdSMauro Carvalho Chehab status = scu_command(state, 3508ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 3509ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 3510ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 35119a0bf528SMauro Carvalho Chehab if (status < 0) 35129a0bf528SMauro Carvalho Chehab goto error; 35139a0bf528SMauro Carvalho Chehab 35149a0bf528SMauro Carvalho Chehab /* send OFDM setenv command */ 3515ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 3516ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 3517ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 35189a0bf528SMauro Carvalho Chehab if (status < 0) 35199a0bf528SMauro Carvalho Chehab goto error; 35209a0bf528SMauro Carvalho Chehab 35219a0bf528SMauro Carvalho Chehab /* reset datapath for OFDM, processors first */ 35229a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 35239a0bf528SMauro Carvalho Chehab if (status < 0) 35249a0bf528SMauro Carvalho Chehab goto error; 35259a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 35269a0bf528SMauro Carvalho Chehab if (status < 0) 35279a0bf528SMauro Carvalho Chehab goto error; 35289a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 35299a0bf528SMauro Carvalho Chehab if (status < 0) 35309a0bf528SMauro Carvalho Chehab goto error; 35319a0bf528SMauro Carvalho Chehab 35329a0bf528SMauro Carvalho Chehab /* IQM setup */ 35339a0bf528SMauro Carvalho Chehab /* synchronize on ofdstate->m_festart */ 35349a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 1); 35359a0bf528SMauro Carvalho Chehab if (status < 0) 35369a0bf528SMauro Carvalho Chehab goto error; 35379a0bf528SMauro Carvalho Chehab /* window size for clipping ADC detection */ 35389a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0); 35399a0bf528SMauro Carvalho Chehab if (status < 0) 35409a0bf528SMauro Carvalho Chehab goto error; 35419a0bf528SMauro Carvalho Chehab /* window size for for sense pre-SAW detection */ 35429a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0); 35439a0bf528SMauro Carvalho Chehab if (status < 0) 35449a0bf528SMauro Carvalho Chehab goto error; 35459a0bf528SMauro Carvalho Chehab /* sense threshold for sense pre-SAW detection */ 35469a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 35479a0bf528SMauro Carvalho Chehab if (status < 0) 35489a0bf528SMauro Carvalho Chehab goto error; 3549cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true); 35509a0bf528SMauro Carvalho Chehab if (status < 0) 35519a0bf528SMauro Carvalho Chehab goto error; 35529a0bf528SMauro Carvalho Chehab 35539a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AGC_RF__A, 0); 35549a0bf528SMauro Carvalho Chehab if (status < 0) 35559a0bf528SMauro Carvalho Chehab goto error; 35569a0bf528SMauro Carvalho Chehab 35579a0bf528SMauro Carvalho Chehab /* Impulse noise cruncher setup */ 35589a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */ 35599a0bf528SMauro Carvalho Chehab if (status < 0) 35609a0bf528SMauro Carvalho Chehab goto error; 35619a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */ 35629a0bf528SMauro Carvalho Chehab if (status < 0) 35639a0bf528SMauro Carvalho Chehab goto error; 35649a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */ 35659a0bf528SMauro Carvalho Chehab if (status < 0) 35669a0bf528SMauro Carvalho Chehab goto error; 35679a0bf528SMauro Carvalho Chehab 35689a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 16); 35699a0bf528SMauro Carvalho Chehab if (status < 0) 35709a0bf528SMauro Carvalho Chehab goto error; 35719a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ 35729a0bf528SMauro Carvalho Chehab if (status < 0) 35739a0bf528SMauro Carvalho Chehab goto error; 35749a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */ 35759a0bf528SMauro Carvalho Chehab if (status < 0) 35769a0bf528SMauro Carvalho Chehab goto error; 35779a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE__A, 1600); 35789a0bf528SMauro Carvalho Chehab if (status < 0) 35799a0bf528SMauro Carvalho Chehab goto error; 35809a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, 0); 35819a0bf528SMauro Carvalho Chehab if (status < 0) 35829a0bf528SMauro Carvalho Chehab goto error; 35839a0bf528SMauro Carvalho Chehab 35849a0bf528SMauro Carvalho Chehab /* virtual clipping threshold for clipping ADC detection */ 35859a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448); 35869a0bf528SMauro Carvalho Chehab if (status < 0) 35879a0bf528SMauro Carvalho Chehab goto error; 35889a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */ 35899a0bf528SMauro Carvalho Chehab if (status < 0) 35909a0bf528SMauro Carvalho Chehab goto error; 35919a0bf528SMauro Carvalho Chehab 3592ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, 3593ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); 35949a0bf528SMauro Carvalho Chehab if (status < 0) 35959a0bf528SMauro Carvalho Chehab goto error; 35969a0bf528SMauro Carvalho Chehab 35979a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */ 35989a0bf528SMauro Carvalho Chehab if (status < 0) 35999a0bf528SMauro Carvalho Chehab goto error; 36009a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2); 36019a0bf528SMauro Carvalho Chehab if (status < 0) 36029a0bf528SMauro Carvalho Chehab goto error; 36039a0bf528SMauro Carvalho Chehab /* enable power measurement interrupt */ 36049a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_COMM_INT_MSK__A, 1); 36059a0bf528SMauro Carvalho Chehab if (status < 0) 36069a0bf528SMauro Carvalho Chehab goto error; 36079a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 36089a0bf528SMauro Carvalho Chehab if (status < 0) 36099a0bf528SMauro Carvalho Chehab goto error; 36109a0bf528SMauro Carvalho Chehab 36119a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */ 3612cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state); 36139a0bf528SMauro Carvalho Chehab if (status < 0) 36149a0bf528SMauro Carvalho Chehab goto error; 3615cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg); 36169a0bf528SMauro Carvalho Chehab if (status < 0) 36179a0bf528SMauro Carvalho Chehab goto error; 36189a0bf528SMauro Carvalho Chehab 36199a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 36209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 36219a0bf528SMauro Carvalho Chehab if (status < 0) 36229a0bf528SMauro Carvalho Chehab goto error; 36239a0bf528SMauro Carvalho Chehab 3624cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true); 36259a0bf528SMauro Carvalho Chehab if (status < 0) 36269a0bf528SMauro Carvalho Chehab goto error; 3627cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true); 36289a0bf528SMauro Carvalho Chehab if (status < 0) 36299a0bf528SMauro Carvalho Chehab goto error; 36309a0bf528SMauro Carvalho Chehab 36319a0bf528SMauro Carvalho Chehab /* Set Noise Estimation notch width and enable DC fix */ 36329a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data); 36339a0bf528SMauro Carvalho Chehab if (status < 0) 36349a0bf528SMauro Carvalho Chehab goto error; 36359a0bf528SMauro Carvalho Chehab data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M; 36369a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data); 36379a0bf528SMauro Carvalho Chehab if (status < 0) 36389a0bf528SMauro Carvalho Chehab goto error; 36399a0bf528SMauro Carvalho Chehab 36409a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 36419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 36429a0bf528SMauro Carvalho Chehab if (status < 0) 36439a0bf528SMauro Carvalho Chehab goto error; 36449a0bf528SMauro Carvalho Chehab 3645cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code) { 3646cd7a67a4SMauro Carvalho Chehab /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */ 3647ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 3648ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay); 36499a0bf528SMauro Carvalho Chehab if (status < 0) 36509a0bf528SMauro Carvalho Chehab goto error; 36519a0bf528SMauro Carvalho Chehab } 36529a0bf528SMauro Carvalho Chehab 36539a0bf528SMauro Carvalho Chehab /* OFDM_SC setup */ 36549a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT 36559a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1); 36569a0bf528SMauro Carvalho Chehab if (status < 0) 36579a0bf528SMauro Carvalho Chehab goto error; 36589a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2); 36599a0bf528SMauro Carvalho Chehab if (status < 0) 36609a0bf528SMauro Carvalho Chehab goto error; 36619a0bf528SMauro Carvalho Chehab #endif 36629a0bf528SMauro Carvalho Chehab 36639a0bf528SMauro Carvalho Chehab /* FEC setup */ 36649a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */ 36659a0bf528SMauro Carvalho Chehab if (status < 0) 36669a0bf528SMauro Carvalho Chehab goto error; 36679a0bf528SMauro Carvalho Chehab 36689a0bf528SMauro Carvalho Chehab 36699a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT 36709a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400); 36719a0bf528SMauro Carvalho Chehab if (status < 0) 36729a0bf528SMauro Carvalho Chehab goto error; 36739a0bf528SMauro Carvalho Chehab #else 36749a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000); 36759a0bf528SMauro Carvalho Chehab if (status < 0) 36769a0bf528SMauro Carvalho Chehab goto error; 36779a0bf528SMauro Carvalho Chehab #endif 36789a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001); 36799a0bf528SMauro Carvalho Chehab if (status < 0) 36809a0bf528SMauro Carvalho Chehab goto error; 36819a0bf528SMauro Carvalho Chehab 36829a0bf528SMauro Carvalho Chehab /* Setup MPEG bus */ 3683cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, OM_DVBT); 36849a0bf528SMauro Carvalho Chehab if (status < 0) 36859a0bf528SMauro Carvalho Chehab goto error; 36869a0bf528SMauro Carvalho Chehab /* Set DVBT Presets */ 3687cd7a67a4SMauro Carvalho Chehab status = dvbt_activate_presets(state); 36889a0bf528SMauro Carvalho Chehab if (status < 0) 36899a0bf528SMauro Carvalho Chehab goto error; 36909a0bf528SMauro Carvalho Chehab 36919a0bf528SMauro Carvalho Chehab error: 36929a0bf528SMauro Carvalho Chehab if (status < 0) 36933a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 36949a0bf528SMauro Carvalho Chehab return status; 36959a0bf528SMauro Carvalho Chehab } 36969a0bf528SMauro Carvalho Chehab 36979a0bf528SMauro Carvalho Chehab /*============================================================================*/ 36989a0bf528SMauro Carvalho Chehab /** 3699cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel. 37009a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 37019a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 37029a0bf528SMauro Carvalho Chehab */ 3703cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state) 37049a0bf528SMauro Carvalho Chehab { 37059a0bf528SMauro Carvalho Chehab u16 param1; 37069a0bf528SMauro Carvalho Chehab int status; 3707cd7a67a4SMauro Carvalho Chehab /* drxk_ofdm_sc_cmd_t scCmd; */ 37089a0bf528SMauro Carvalho Chehab 37099a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3710cd7a67a4SMauro Carvalho Chehab /* start correct processes to get in lock */ 37119a0bf528SMauro Carvalho Chehab /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */ 37129a0bf528SMauro Carvalho Chehab param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN; 3713ab5060cdSMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, 3714ab5060cdSMauro Carvalho Chehab OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 3715ab5060cdSMauro Carvalho Chehab 0, 0, 0); 37169a0bf528SMauro Carvalho Chehab if (status < 0) 37179a0bf528SMauro Carvalho Chehab goto error; 3718cd7a67a4SMauro Carvalho Chehab /* start FEC OC */ 3719cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state); 37209a0bf528SMauro Carvalho Chehab if (status < 0) 37219a0bf528SMauro Carvalho Chehab goto error; 37229a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 37239a0bf528SMauro Carvalho Chehab if (status < 0) 37249a0bf528SMauro Carvalho Chehab goto error; 37259a0bf528SMauro Carvalho Chehab error: 37269a0bf528SMauro Carvalho Chehab if (status < 0) 37273a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 37289a0bf528SMauro Carvalho Chehab return status; 37299a0bf528SMauro Carvalho Chehab } 37309a0bf528SMauro Carvalho Chehab 37319a0bf528SMauro Carvalho Chehab 37329a0bf528SMauro Carvalho Chehab /*============================================================================*/ 37339a0bf528SMauro Carvalho Chehab 37349a0bf528SMauro Carvalho Chehab /** 37359a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel. 37369a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 37379a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 37389a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel() 37399a0bf528SMauro Carvalho Chehab */ 3740cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 3741cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset) 37429a0bf528SMauro Carvalho Chehab { 3743cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 3744cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0; 3745cd7a67a4SMauro Carvalho Chehab u16 operation_mode = 0; 3746cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate_ofs = 0; 37479a0bf528SMauro Carvalho Chehab u32 bandwidth = 0; 37489a0bf528SMauro Carvalho Chehab u16 param1; 37499a0bf528SMauro Carvalho Chehab int status; 37509a0bf528SMauro Carvalho Chehab 3751ab5060cdSMauro Carvalho Chehab dprintk(1, "IF =%d, TFO = %d\n", 3752ab5060cdSMauro Carvalho Chehab intermediate_freqk_hz, tuner_freq_offset); 37539a0bf528SMauro Carvalho Chehab 3754ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 3755ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 3756ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 37579a0bf528SMauro Carvalho Chehab if (status < 0) 37589a0bf528SMauro Carvalho Chehab goto error; 37599a0bf528SMauro Carvalho Chehab 37609a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 37619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 37629a0bf528SMauro Carvalho Chehab if (status < 0) 37639a0bf528SMauro Carvalho Chehab goto error; 37649a0bf528SMauro Carvalho Chehab 37659a0bf528SMauro Carvalho Chehab /* Stop processors */ 37669a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 37679a0bf528SMauro Carvalho Chehab if (status < 0) 37689a0bf528SMauro Carvalho Chehab goto error; 37699a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 37709a0bf528SMauro Carvalho Chehab if (status < 0) 37719a0bf528SMauro Carvalho Chehab goto error; 37729a0bf528SMauro Carvalho Chehab 37739a0bf528SMauro Carvalho Chehab /* Mandatory fix, always stop CP, required to set spl offset back to 37749a0bf528SMauro Carvalho Chehab hardware default (is set to 0 by ucode during pilot detection */ 37759a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP); 37769a0bf528SMauro Carvalho Chehab if (status < 0) 37779a0bf528SMauro Carvalho Chehab goto error; 37789a0bf528SMauro Carvalho Chehab 3779ab5060cdSMauro Carvalho Chehab /*== Write channel settings to device ================================*/ 37809a0bf528SMauro Carvalho Chehab 37819a0bf528SMauro Carvalho Chehab /* mode */ 37829a0bf528SMauro Carvalho Chehab switch (state->props.transmission_mode) { 37839a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_AUTO: 37849a0bf528SMauro Carvalho Chehab default: 3785cd7a67a4SMauro Carvalho Chehab operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; 37869a0bf528SMauro Carvalho Chehab /* fall through , try first guess DRX_FFTMODE_8K */ 37879a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_8K: 3788cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; 37899a0bf528SMauro Carvalho Chehab break; 37909a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_2K: 3791cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; 37929a0bf528SMauro Carvalho Chehab break; 37939a0bf528SMauro Carvalho Chehab } 37949a0bf528SMauro Carvalho Chehab 37959a0bf528SMauro Carvalho Chehab /* guard */ 37969a0bf528SMauro Carvalho Chehab switch (state->props.guard_interval) { 37979a0bf528SMauro Carvalho Chehab default: 37989a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_AUTO: 3799cd7a67a4SMauro Carvalho Chehab operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; 38009a0bf528SMauro Carvalho Chehab /* fall through , try first guess DRX_GUARD_1DIV4 */ 38019a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_4: 3802cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; 38039a0bf528SMauro Carvalho Chehab break; 38049a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_32: 3805cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; 38069a0bf528SMauro Carvalho Chehab break; 38079a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_16: 3808cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; 38099a0bf528SMauro Carvalho Chehab break; 38109a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_8: 3811cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; 38129a0bf528SMauro Carvalho Chehab break; 38139a0bf528SMauro Carvalho Chehab } 38149a0bf528SMauro Carvalho Chehab 38159a0bf528SMauro Carvalho Chehab /* hierarchy */ 38169a0bf528SMauro Carvalho Chehab switch (state->props.hierarchy) { 38179a0bf528SMauro Carvalho Chehab case HIERARCHY_AUTO: 38189a0bf528SMauro Carvalho Chehab case HIERARCHY_NONE: 38199a0bf528SMauro Carvalho Chehab default: 3820cd7a67a4SMauro Carvalho Chehab operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; 38219a0bf528SMauro Carvalho Chehab /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */ 3822cd7a67a4SMauro Carvalho Chehab /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ 38239a0bf528SMauro Carvalho Chehab /* break; */ 38249a0bf528SMauro Carvalho Chehab case HIERARCHY_1: 3825cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; 38269a0bf528SMauro Carvalho Chehab break; 38279a0bf528SMauro Carvalho Chehab case HIERARCHY_2: 3828cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; 38299a0bf528SMauro Carvalho Chehab break; 38309a0bf528SMauro Carvalho Chehab case HIERARCHY_4: 3831cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; 38329a0bf528SMauro Carvalho Chehab break; 38339a0bf528SMauro Carvalho Chehab } 38349a0bf528SMauro Carvalho Chehab 38359a0bf528SMauro Carvalho Chehab 38369a0bf528SMauro Carvalho Chehab /* modulation */ 38379a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 38389a0bf528SMauro Carvalho Chehab case QAM_AUTO: 38399a0bf528SMauro Carvalho Chehab default: 3840cd7a67a4SMauro Carvalho Chehab operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; 38419a0bf528SMauro Carvalho Chehab /* fall through , try first guess DRX_CONSTELLATION_QAM64 */ 38429a0bf528SMauro Carvalho Chehab case QAM_64: 3843cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; 38449a0bf528SMauro Carvalho Chehab break; 38459a0bf528SMauro Carvalho Chehab case QPSK: 3846cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; 38479a0bf528SMauro Carvalho Chehab break; 38489a0bf528SMauro Carvalho Chehab case QAM_16: 3849cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; 38509a0bf528SMauro Carvalho Chehab break; 38519a0bf528SMauro Carvalho Chehab } 38529a0bf528SMauro Carvalho Chehab #if 0 385339c1cb2bSJonathan McCrohan /* No hierarchical channels support in BDA */ 38549a0bf528SMauro Carvalho Chehab /* Priority (only for hierarchical channels) */ 38559a0bf528SMauro Carvalho Chehab switch (channel->priority) { 38569a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_LOW: 3857cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; 3858cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38599a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_LO); 38609a0bf528SMauro Carvalho Chehab break; 38619a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_HIGH: 3862cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 3863cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38649a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_HI)); 38659a0bf528SMauro Carvalho Chehab break; 38669a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_UNKNOWN: /* fall through */ 38679a0bf528SMauro Carvalho Chehab default: 38689a0bf528SMauro Carvalho Chehab status = -EINVAL; 38699a0bf528SMauro Carvalho Chehab goto error; 38709a0bf528SMauro Carvalho Chehab } 38719a0bf528SMauro Carvalho Chehab #else 38729a0bf528SMauro Carvalho Chehab /* Set Priorty high */ 3873cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 38749a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI); 38759a0bf528SMauro Carvalho Chehab if (status < 0) 38769a0bf528SMauro Carvalho Chehab goto error; 38779a0bf528SMauro Carvalho Chehab #endif 38789a0bf528SMauro Carvalho Chehab 38799a0bf528SMauro Carvalho Chehab /* coderate */ 38809a0bf528SMauro Carvalho Chehab switch (state->props.code_rate_HP) { 38819a0bf528SMauro Carvalho Chehab case FEC_AUTO: 38829a0bf528SMauro Carvalho Chehab default: 3883cd7a67a4SMauro Carvalho Chehab operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; 38849a0bf528SMauro Carvalho Chehab /* fall through , try first guess DRX_CODERATE_2DIV3 */ 38859a0bf528SMauro Carvalho Chehab case FEC_2_3: 3886cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; 38879a0bf528SMauro Carvalho Chehab break; 38889a0bf528SMauro Carvalho Chehab case FEC_1_2: 3889cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; 38909a0bf528SMauro Carvalho Chehab break; 38919a0bf528SMauro Carvalho Chehab case FEC_3_4: 3892cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; 38939a0bf528SMauro Carvalho Chehab break; 38949a0bf528SMauro Carvalho Chehab case FEC_5_6: 3895cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; 38969a0bf528SMauro Carvalho Chehab break; 38979a0bf528SMauro Carvalho Chehab case FEC_7_8: 3898cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; 38999a0bf528SMauro Carvalho Chehab break; 39009a0bf528SMauro Carvalho Chehab } 39019a0bf528SMauro Carvalho Chehab 3902ab5060cdSMauro Carvalho Chehab /* 3903ab5060cdSMauro Carvalho Chehab * SAW filter selection: normaly not necesarry, but if wanted 3904ab5060cdSMauro Carvalho Chehab * the application can select a SAW filter via the driver by 3905ab5060cdSMauro Carvalho Chehab * using UIOs 3906ab5060cdSMauro Carvalho Chehab */ 3907ab5060cdSMauro Carvalho Chehab 39089a0bf528SMauro Carvalho Chehab /* First determine real bandwidth (Hz) */ 39099a0bf528SMauro Carvalho Chehab /* Also set delay for impulse noise cruncher */ 3910ab5060cdSMauro Carvalho Chehab /* 3911ab5060cdSMauro Carvalho Chehab * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is 3912ab5060cdSMauro Carvalho Chehab * changed by SC for fix for some 8K,1/8 guard but is restored by 3913ab5060cdSMauro Carvalho Chehab * InitEC and ResetEC functions 3914ab5060cdSMauro Carvalho Chehab */ 39159a0bf528SMauro Carvalho Chehab switch (state->props.bandwidth_hz) { 39169a0bf528SMauro Carvalho Chehab case 0: 39179a0bf528SMauro Carvalho Chehab state->props.bandwidth_hz = 8000000; 39189a0bf528SMauro Carvalho Chehab /* fall though */ 39199a0bf528SMauro Carvalho Chehab case 8000000: 39209a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; 3921ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3922ab5060cdSMauro Carvalho Chehab 3052); 39239a0bf528SMauro Carvalho Chehab if (status < 0) 39249a0bf528SMauro Carvalho Chehab goto error; 39259a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 8 MHz */ 3926ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3927ab5060cdSMauro Carvalho Chehab 7); 39289a0bf528SMauro Carvalho Chehab if (status < 0) 39299a0bf528SMauro Carvalho Chehab goto error; 3930ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3931ab5060cdSMauro Carvalho Chehab 7); 39329a0bf528SMauro Carvalho Chehab if (status < 0) 39339a0bf528SMauro Carvalho Chehab goto error; 3934ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3935ab5060cdSMauro Carvalho Chehab 7); 39369a0bf528SMauro Carvalho Chehab if (status < 0) 39379a0bf528SMauro Carvalho Chehab goto error; 3938ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3939ab5060cdSMauro Carvalho Chehab 1); 39409a0bf528SMauro Carvalho Chehab if (status < 0) 39419a0bf528SMauro Carvalho Chehab goto error; 39429a0bf528SMauro Carvalho Chehab break; 39439a0bf528SMauro Carvalho Chehab case 7000000: 39449a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; 3945ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3946ab5060cdSMauro Carvalho Chehab 3491); 39479a0bf528SMauro Carvalho Chehab if (status < 0) 39489a0bf528SMauro Carvalho Chehab goto error; 39499a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 7 MHz */ 3950ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3951ab5060cdSMauro Carvalho Chehab 8); 39529a0bf528SMauro Carvalho Chehab if (status < 0) 39539a0bf528SMauro Carvalho Chehab goto error; 3954ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3955ab5060cdSMauro Carvalho Chehab 8); 39569a0bf528SMauro Carvalho Chehab if (status < 0) 39579a0bf528SMauro Carvalho Chehab goto error; 3958ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3959ab5060cdSMauro Carvalho Chehab 4); 39609a0bf528SMauro Carvalho Chehab if (status < 0) 39619a0bf528SMauro Carvalho Chehab goto error; 3962ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3963ab5060cdSMauro Carvalho Chehab 1); 39649a0bf528SMauro Carvalho Chehab if (status < 0) 39659a0bf528SMauro Carvalho Chehab goto error; 39669a0bf528SMauro Carvalho Chehab break; 39679a0bf528SMauro Carvalho Chehab case 6000000: 39689a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; 3969ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3970ab5060cdSMauro Carvalho Chehab 4073); 39719a0bf528SMauro Carvalho Chehab if (status < 0) 39729a0bf528SMauro Carvalho Chehab goto error; 39739a0bf528SMauro Carvalho Chehab /* cochannel protection for NTSC 6 MHz */ 3974ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3975ab5060cdSMauro Carvalho Chehab 19); 39769a0bf528SMauro Carvalho Chehab if (status < 0) 39779a0bf528SMauro Carvalho Chehab goto error; 3978ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3979ab5060cdSMauro Carvalho Chehab 19); 39809a0bf528SMauro Carvalho Chehab if (status < 0) 39819a0bf528SMauro Carvalho Chehab goto error; 3982ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3983ab5060cdSMauro Carvalho Chehab 14); 39849a0bf528SMauro Carvalho Chehab if (status < 0) 39859a0bf528SMauro Carvalho Chehab goto error; 3986ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3987ab5060cdSMauro Carvalho Chehab 1); 39889a0bf528SMauro Carvalho Chehab if (status < 0) 39899a0bf528SMauro Carvalho Chehab goto error; 39909a0bf528SMauro Carvalho Chehab break; 39919a0bf528SMauro Carvalho Chehab default: 39929a0bf528SMauro Carvalho Chehab status = -EINVAL; 39939a0bf528SMauro Carvalho Chehab goto error; 39949a0bf528SMauro Carvalho Chehab } 39959a0bf528SMauro Carvalho Chehab 3996cd7a67a4SMauro Carvalho Chehab if (iqm_rc_rate_ofs == 0) { 39979a0bf528SMauro Carvalho Chehab /* Now compute IQM_RC_RATE_OFS 39989a0bf528SMauro Carvalho Chehab (((SysFreq/BandWidth)/2)/2) -1) * 2^23) 39999a0bf528SMauro Carvalho Chehab => 40009a0bf528SMauro Carvalho Chehab ((SysFreq / BandWidth) * (2^21)) - (2^23) 40019a0bf528SMauro Carvalho Chehab */ 40029a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^28) */ 4003ab5060cdSMauro Carvalho Chehab /* 4004ab5060cdSMauro Carvalho Chehab * assert (MAX(sysClk)/MIN(bandwidth) < 16) 4005ab5060cdSMauro Carvalho Chehab * => assert(MAX(sysClk) < 16*MIN(bandwidth)) 4006ab5060cdSMauro Carvalho Chehab * => assert(109714272 > 48000000) = true 4007ab5060cdSMauro Carvalho Chehab * so Frac 28 can be used 4008ab5060cdSMauro Carvalho Chehab */ 4009cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = Frac28a((u32) 4010cd7a67a4SMauro Carvalho Chehab ((state->m_sys_clock_freq * 40119a0bf528SMauro Carvalho Chehab 1000) / 3), bandwidth); 40129a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ 4013cd7a67a4SMauro Carvalho Chehab if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40) 4014cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs += 0x80L; 4015cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7; 40169a0bf528SMauro Carvalho Chehab /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */ 4017cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23); 40189a0bf528SMauro Carvalho Chehab } 40199a0bf528SMauro Carvalho Chehab 4020cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs &= 40219a0bf528SMauro Carvalho Chehab ((((u32) IQM_RC_RATE_OFS_HI__M) << 40229a0bf528SMauro Carvalho Chehab IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M); 4023cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs); 40249a0bf528SMauro Carvalho Chehab if (status < 0) 40259a0bf528SMauro Carvalho Chehab goto error; 40269a0bf528SMauro Carvalho Chehab 40279a0bf528SMauro Carvalho Chehab /* Bandwidth setting done */ 40289a0bf528SMauro Carvalho Chehab 40299a0bf528SMauro Carvalho Chehab #if 0 4030cd7a67a4SMauro Carvalho Chehab status = dvbt_set_frequency_shift(demod, channel, tuner_offset); 40319a0bf528SMauro Carvalho Chehab if (status < 0) 40329a0bf528SMauro Carvalho Chehab goto error; 40339a0bf528SMauro Carvalho Chehab #endif 4034ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz, 4035ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true); 40369a0bf528SMauro Carvalho Chehab if (status < 0) 40379a0bf528SMauro Carvalho Chehab goto error; 40389a0bf528SMauro Carvalho Chehab 4039ab5060cdSMauro Carvalho Chehab /*== start SC, write channel settings to SC ==========================*/ 40409a0bf528SMauro Carvalho Chehab 40419a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 40429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 40439a0bf528SMauro Carvalho Chehab if (status < 0) 40449a0bf528SMauro Carvalho Chehab goto error; 40459a0bf528SMauro Carvalho Chehab 40469a0bf528SMauro Carvalho Chehab /* Enable SC after setting all other parameters */ 40479a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_STATE__A, 0); 40489a0bf528SMauro Carvalho Chehab if (status < 0) 40499a0bf528SMauro Carvalho Chehab goto error; 40509a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, 1); 40519a0bf528SMauro Carvalho Chehab if (status < 0) 40529a0bf528SMauro Carvalho Chehab goto error; 40539a0bf528SMauro Carvalho Chehab 40549a0bf528SMauro Carvalho Chehab 4055ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 4056ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START, 4057ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 40589a0bf528SMauro Carvalho Chehab if (status < 0) 40599a0bf528SMauro Carvalho Chehab goto error; 40609a0bf528SMauro Carvalho Chehab 40619a0bf528SMauro Carvalho Chehab /* Write SC parameter registers, set all AUTO flags in operation mode */ 40629a0bf528SMauro Carvalho Chehab param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M | 40639a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_GUARD__M | 40649a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_CONST__M | 40659a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_HIER__M | 40669a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_RATE__M); 4067cd7a67a4SMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, 4068cd7a67a4SMauro Carvalho Chehab 0, transmission_params, param1, 0, 0, 0); 40699a0bf528SMauro Carvalho Chehab if (status < 0) 40709a0bf528SMauro Carvalho Chehab goto error; 40719a0bf528SMauro Carvalho Chehab 4072cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code) 4073cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed); 40749a0bf528SMauro Carvalho Chehab error: 40759a0bf528SMauro Carvalho Chehab if (status < 0) 40763a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 40779a0bf528SMauro Carvalho Chehab 40789a0bf528SMauro Carvalho Chehab return status; 40799a0bf528SMauro Carvalho Chehab } 40809a0bf528SMauro Carvalho Chehab 40819a0bf528SMauro Carvalho Chehab 40829a0bf528SMauro Carvalho Chehab /*============================================================================*/ 40839a0bf528SMauro Carvalho Chehab 40849a0bf528SMauro Carvalho Chehab /** 408539c1cb2bSJonathan McCrohan * \brief Retrieve lock status . 40869a0bf528SMauro Carvalho Chehab * \param demod Pointer to demodulator instance. 40879a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure. 40889a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 40899a0bf528SMauro Carvalho Chehab * 40909a0bf528SMauro Carvalho Chehab */ 4091cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) 40929a0bf528SMauro Carvalho Chehab { 40939a0bf528SMauro Carvalho Chehab int status; 40949a0bf528SMauro Carvalho Chehab const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M | 40959a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_LOCK_FEC__M); 40969a0bf528SMauro Carvalho Chehab const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M); 40979a0bf528SMauro Carvalho Chehab const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M; 40989a0bf528SMauro Carvalho Chehab 4099cd7a67a4SMauro Carvalho Chehab u16 sc_ra_ram_lock = 0; 4100cd7a67a4SMauro Carvalho Chehab u16 sc_comm_exec = 0; 41019a0bf528SMauro Carvalho Chehab 41029a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 41039a0bf528SMauro Carvalho Chehab 4104cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 41059a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 41069a0bf528SMauro Carvalho Chehab /* Check if SC is running */ 4107cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec); 41089a0bf528SMauro Carvalho Chehab if (status < 0) 41099a0bf528SMauro Carvalho Chehab goto end; 4110cd7a67a4SMauro Carvalho Chehab if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP) 41119a0bf528SMauro Carvalho Chehab goto end; 41129a0bf528SMauro Carvalho Chehab 4113cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock); 41149a0bf528SMauro Carvalho Chehab if (status < 0) 41159a0bf528SMauro Carvalho Chehab goto end; 41169a0bf528SMauro Carvalho Chehab 4117cd7a67a4SMauro Carvalho Chehab if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask) 4118cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK; 4119cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask) 4120cd7a67a4SMauro Carvalho Chehab *p_lock_status = FEC_LOCK; 4121cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask) 4122cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK; 4123cd7a67a4SMauro Carvalho Chehab else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) 4124cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK; 41259a0bf528SMauro Carvalho Chehab end: 41269a0bf528SMauro Carvalho Chehab if (status < 0) 41273a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 41289a0bf528SMauro Carvalho Chehab 41299a0bf528SMauro Carvalho Chehab return status; 41309a0bf528SMauro Carvalho Chehab } 41319a0bf528SMauro Carvalho Chehab 4132cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state) 41339a0bf528SMauro Carvalho Chehab { 4134cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 41359a0bf528SMauro Carvalho Chehab int status; 41369a0bf528SMauro Carvalho Chehab 41379a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 4138cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 41399a0bf528SMauro Carvalho Chehab if (status < 0) 41403a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 41419a0bf528SMauro Carvalho Chehab 41429a0bf528SMauro Carvalho Chehab return status; 41439a0bf528SMauro Carvalho Chehab } 41449a0bf528SMauro Carvalho Chehab 41459a0bf528SMauro Carvalho Chehab 41469a0bf528SMauro Carvalho Chehab /** Power Down QAM */ 4147cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state) 41489a0bf528SMauro Carvalho Chehab { 41499a0bf528SMauro Carvalho Chehab u16 data = 0; 4150cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 41519a0bf528SMauro Carvalho Chehab int status = 0; 41529a0bf528SMauro Carvalho Chehab 41539a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 41549a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data); 41559a0bf528SMauro Carvalho Chehab if (status < 0) 41569a0bf528SMauro Carvalho Chehab goto error; 41579a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) { 41589a0bf528SMauro Carvalho Chehab /* 41599a0bf528SMauro Carvalho Chehab STOP demodulator 41609a0bf528SMauro Carvalho Chehab QAM and HW blocks 41619a0bf528SMauro Carvalho Chehab */ 41629a0bf528SMauro Carvalho Chehab /* stop all comstate->m_exec */ 41639a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 41649a0bf528SMauro Carvalho Chehab if (status < 0) 41659a0bf528SMauro Carvalho Chehab goto error; 4166ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 4167ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 4168ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 41699a0bf528SMauro Carvalho Chehab if (status < 0) 41709a0bf528SMauro Carvalho Chehab goto error; 41719a0bf528SMauro Carvalho Chehab } 41729a0bf528SMauro Carvalho Chehab /* powerdown AFE */ 4173cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false); 41749a0bf528SMauro Carvalho Chehab 41759a0bf528SMauro Carvalho Chehab error: 41769a0bf528SMauro Carvalho Chehab if (status < 0) 41773a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 41789a0bf528SMauro Carvalho Chehab 41799a0bf528SMauro Carvalho Chehab return status; 41809a0bf528SMauro Carvalho Chehab } 41819a0bf528SMauro Carvalho Chehab 41829a0bf528SMauro Carvalho Chehab /*============================================================================*/ 41839a0bf528SMauro Carvalho Chehab 41849a0bf528SMauro Carvalho Chehab /** 41859a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality 41869a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 41879a0bf528SMauro Carvalho Chehab * \param modulation current modulation. 41889a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 41899a0bf528SMauro Carvalho Chehab * 41909a0bf528SMauro Carvalho Chehab * NOTE: 41919a0bf528SMauro Carvalho Chehab * Take into account that for certain settings the errorcounters can overflow. 41929a0bf528SMauro Carvalho Chehab * The implementation does not check this. 41939a0bf528SMauro Carvalho Chehab * 41949a0bf528SMauro Carvalho Chehab */ 4195cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state, 4196cd7a67a4SMauro Carvalho Chehab enum e_drxk_constellation modulation, 4197cd7a67a4SMauro Carvalho Chehab u32 symbol_rate) 41989a0bf528SMauro Carvalho Chehab { 4199cd7a67a4SMauro Carvalho Chehab u32 fec_bits_desired = 0; /* BER accounting period */ 4200cd7a67a4SMauro Carvalho Chehab u32 fec_rs_period_total = 0; /* Total period */ 4201cd7a67a4SMauro Carvalho Chehab u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */ 4202cd7a67a4SMauro Carvalho Chehab u16 fec_rs_period = 0; /* Value for corresponding I2C register */ 42039a0bf528SMauro Carvalho Chehab int status = 0; 42049a0bf528SMauro Carvalho Chehab 42059a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 42069a0bf528SMauro Carvalho Chehab 4207cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1; 4208cd7a67a4SMauro Carvalho Chehab /* fec_bits_desired = symbol_rate [kHz] * 42099a0bf528SMauro Carvalho Chehab FrameLenght [ms] * 42109a0bf528SMauro Carvalho Chehab (modulation + 1) * 42119a0bf528SMauro Carvalho Chehab SyncLoss (== 1) * 42129a0bf528SMauro Carvalho Chehab ViterbiLoss (==1) 42139a0bf528SMauro Carvalho Chehab */ 42149a0bf528SMauro Carvalho Chehab switch (modulation) { 42159a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM16: 4216cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 4 * symbol_rate; 42179a0bf528SMauro Carvalho Chehab break; 42189a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM32: 4219cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 5 * symbol_rate; 42209a0bf528SMauro Carvalho Chehab break; 42219a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM64: 4222cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 6 * symbol_rate; 42239a0bf528SMauro Carvalho Chehab break; 42249a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM128: 4225cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 7 * symbol_rate; 42269a0bf528SMauro Carvalho Chehab break; 42279a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM256: 4228cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 8 * symbol_rate; 42299a0bf528SMauro Carvalho Chehab break; 42309a0bf528SMauro Carvalho Chehab default: 42319a0bf528SMauro Carvalho Chehab status = -EINVAL; 42329a0bf528SMauro Carvalho Chehab } 42339a0bf528SMauro Carvalho Chehab if (status < 0) 42349a0bf528SMauro Carvalho Chehab goto error; 42359a0bf528SMauro Carvalho Chehab 4236cd7a67a4SMauro Carvalho Chehab fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */ 4237cd7a67a4SMauro Carvalho Chehab fec_bits_desired *= 500; /* meas. period [ms] */ 42389a0bf528SMauro Carvalho Chehab 42399a0bf528SMauro Carvalho Chehab /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */ 4240cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_bits_desired / 1632 */ 4241cd7a67a4SMauro Carvalho Chehab fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */ 42429a0bf528SMauro Carvalho Chehab 4243cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */ 4244cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16); 4245cd7a67a4SMauro Carvalho Chehab if (fec_rs_prescale == 0) { 42469a0bf528SMauro Carvalho Chehab /* Divide by zero (though impossible) */ 42479a0bf528SMauro Carvalho Chehab status = -EINVAL; 42489a0bf528SMauro Carvalho Chehab if (status < 0) 42499a0bf528SMauro Carvalho Chehab goto error; 42509a0bf528SMauro Carvalho Chehab } 4251cd7a67a4SMauro Carvalho Chehab fec_rs_period = 4252cd7a67a4SMauro Carvalho Chehab ((u16) fec_rs_period_total + 4253cd7a67a4SMauro Carvalho Chehab (fec_rs_prescale >> 1)) / fec_rs_prescale; 42549a0bf528SMauro Carvalho Chehab 42559a0bf528SMauro Carvalho Chehab /* write corresponding registers */ 4256cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period); 42579a0bf528SMauro Carvalho Chehab if (status < 0) 42589a0bf528SMauro Carvalho Chehab goto error; 4259ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 4260ab5060cdSMauro Carvalho Chehab fec_rs_prescale); 42619a0bf528SMauro Carvalho Chehab if (status < 0) 42629a0bf528SMauro Carvalho Chehab goto error; 4263cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period); 42649a0bf528SMauro Carvalho Chehab error: 42659a0bf528SMauro Carvalho Chehab if (status < 0) 42663a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 42679a0bf528SMauro Carvalho Chehab return status; 42689a0bf528SMauro Carvalho Chehab } 42699a0bf528SMauro Carvalho Chehab 4270cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state) 42719a0bf528SMauro Carvalho Chehab { 42729a0bf528SMauro Carvalho Chehab int status = 0; 42739a0bf528SMauro Carvalho Chehab 42749a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 42759a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 42769a0bf528SMauro Carvalho Chehab /* Equalizer */ 42779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517); 42789a0bf528SMauro Carvalho Chehab if (status < 0) 42799a0bf528SMauro Carvalho Chehab goto error; 42809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517); 42819a0bf528SMauro Carvalho Chehab if (status < 0) 42829a0bf528SMauro Carvalho Chehab goto error; 42839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517); 42849a0bf528SMauro Carvalho Chehab if (status < 0) 42859a0bf528SMauro Carvalho Chehab goto error; 42869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517); 42879a0bf528SMauro Carvalho Chehab if (status < 0) 42889a0bf528SMauro Carvalho Chehab goto error; 42899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517); 42909a0bf528SMauro Carvalho Chehab if (status < 0) 42919a0bf528SMauro Carvalho Chehab goto error; 42929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517); 42939a0bf528SMauro Carvalho Chehab if (status < 0) 42949a0bf528SMauro Carvalho Chehab goto error; 42959a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 42969a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 2); 42979a0bf528SMauro Carvalho Chehab if (status < 0) 42989a0bf528SMauro Carvalho Chehab goto error; 42999a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 2); 43009a0bf528SMauro Carvalho Chehab if (status < 0) 43019a0bf528SMauro Carvalho Chehab goto error; 43029a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 2); 43039a0bf528SMauro Carvalho Chehab if (status < 0) 43049a0bf528SMauro Carvalho Chehab goto error; 43059a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 2); 43069a0bf528SMauro Carvalho Chehab if (status < 0) 43079a0bf528SMauro Carvalho Chehab goto error; 43089a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 2); 43099a0bf528SMauro Carvalho Chehab if (status < 0) 43109a0bf528SMauro Carvalho Chehab goto error; 43119a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 43129a0bf528SMauro Carvalho Chehab if (status < 0) 43139a0bf528SMauro Carvalho Chehab goto error; 43149a0bf528SMauro Carvalho Chehab 43159a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 43169a0bf528SMauro Carvalho Chehab if (status < 0) 43179a0bf528SMauro Carvalho Chehab goto error; 43189a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 43199a0bf528SMauro Carvalho Chehab if (status < 0) 43209a0bf528SMauro Carvalho Chehab goto error; 43219a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 43229a0bf528SMauro Carvalho Chehab if (status < 0) 43239a0bf528SMauro Carvalho Chehab goto error; 43249a0bf528SMauro Carvalho Chehab 43259a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 4326ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4327ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM16); 43289a0bf528SMauro Carvalho Chehab if (status < 0) 43299a0bf528SMauro Carvalho Chehab goto error; 43309a0bf528SMauro Carvalho Chehab 43319a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 43329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 43339a0bf528SMauro Carvalho Chehab if (status < 0) 43349a0bf528SMauro Carvalho Chehab goto error; 43359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 43369a0bf528SMauro Carvalho Chehab if (status < 0) 43379a0bf528SMauro Carvalho Chehab goto error; 43389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 43399a0bf528SMauro Carvalho Chehab if (status < 0) 43409a0bf528SMauro Carvalho Chehab goto error; 43419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 43429a0bf528SMauro Carvalho Chehab if (status < 0) 43439a0bf528SMauro Carvalho Chehab goto error; 43449a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 43459a0bf528SMauro Carvalho Chehab if (status < 0) 43469a0bf528SMauro Carvalho Chehab goto error; 43479a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 43489a0bf528SMauro Carvalho Chehab if (status < 0) 43499a0bf528SMauro Carvalho Chehab goto error; 43509a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 43519a0bf528SMauro Carvalho Chehab if (status < 0) 43529a0bf528SMauro Carvalho Chehab goto error; 43539a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 43549a0bf528SMauro Carvalho Chehab if (status < 0) 43559a0bf528SMauro Carvalho Chehab goto error; 43569a0bf528SMauro Carvalho Chehab 43579a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 43589a0bf528SMauro Carvalho Chehab if (status < 0) 43599a0bf528SMauro Carvalho Chehab goto error; 43609a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 43619a0bf528SMauro Carvalho Chehab if (status < 0) 43629a0bf528SMauro Carvalho Chehab goto error; 43639a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 43649a0bf528SMauro Carvalho Chehab if (status < 0) 43659a0bf528SMauro Carvalho Chehab goto error; 43669a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 43679a0bf528SMauro Carvalho Chehab if (status < 0) 43689a0bf528SMauro Carvalho Chehab goto error; 43699a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 43709a0bf528SMauro Carvalho Chehab if (status < 0) 43719a0bf528SMauro Carvalho Chehab goto error; 43729a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 43739a0bf528SMauro Carvalho Chehab if (status < 0) 43749a0bf528SMauro Carvalho Chehab goto error; 43759a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 43769a0bf528SMauro Carvalho Chehab if (status < 0) 43779a0bf528SMauro Carvalho Chehab goto error; 43789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 43799a0bf528SMauro Carvalho Chehab if (status < 0) 43809a0bf528SMauro Carvalho Chehab goto error; 43819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32); 43829a0bf528SMauro Carvalho Chehab if (status < 0) 43839a0bf528SMauro Carvalho Chehab goto error; 43849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 43859a0bf528SMauro Carvalho Chehab if (status < 0) 43869a0bf528SMauro Carvalho Chehab goto error; 43879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 43889a0bf528SMauro Carvalho Chehab if (status < 0) 43899a0bf528SMauro Carvalho Chehab goto error; 43909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 43919a0bf528SMauro Carvalho Chehab if (status < 0) 43929a0bf528SMauro Carvalho Chehab goto error; 43939a0bf528SMauro Carvalho Chehab 43949a0bf528SMauro Carvalho Chehab 43959a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 43969a0bf528SMauro Carvalho Chehab 43979a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140); 43989a0bf528SMauro Carvalho Chehab if (status < 0) 43999a0bf528SMauro Carvalho Chehab goto error; 44009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 44019a0bf528SMauro Carvalho Chehab if (status < 0) 44029a0bf528SMauro Carvalho Chehab goto error; 44039a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95); 44049a0bf528SMauro Carvalho Chehab if (status < 0) 44059a0bf528SMauro Carvalho Chehab goto error; 44069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120); 44079a0bf528SMauro Carvalho Chehab if (status < 0) 44089a0bf528SMauro Carvalho Chehab goto error; 44099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230); 44109a0bf528SMauro Carvalho Chehab if (status < 0) 44119a0bf528SMauro Carvalho Chehab goto error; 44129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105); 44139a0bf528SMauro Carvalho Chehab if (status < 0) 44149a0bf528SMauro Carvalho Chehab goto error; 44159a0bf528SMauro Carvalho Chehab 44169a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 44179a0bf528SMauro Carvalho Chehab if (status < 0) 44189a0bf528SMauro Carvalho Chehab goto error; 44199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 44209a0bf528SMauro Carvalho Chehab if (status < 0) 44219a0bf528SMauro Carvalho Chehab goto error; 44229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24); 44239a0bf528SMauro Carvalho Chehab if (status < 0) 44249a0bf528SMauro Carvalho Chehab goto error; 44259a0bf528SMauro Carvalho Chehab 44269a0bf528SMauro Carvalho Chehab 44279a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 44289a0bf528SMauro Carvalho Chehab 44299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16); 44309a0bf528SMauro Carvalho Chehab if (status < 0) 44319a0bf528SMauro Carvalho Chehab goto error; 44329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220); 44339a0bf528SMauro Carvalho Chehab if (status < 0) 44349a0bf528SMauro Carvalho Chehab goto error; 44359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25); 44369a0bf528SMauro Carvalho Chehab if (status < 0) 44379a0bf528SMauro Carvalho Chehab goto error; 44389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6); 44399a0bf528SMauro Carvalho Chehab if (status < 0) 44409a0bf528SMauro Carvalho Chehab goto error; 44419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24); 44429a0bf528SMauro Carvalho Chehab if (status < 0) 44439a0bf528SMauro Carvalho Chehab goto error; 44449a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65); 44459a0bf528SMauro Carvalho Chehab if (status < 0) 44469a0bf528SMauro Carvalho Chehab goto error; 44479a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127); 44489a0bf528SMauro Carvalho Chehab if (status < 0) 44499a0bf528SMauro Carvalho Chehab goto error; 44509a0bf528SMauro Carvalho Chehab 44519a0bf528SMauro Carvalho Chehab error: 44529a0bf528SMauro Carvalho Chehab if (status < 0) 44533a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 44549a0bf528SMauro Carvalho Chehab return status; 44559a0bf528SMauro Carvalho Chehab } 44569a0bf528SMauro Carvalho Chehab 44579a0bf528SMauro Carvalho Chehab /*============================================================================*/ 44589a0bf528SMauro Carvalho Chehab 44599a0bf528SMauro Carvalho Chehab /** 44609a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup 44619a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 44629a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 44639a0bf528SMauro Carvalho Chehab */ 4464cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state) 44659a0bf528SMauro Carvalho Chehab { 44669a0bf528SMauro Carvalho Chehab int status = 0; 44679a0bf528SMauro Carvalho Chehab 44689a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 44699a0bf528SMauro Carvalho Chehab 44709a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 44719a0bf528SMauro Carvalho Chehab /* Equalizer */ 44729a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707); 44739a0bf528SMauro Carvalho Chehab if (status < 0) 44749a0bf528SMauro Carvalho Chehab goto error; 44759a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707); 44769a0bf528SMauro Carvalho Chehab if (status < 0) 44779a0bf528SMauro Carvalho Chehab goto error; 44789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707); 44799a0bf528SMauro Carvalho Chehab if (status < 0) 44809a0bf528SMauro Carvalho Chehab goto error; 44819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707); 44829a0bf528SMauro Carvalho Chehab if (status < 0) 44839a0bf528SMauro Carvalho Chehab goto error; 44849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707); 44859a0bf528SMauro Carvalho Chehab if (status < 0) 44869a0bf528SMauro Carvalho Chehab goto error; 44879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707); 44889a0bf528SMauro Carvalho Chehab if (status < 0) 44899a0bf528SMauro Carvalho Chehab goto error; 44909a0bf528SMauro Carvalho Chehab 44919a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 44929a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 3); 44939a0bf528SMauro Carvalho Chehab if (status < 0) 44949a0bf528SMauro Carvalho Chehab goto error; 44959a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 3); 44969a0bf528SMauro Carvalho Chehab if (status < 0) 44979a0bf528SMauro Carvalho Chehab goto error; 44989a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 3); 44999a0bf528SMauro Carvalho Chehab if (status < 0) 45009a0bf528SMauro Carvalho Chehab goto error; 45019a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 3); 45029a0bf528SMauro Carvalho Chehab if (status < 0) 45039a0bf528SMauro Carvalho Chehab goto error; 45049a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 45059a0bf528SMauro Carvalho Chehab if (status < 0) 45069a0bf528SMauro Carvalho Chehab goto error; 45079a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 45089a0bf528SMauro Carvalho Chehab if (status < 0) 45099a0bf528SMauro Carvalho Chehab goto error; 45109a0bf528SMauro Carvalho Chehab 45119a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6); 45129a0bf528SMauro Carvalho Chehab if (status < 0) 45139a0bf528SMauro Carvalho Chehab goto error; 45149a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5); 45159a0bf528SMauro Carvalho Chehab if (status < 0) 45169a0bf528SMauro Carvalho Chehab goto error; 45179a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 45189a0bf528SMauro Carvalho Chehab if (status < 0) 45199a0bf528SMauro Carvalho Chehab goto error; 45209a0bf528SMauro Carvalho Chehab 45219a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 45229a0bf528SMauro Carvalho Chehab 4523ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4524ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM32); 45259a0bf528SMauro Carvalho Chehab if (status < 0) 45269a0bf528SMauro Carvalho Chehab goto error; 45279a0bf528SMauro Carvalho Chehab 45289a0bf528SMauro Carvalho Chehab 45299a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 45309a0bf528SMauro Carvalho Chehab 45319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 45329a0bf528SMauro Carvalho Chehab if (status < 0) 45339a0bf528SMauro Carvalho Chehab goto error; 45349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 45359a0bf528SMauro Carvalho Chehab if (status < 0) 45369a0bf528SMauro Carvalho Chehab goto error; 45379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 45389a0bf528SMauro Carvalho Chehab if (status < 0) 45399a0bf528SMauro Carvalho Chehab goto error; 45409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 45419a0bf528SMauro Carvalho Chehab if (status < 0) 45429a0bf528SMauro Carvalho Chehab goto error; 45439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 45449a0bf528SMauro Carvalho Chehab if (status < 0) 45459a0bf528SMauro Carvalho Chehab goto error; 45469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 45479a0bf528SMauro Carvalho Chehab if (status < 0) 45489a0bf528SMauro Carvalho Chehab goto error; 45499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 45509a0bf528SMauro Carvalho Chehab if (status < 0) 45519a0bf528SMauro Carvalho Chehab goto error; 45529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 45539a0bf528SMauro Carvalho Chehab if (status < 0) 45549a0bf528SMauro Carvalho Chehab goto error; 45559a0bf528SMauro Carvalho Chehab 45569a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 45579a0bf528SMauro Carvalho Chehab if (status < 0) 45589a0bf528SMauro Carvalho Chehab goto error; 45599a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 45609a0bf528SMauro Carvalho Chehab if (status < 0) 45619a0bf528SMauro Carvalho Chehab goto error; 45629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 45639a0bf528SMauro Carvalho Chehab if (status < 0) 45649a0bf528SMauro Carvalho Chehab goto error; 45659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 45669a0bf528SMauro Carvalho Chehab if (status < 0) 45679a0bf528SMauro Carvalho Chehab goto error; 45689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 45699a0bf528SMauro Carvalho Chehab if (status < 0) 45709a0bf528SMauro Carvalho Chehab goto error; 45719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 45729a0bf528SMauro Carvalho Chehab if (status < 0) 45739a0bf528SMauro Carvalho Chehab goto error; 45749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 45759a0bf528SMauro Carvalho Chehab if (status < 0) 45769a0bf528SMauro Carvalho Chehab goto error; 45779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 45789a0bf528SMauro Carvalho Chehab if (status < 0) 45799a0bf528SMauro Carvalho Chehab goto error; 45809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16); 45819a0bf528SMauro Carvalho Chehab if (status < 0) 45829a0bf528SMauro Carvalho Chehab goto error; 45839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 45849a0bf528SMauro Carvalho Chehab if (status < 0) 45859a0bf528SMauro Carvalho Chehab goto error; 45869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 45879a0bf528SMauro Carvalho Chehab if (status < 0) 45889a0bf528SMauro Carvalho Chehab goto error; 45899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 45909a0bf528SMauro Carvalho Chehab if (status < 0) 45919a0bf528SMauro Carvalho Chehab goto error; 45929a0bf528SMauro Carvalho Chehab 45939a0bf528SMauro Carvalho Chehab 45949a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 45959a0bf528SMauro Carvalho Chehab 45969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90); 45979a0bf528SMauro Carvalho Chehab if (status < 0) 45989a0bf528SMauro Carvalho Chehab goto error; 45999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 46009a0bf528SMauro Carvalho Chehab if (status < 0) 46019a0bf528SMauro Carvalho Chehab goto error; 46029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 46039a0bf528SMauro Carvalho Chehab if (status < 0) 46049a0bf528SMauro Carvalho Chehab goto error; 46059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 46069a0bf528SMauro Carvalho Chehab if (status < 0) 46079a0bf528SMauro Carvalho Chehab goto error; 46089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170); 46099a0bf528SMauro Carvalho Chehab if (status < 0) 46109a0bf528SMauro Carvalho Chehab goto error; 46119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 46129a0bf528SMauro Carvalho Chehab if (status < 0) 46139a0bf528SMauro Carvalho Chehab goto error; 46149a0bf528SMauro Carvalho Chehab 46159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 46169a0bf528SMauro Carvalho Chehab if (status < 0) 46179a0bf528SMauro Carvalho Chehab goto error; 46189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 46199a0bf528SMauro Carvalho Chehab if (status < 0) 46209a0bf528SMauro Carvalho Chehab goto error; 46219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10); 46229a0bf528SMauro Carvalho Chehab if (status < 0) 46239a0bf528SMauro Carvalho Chehab goto error; 46249a0bf528SMauro Carvalho Chehab 46259a0bf528SMauro Carvalho Chehab 46269a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 46279a0bf528SMauro Carvalho Chehab 46289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 46299a0bf528SMauro Carvalho Chehab if (status < 0) 46309a0bf528SMauro Carvalho Chehab goto error; 46319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140); 46329a0bf528SMauro Carvalho Chehab if (status < 0) 46339a0bf528SMauro Carvalho Chehab goto error; 46349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8); 46359a0bf528SMauro Carvalho Chehab if (status < 0) 46369a0bf528SMauro Carvalho Chehab goto error; 46379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16); 46389a0bf528SMauro Carvalho Chehab if (status < 0) 46399a0bf528SMauro Carvalho Chehab goto error; 46409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26); 46419a0bf528SMauro Carvalho Chehab if (status < 0) 46429a0bf528SMauro Carvalho Chehab goto error; 46439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56); 46449a0bf528SMauro Carvalho Chehab if (status < 0) 46459a0bf528SMauro Carvalho Chehab goto error; 46469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86); 46479a0bf528SMauro Carvalho Chehab error: 46489a0bf528SMauro Carvalho Chehab if (status < 0) 46493a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 46509a0bf528SMauro Carvalho Chehab return status; 46519a0bf528SMauro Carvalho Chehab } 46529a0bf528SMauro Carvalho Chehab 46539a0bf528SMauro Carvalho Chehab /*============================================================================*/ 46549a0bf528SMauro Carvalho Chehab 46559a0bf528SMauro Carvalho Chehab /** 46569a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup 46579a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 46589a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 46599a0bf528SMauro Carvalho Chehab */ 4660cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state) 46619a0bf528SMauro Carvalho Chehab { 46629a0bf528SMauro Carvalho Chehab int status = 0; 46639a0bf528SMauro Carvalho Chehab 46649a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 46659a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 46669a0bf528SMauro Carvalho Chehab /* Equalizer */ 46679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336); 46689a0bf528SMauro Carvalho Chehab if (status < 0) 46699a0bf528SMauro Carvalho Chehab goto error; 46709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618); 46719a0bf528SMauro Carvalho Chehab if (status < 0) 46729a0bf528SMauro Carvalho Chehab goto error; 46739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988); 46749a0bf528SMauro Carvalho Chehab if (status < 0) 46759a0bf528SMauro Carvalho Chehab goto error; 46769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809); 46779a0bf528SMauro Carvalho Chehab if (status < 0) 46789a0bf528SMauro Carvalho Chehab goto error; 46799a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809); 46809a0bf528SMauro Carvalho Chehab if (status < 0) 46819a0bf528SMauro Carvalho Chehab goto error; 46829a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609); 46839a0bf528SMauro Carvalho Chehab if (status < 0) 46849a0bf528SMauro Carvalho Chehab goto error; 46859a0bf528SMauro Carvalho Chehab 46869a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 46879a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 4); 46889a0bf528SMauro Carvalho Chehab if (status < 0) 46899a0bf528SMauro Carvalho Chehab goto error; 46909a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 4); 46919a0bf528SMauro Carvalho Chehab if (status < 0) 46929a0bf528SMauro Carvalho Chehab goto error; 46939a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 4); 46949a0bf528SMauro Carvalho Chehab if (status < 0) 46959a0bf528SMauro Carvalho Chehab goto error; 46969a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 4); 46979a0bf528SMauro Carvalho Chehab if (status < 0) 46989a0bf528SMauro Carvalho Chehab goto error; 46999a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 47009a0bf528SMauro Carvalho Chehab if (status < 0) 47019a0bf528SMauro Carvalho Chehab goto error; 47029a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 47039a0bf528SMauro Carvalho Chehab if (status < 0) 47049a0bf528SMauro Carvalho Chehab goto error; 47059a0bf528SMauro Carvalho Chehab 47069a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 47079a0bf528SMauro Carvalho Chehab if (status < 0) 47089a0bf528SMauro Carvalho Chehab goto error; 47099a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 47109a0bf528SMauro Carvalho Chehab if (status < 0) 47119a0bf528SMauro Carvalho Chehab goto error; 47129a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 47139a0bf528SMauro Carvalho Chehab if (status < 0) 47149a0bf528SMauro Carvalho Chehab goto error; 47159a0bf528SMauro Carvalho Chehab 47169a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 4717ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4718ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM64); 47199a0bf528SMauro Carvalho Chehab if (status < 0) 47209a0bf528SMauro Carvalho Chehab goto error; 47219a0bf528SMauro Carvalho Chehab 47229a0bf528SMauro Carvalho Chehab 47239a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 47249a0bf528SMauro Carvalho Chehab 47259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 47269a0bf528SMauro Carvalho Chehab if (status < 0) 47279a0bf528SMauro Carvalho Chehab goto error; 47289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 47299a0bf528SMauro Carvalho Chehab if (status < 0) 47309a0bf528SMauro Carvalho Chehab goto error; 47319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 47329a0bf528SMauro Carvalho Chehab if (status < 0) 47339a0bf528SMauro Carvalho Chehab goto error; 47349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 47359a0bf528SMauro Carvalho Chehab if (status < 0) 47369a0bf528SMauro Carvalho Chehab goto error; 47379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 47389a0bf528SMauro Carvalho Chehab if (status < 0) 47399a0bf528SMauro Carvalho Chehab goto error; 47409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 47419a0bf528SMauro Carvalho Chehab if (status < 0) 47429a0bf528SMauro Carvalho Chehab goto error; 47439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 47449a0bf528SMauro Carvalho Chehab if (status < 0) 47459a0bf528SMauro Carvalho Chehab goto error; 47469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 47479a0bf528SMauro Carvalho Chehab if (status < 0) 47489a0bf528SMauro Carvalho Chehab goto error; 47499a0bf528SMauro Carvalho Chehab 47509a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 47519a0bf528SMauro Carvalho Chehab if (status < 0) 47529a0bf528SMauro Carvalho Chehab goto error; 47539a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30); 47549a0bf528SMauro Carvalho Chehab if (status < 0) 47559a0bf528SMauro Carvalho Chehab goto error; 47569a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100); 47579a0bf528SMauro Carvalho Chehab if (status < 0) 47589a0bf528SMauro Carvalho Chehab goto error; 47599a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 47609a0bf528SMauro Carvalho Chehab if (status < 0) 47619a0bf528SMauro Carvalho Chehab goto error; 47629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30); 47639a0bf528SMauro Carvalho Chehab if (status < 0) 47649a0bf528SMauro Carvalho Chehab goto error; 47659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 47669a0bf528SMauro Carvalho Chehab if (status < 0) 47679a0bf528SMauro Carvalho Chehab goto error; 47689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 47699a0bf528SMauro Carvalho Chehab if (status < 0) 47709a0bf528SMauro Carvalho Chehab goto error; 47719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 47729a0bf528SMauro Carvalho Chehab if (status < 0) 47739a0bf528SMauro Carvalho Chehab goto error; 47749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 47759a0bf528SMauro Carvalho Chehab if (status < 0) 47769a0bf528SMauro Carvalho Chehab goto error; 47779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 47789a0bf528SMauro Carvalho Chehab if (status < 0) 47799a0bf528SMauro Carvalho Chehab goto error; 47809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 47819a0bf528SMauro Carvalho Chehab if (status < 0) 47829a0bf528SMauro Carvalho Chehab goto error; 47839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 47849a0bf528SMauro Carvalho Chehab if (status < 0) 47859a0bf528SMauro Carvalho Chehab goto error; 47869a0bf528SMauro Carvalho Chehab 47879a0bf528SMauro Carvalho Chehab 47889a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 47899a0bf528SMauro Carvalho Chehab 47909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100); 47919a0bf528SMauro Carvalho Chehab if (status < 0) 47929a0bf528SMauro Carvalho Chehab goto error; 47939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 47949a0bf528SMauro Carvalho Chehab if (status < 0) 47959a0bf528SMauro Carvalho Chehab goto error; 47969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 47979a0bf528SMauro Carvalho Chehab if (status < 0) 47989a0bf528SMauro Carvalho Chehab goto error; 47999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110); 48009a0bf528SMauro Carvalho Chehab if (status < 0) 48019a0bf528SMauro Carvalho Chehab goto error; 48029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200); 48039a0bf528SMauro Carvalho Chehab if (status < 0) 48049a0bf528SMauro Carvalho Chehab goto error; 48059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95); 48069a0bf528SMauro Carvalho Chehab if (status < 0) 48079a0bf528SMauro Carvalho Chehab goto error; 48089a0bf528SMauro Carvalho Chehab 48099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 48109a0bf528SMauro Carvalho Chehab if (status < 0) 48119a0bf528SMauro Carvalho Chehab goto error; 48129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 48139a0bf528SMauro Carvalho Chehab if (status < 0) 48149a0bf528SMauro Carvalho Chehab goto error; 48159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15); 48169a0bf528SMauro Carvalho Chehab if (status < 0) 48179a0bf528SMauro Carvalho Chehab goto error; 48189a0bf528SMauro Carvalho Chehab 48199a0bf528SMauro Carvalho Chehab 48209a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 48219a0bf528SMauro Carvalho Chehab 48229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 48239a0bf528SMauro Carvalho Chehab if (status < 0) 48249a0bf528SMauro Carvalho Chehab goto error; 48259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141); 48269a0bf528SMauro Carvalho Chehab if (status < 0) 48279a0bf528SMauro Carvalho Chehab goto error; 48289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7); 48299a0bf528SMauro Carvalho Chehab if (status < 0) 48309a0bf528SMauro Carvalho Chehab goto error; 48319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0); 48329a0bf528SMauro Carvalho Chehab if (status < 0) 48339a0bf528SMauro Carvalho Chehab goto error; 48349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15); 48359a0bf528SMauro Carvalho Chehab if (status < 0) 48369a0bf528SMauro Carvalho Chehab goto error; 48379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45); 48389a0bf528SMauro Carvalho Chehab if (status < 0) 48399a0bf528SMauro Carvalho Chehab goto error; 48409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80); 48419a0bf528SMauro Carvalho Chehab error: 48429a0bf528SMauro Carvalho Chehab if (status < 0) 48433a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 48449a0bf528SMauro Carvalho Chehab 48459a0bf528SMauro Carvalho Chehab return status; 48469a0bf528SMauro Carvalho Chehab } 48479a0bf528SMauro Carvalho Chehab 48489a0bf528SMauro Carvalho Chehab /*============================================================================*/ 48499a0bf528SMauro Carvalho Chehab 48509a0bf528SMauro Carvalho Chehab /** 48519a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup 48529a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 48539a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 48549a0bf528SMauro Carvalho Chehab */ 4855cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state) 48569a0bf528SMauro Carvalho Chehab { 48579a0bf528SMauro Carvalho Chehab int status = 0; 48589a0bf528SMauro Carvalho Chehab 48599a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 48609a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 48619a0bf528SMauro Carvalho Chehab /* Equalizer */ 48629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564); 48639a0bf528SMauro Carvalho Chehab if (status < 0) 48649a0bf528SMauro Carvalho Chehab goto error; 48659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598); 48669a0bf528SMauro Carvalho Chehab if (status < 0) 48679a0bf528SMauro Carvalho Chehab goto error; 48689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394); 48699a0bf528SMauro Carvalho Chehab if (status < 0) 48709a0bf528SMauro Carvalho Chehab goto error; 48719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409); 48729a0bf528SMauro Carvalho Chehab if (status < 0) 48739a0bf528SMauro Carvalho Chehab goto error; 48749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656); 48759a0bf528SMauro Carvalho Chehab if (status < 0) 48769a0bf528SMauro Carvalho Chehab goto error; 48779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238); 48789a0bf528SMauro Carvalho Chehab if (status < 0) 48799a0bf528SMauro Carvalho Chehab goto error; 48809a0bf528SMauro Carvalho Chehab 48819a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 48829a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 6); 48839a0bf528SMauro Carvalho Chehab if (status < 0) 48849a0bf528SMauro Carvalho Chehab goto error; 48859a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 6); 48869a0bf528SMauro Carvalho Chehab if (status < 0) 48879a0bf528SMauro Carvalho Chehab goto error; 48889a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 6); 48899a0bf528SMauro Carvalho Chehab if (status < 0) 48909a0bf528SMauro Carvalho Chehab goto error; 48919a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 6); 48929a0bf528SMauro Carvalho Chehab if (status < 0) 48939a0bf528SMauro Carvalho Chehab goto error; 48949a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 5); 48959a0bf528SMauro Carvalho Chehab if (status < 0) 48969a0bf528SMauro Carvalho Chehab goto error; 48979a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 48989a0bf528SMauro Carvalho Chehab if (status < 0) 48999a0bf528SMauro Carvalho Chehab goto error; 49009a0bf528SMauro Carvalho Chehab 49019a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6); 49029a0bf528SMauro Carvalho Chehab if (status < 0) 49039a0bf528SMauro Carvalho Chehab goto error; 49049a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5); 49059a0bf528SMauro Carvalho Chehab if (status < 0) 49069a0bf528SMauro Carvalho Chehab goto error; 49079a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 49089a0bf528SMauro Carvalho Chehab if (status < 0) 49099a0bf528SMauro Carvalho Chehab goto error; 49109a0bf528SMauro Carvalho Chehab 49119a0bf528SMauro Carvalho Chehab 49129a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 49139a0bf528SMauro Carvalho Chehab 4914ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4915ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM128); 49169a0bf528SMauro Carvalho Chehab if (status < 0) 49179a0bf528SMauro Carvalho Chehab goto error; 49189a0bf528SMauro Carvalho Chehab 49199a0bf528SMauro Carvalho Chehab 49209a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 49219a0bf528SMauro Carvalho Chehab 49229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 49239a0bf528SMauro Carvalho Chehab if (status < 0) 49249a0bf528SMauro Carvalho Chehab goto error; 49259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 49269a0bf528SMauro Carvalho Chehab if (status < 0) 49279a0bf528SMauro Carvalho Chehab goto error; 49289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 49299a0bf528SMauro Carvalho Chehab if (status < 0) 49309a0bf528SMauro Carvalho Chehab goto error; 49319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 49329a0bf528SMauro Carvalho Chehab if (status < 0) 49339a0bf528SMauro Carvalho Chehab goto error; 49349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 49359a0bf528SMauro Carvalho Chehab if (status < 0) 49369a0bf528SMauro Carvalho Chehab goto error; 49379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 49389a0bf528SMauro Carvalho Chehab if (status < 0) 49399a0bf528SMauro Carvalho Chehab goto error; 49409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 49419a0bf528SMauro Carvalho Chehab if (status < 0) 49429a0bf528SMauro Carvalho Chehab goto error; 49439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 49449a0bf528SMauro Carvalho Chehab if (status < 0) 49459a0bf528SMauro Carvalho Chehab goto error; 49469a0bf528SMauro Carvalho Chehab 49479a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 49489a0bf528SMauro Carvalho Chehab if (status < 0) 49499a0bf528SMauro Carvalho Chehab goto error; 49509a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40); 49519a0bf528SMauro Carvalho Chehab if (status < 0) 49529a0bf528SMauro Carvalho Chehab goto error; 49539a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120); 49549a0bf528SMauro Carvalho Chehab if (status < 0) 49559a0bf528SMauro Carvalho Chehab goto error; 49569a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 49579a0bf528SMauro Carvalho Chehab if (status < 0) 49589a0bf528SMauro Carvalho Chehab goto error; 49599a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40); 49609a0bf528SMauro Carvalho Chehab if (status < 0) 49619a0bf528SMauro Carvalho Chehab goto error; 49629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60); 49639a0bf528SMauro Carvalho Chehab if (status < 0) 49649a0bf528SMauro Carvalho Chehab goto error; 49659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 49669a0bf528SMauro Carvalho Chehab if (status < 0) 49679a0bf528SMauro Carvalho Chehab goto error; 49689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 49699a0bf528SMauro Carvalho Chehab if (status < 0) 49709a0bf528SMauro Carvalho Chehab goto error; 49719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64); 49729a0bf528SMauro Carvalho Chehab if (status < 0) 49739a0bf528SMauro Carvalho Chehab goto error; 49749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 49759a0bf528SMauro Carvalho Chehab if (status < 0) 49769a0bf528SMauro Carvalho Chehab goto error; 49779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 49789a0bf528SMauro Carvalho Chehab if (status < 0) 49799a0bf528SMauro Carvalho Chehab goto error; 49809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 49819a0bf528SMauro Carvalho Chehab if (status < 0) 49829a0bf528SMauro Carvalho Chehab goto error; 49839a0bf528SMauro Carvalho Chehab 49849a0bf528SMauro Carvalho Chehab 49859a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 49869a0bf528SMauro Carvalho Chehab 49879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 49889a0bf528SMauro Carvalho Chehab if (status < 0) 49899a0bf528SMauro Carvalho Chehab goto error; 49909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 49919a0bf528SMauro Carvalho Chehab if (status < 0) 49929a0bf528SMauro Carvalho Chehab goto error; 49939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 49949a0bf528SMauro Carvalho Chehab if (status < 0) 49959a0bf528SMauro Carvalho Chehab goto error; 49969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 49979a0bf528SMauro Carvalho Chehab if (status < 0) 49989a0bf528SMauro Carvalho Chehab goto error; 49999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140); 50009a0bf528SMauro Carvalho Chehab if (status < 0) 50019a0bf528SMauro Carvalho Chehab goto error; 50029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 50039a0bf528SMauro Carvalho Chehab if (status < 0) 50049a0bf528SMauro Carvalho Chehab goto error; 50059a0bf528SMauro Carvalho Chehab 50069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 50079a0bf528SMauro Carvalho Chehab if (status < 0) 50089a0bf528SMauro Carvalho Chehab goto error; 50099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5); 50109a0bf528SMauro Carvalho Chehab if (status < 0) 50119a0bf528SMauro Carvalho Chehab goto error; 50129a0bf528SMauro Carvalho Chehab 50139a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 50149a0bf528SMauro Carvalho Chehab if (status < 0) 50159a0bf528SMauro Carvalho Chehab goto error; 50169a0bf528SMauro Carvalho Chehab 50179a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 50189a0bf528SMauro Carvalho Chehab 50199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 50209a0bf528SMauro Carvalho Chehab if (status < 0) 50219a0bf528SMauro Carvalho Chehab goto error; 50229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65); 50239a0bf528SMauro Carvalho Chehab if (status < 0) 50249a0bf528SMauro Carvalho Chehab goto error; 50259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5); 50269a0bf528SMauro Carvalho Chehab if (status < 0) 50279a0bf528SMauro Carvalho Chehab goto error; 50289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3); 50299a0bf528SMauro Carvalho Chehab if (status < 0) 50309a0bf528SMauro Carvalho Chehab goto error; 50319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1); 50329a0bf528SMauro Carvalho Chehab if (status < 0) 50339a0bf528SMauro Carvalho Chehab goto error; 50349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12); 50359a0bf528SMauro Carvalho Chehab if (status < 0) 50369a0bf528SMauro Carvalho Chehab goto error; 50379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23); 50389a0bf528SMauro Carvalho Chehab error: 50399a0bf528SMauro Carvalho Chehab if (status < 0) 50403a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 50419a0bf528SMauro Carvalho Chehab 50429a0bf528SMauro Carvalho Chehab return status; 50439a0bf528SMauro Carvalho Chehab } 50449a0bf528SMauro Carvalho Chehab 50459a0bf528SMauro Carvalho Chehab /*============================================================================*/ 50469a0bf528SMauro Carvalho Chehab 50479a0bf528SMauro Carvalho Chehab /** 50489a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup 50499a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 50509a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 50519a0bf528SMauro Carvalho Chehab */ 5052cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state) 50539a0bf528SMauro Carvalho Chehab { 50549a0bf528SMauro Carvalho Chehab int status = 0; 50559a0bf528SMauro Carvalho Chehab 50569a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 50579a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 50589a0bf528SMauro Carvalho Chehab /* Equalizer */ 50599a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502); 50609a0bf528SMauro Carvalho Chehab if (status < 0) 50619a0bf528SMauro Carvalho Chehab goto error; 50629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084); 50639a0bf528SMauro Carvalho Chehab if (status < 0) 50649a0bf528SMauro Carvalho Chehab goto error; 50659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543); 50669a0bf528SMauro Carvalho Chehab if (status < 0) 50679a0bf528SMauro Carvalho Chehab goto error; 50689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931); 50699a0bf528SMauro Carvalho Chehab if (status < 0) 50709a0bf528SMauro Carvalho Chehab goto error; 50719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629); 50729a0bf528SMauro Carvalho Chehab if (status < 0) 50739a0bf528SMauro Carvalho Chehab goto error; 50749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385); 50759a0bf528SMauro Carvalho Chehab if (status < 0) 50769a0bf528SMauro Carvalho Chehab goto error; 50779a0bf528SMauro Carvalho Chehab 50789a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 50799a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 8); 50809a0bf528SMauro Carvalho Chehab if (status < 0) 50819a0bf528SMauro Carvalho Chehab goto error; 50829a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 8); 50839a0bf528SMauro Carvalho Chehab if (status < 0) 50849a0bf528SMauro Carvalho Chehab goto error; 50859a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 8); 50869a0bf528SMauro Carvalho Chehab if (status < 0) 50879a0bf528SMauro Carvalho Chehab goto error; 50889a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 8); 50899a0bf528SMauro Carvalho Chehab if (status < 0) 50909a0bf528SMauro Carvalho Chehab goto error; 50919a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 6); 50929a0bf528SMauro Carvalho Chehab if (status < 0) 50939a0bf528SMauro Carvalho Chehab goto error; 50949a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 50959a0bf528SMauro Carvalho Chehab if (status < 0) 50969a0bf528SMauro Carvalho Chehab goto error; 50979a0bf528SMauro Carvalho Chehab 50989a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 50999a0bf528SMauro Carvalho Chehab if (status < 0) 51009a0bf528SMauro Carvalho Chehab goto error; 51019a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 51029a0bf528SMauro Carvalho Chehab if (status < 0) 51039a0bf528SMauro Carvalho Chehab goto error; 51049a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 51059a0bf528SMauro Carvalho Chehab if (status < 0) 51069a0bf528SMauro Carvalho Chehab goto error; 51079a0bf528SMauro Carvalho Chehab 51089a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 51099a0bf528SMauro Carvalho Chehab 5110ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 5111ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM256); 51129a0bf528SMauro Carvalho Chehab if (status < 0) 51139a0bf528SMauro Carvalho Chehab goto error; 51149a0bf528SMauro Carvalho Chehab 51159a0bf528SMauro Carvalho Chehab 51169a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 51179a0bf528SMauro Carvalho Chehab 51189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 51199a0bf528SMauro Carvalho Chehab if (status < 0) 51209a0bf528SMauro Carvalho Chehab goto error; 51219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 51229a0bf528SMauro Carvalho Chehab if (status < 0) 51239a0bf528SMauro Carvalho Chehab goto error; 51249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 51259a0bf528SMauro Carvalho Chehab if (status < 0) 51269a0bf528SMauro Carvalho Chehab goto error; 51279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 51289a0bf528SMauro Carvalho Chehab if (status < 0) 51299a0bf528SMauro Carvalho Chehab goto error; 51309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 51319a0bf528SMauro Carvalho Chehab if (status < 0) 51329a0bf528SMauro Carvalho Chehab goto error; 51339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 51349a0bf528SMauro Carvalho Chehab if (status < 0) 51359a0bf528SMauro Carvalho Chehab goto error; 51369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 51379a0bf528SMauro Carvalho Chehab if (status < 0) 51389a0bf528SMauro Carvalho Chehab goto error; 51399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 51409a0bf528SMauro Carvalho Chehab if (status < 0) 51419a0bf528SMauro Carvalho Chehab goto error; 51429a0bf528SMauro Carvalho Chehab 51439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 51449a0bf528SMauro Carvalho Chehab if (status < 0) 51459a0bf528SMauro Carvalho Chehab goto error; 51469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50); 51479a0bf528SMauro Carvalho Chehab if (status < 0) 51489a0bf528SMauro Carvalho Chehab goto error; 51499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250); 51509a0bf528SMauro Carvalho Chehab if (status < 0) 51519a0bf528SMauro Carvalho Chehab goto error; 51529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 51539a0bf528SMauro Carvalho Chehab if (status < 0) 51549a0bf528SMauro Carvalho Chehab goto error; 51559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50); 51569a0bf528SMauro Carvalho Chehab if (status < 0) 51579a0bf528SMauro Carvalho Chehab goto error; 51589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125); 51599a0bf528SMauro Carvalho Chehab if (status < 0) 51609a0bf528SMauro Carvalho Chehab goto error; 51619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 51629a0bf528SMauro Carvalho Chehab if (status < 0) 51639a0bf528SMauro Carvalho Chehab goto error; 51649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 51659a0bf528SMauro Carvalho Chehab if (status < 0) 51669a0bf528SMauro Carvalho Chehab goto error; 51679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 51689a0bf528SMauro Carvalho Chehab if (status < 0) 51699a0bf528SMauro Carvalho Chehab goto error; 51709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 51719a0bf528SMauro Carvalho Chehab if (status < 0) 51729a0bf528SMauro Carvalho Chehab goto error; 51739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 51749a0bf528SMauro Carvalho Chehab if (status < 0) 51759a0bf528SMauro Carvalho Chehab goto error; 51769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 51779a0bf528SMauro Carvalho Chehab if (status < 0) 51789a0bf528SMauro Carvalho Chehab goto error; 51799a0bf528SMauro Carvalho Chehab 51809a0bf528SMauro Carvalho Chehab 51819a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 51829a0bf528SMauro Carvalho Chehab 51839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 51849a0bf528SMauro Carvalho Chehab if (status < 0) 51859a0bf528SMauro Carvalho Chehab goto error; 51869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 51879a0bf528SMauro Carvalho Chehab if (status < 0) 51889a0bf528SMauro Carvalho Chehab goto error; 51899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 51909a0bf528SMauro Carvalho Chehab if (status < 0) 51919a0bf528SMauro Carvalho Chehab goto error; 51929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 51939a0bf528SMauro Carvalho Chehab if (status < 0) 51949a0bf528SMauro Carvalho Chehab goto error; 51959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150); 51969a0bf528SMauro Carvalho Chehab if (status < 0) 51979a0bf528SMauro Carvalho Chehab goto error; 51989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110); 51999a0bf528SMauro Carvalho Chehab if (status < 0) 52009a0bf528SMauro Carvalho Chehab goto error; 52019a0bf528SMauro Carvalho Chehab 52029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 52039a0bf528SMauro Carvalho Chehab if (status < 0) 52049a0bf528SMauro Carvalho Chehab goto error; 52059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 52069a0bf528SMauro Carvalho Chehab if (status < 0) 52079a0bf528SMauro Carvalho Chehab goto error; 52089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 52099a0bf528SMauro Carvalho Chehab if (status < 0) 52109a0bf528SMauro Carvalho Chehab goto error; 52119a0bf528SMauro Carvalho Chehab 52129a0bf528SMauro Carvalho Chehab 52139a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 52149a0bf528SMauro Carvalho Chehab 52159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 52169a0bf528SMauro Carvalho Chehab if (status < 0) 52179a0bf528SMauro Carvalho Chehab goto error; 52189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74); 52199a0bf528SMauro Carvalho Chehab if (status < 0) 52209a0bf528SMauro Carvalho Chehab goto error; 52219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18); 52229a0bf528SMauro Carvalho Chehab if (status < 0) 52239a0bf528SMauro Carvalho Chehab goto error; 52249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13); 52259a0bf528SMauro Carvalho Chehab if (status < 0) 52269a0bf528SMauro Carvalho Chehab goto error; 52279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7); 52289a0bf528SMauro Carvalho Chehab if (status < 0) 52299a0bf528SMauro Carvalho Chehab goto error; 52309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0); 52319a0bf528SMauro Carvalho Chehab if (status < 0) 52329a0bf528SMauro Carvalho Chehab goto error; 52339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8); 52349a0bf528SMauro Carvalho Chehab error: 52359a0bf528SMauro Carvalho Chehab if (status < 0) 52363a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 52379a0bf528SMauro Carvalho Chehab return status; 52389a0bf528SMauro Carvalho Chehab } 52399a0bf528SMauro Carvalho Chehab 52409a0bf528SMauro Carvalho Chehab 52419a0bf528SMauro Carvalho Chehab /*============================================================================*/ 52429a0bf528SMauro Carvalho Chehab /** 52439a0bf528SMauro Carvalho Chehab * \brief Reset QAM block. 52449a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 52459a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 52469a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 52479a0bf528SMauro Carvalho Chehab */ 5248cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state) 52499a0bf528SMauro Carvalho Chehab { 52509a0bf528SMauro Carvalho Chehab int status; 5251cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 52529a0bf528SMauro Carvalho Chehab 52539a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 52549a0bf528SMauro Carvalho Chehab /* Stop QAM comstate->m_exec */ 52559a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 52569a0bf528SMauro Carvalho Chehab if (status < 0) 52579a0bf528SMauro Carvalho Chehab goto error; 52589a0bf528SMauro Carvalho Chehab 5259ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 5260ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 5261ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 52629a0bf528SMauro Carvalho Chehab error: 52639a0bf528SMauro Carvalho Chehab if (status < 0) 52643a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 52659a0bf528SMauro Carvalho Chehab return status; 52669a0bf528SMauro Carvalho Chehab } 52679a0bf528SMauro Carvalho Chehab 52689a0bf528SMauro Carvalho Chehab /*============================================================================*/ 52699a0bf528SMauro Carvalho Chehab 52709a0bf528SMauro Carvalho Chehab /** 52719a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate. 52729a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 52739a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 52749a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 52759a0bf528SMauro Carvalho Chehab */ 5276cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state) 52779a0bf528SMauro Carvalho Chehab { 5278cd7a67a4SMauro Carvalho Chehab u32 adc_frequency = 0; 5279cd7a67a4SMauro Carvalho Chehab u32 symb_freq = 0; 5280cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate = 0; 52819a0bf528SMauro Carvalho Chehab u16 ratesel = 0; 5282cd7a67a4SMauro Carvalho Chehab u32 lc_symb_rate = 0; 52839a0bf528SMauro Carvalho Chehab int status; 52849a0bf528SMauro Carvalho Chehab 52859a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 52869a0bf528SMauro Carvalho Chehab /* Select & calculate correct IQM rate */ 5287cd7a67a4SMauro Carvalho Chehab adc_frequency = (state->m_sys_clock_freq * 1000) / 3; 52889a0bf528SMauro Carvalho Chehab ratesel = 0; 52899a0bf528SMauro Carvalho Chehab /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */ 52909a0bf528SMauro Carvalho Chehab if (state->props.symbol_rate <= 1188750) 52919a0bf528SMauro Carvalho Chehab ratesel = 3; 52929a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 2377500) 52939a0bf528SMauro Carvalho Chehab ratesel = 2; 52949a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 4755000) 52959a0bf528SMauro Carvalho Chehab ratesel = 1; 52969a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FD_RATESEL__A, ratesel); 52979a0bf528SMauro Carvalho Chehab if (status < 0) 52989a0bf528SMauro Carvalho Chehab goto error; 52999a0bf528SMauro Carvalho Chehab 53009a0bf528SMauro Carvalho Chehab /* 53019a0bf528SMauro Carvalho Chehab IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23) 53029a0bf528SMauro Carvalho Chehab */ 5303cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate * (1 << ratesel); 5304cd7a67a4SMauro Carvalho Chehab if (symb_freq == 0) { 53059a0bf528SMauro Carvalho Chehab /* Divide by zero */ 53069a0bf528SMauro Carvalho Chehab status = -EINVAL; 53079a0bf528SMauro Carvalho Chehab goto error; 53089a0bf528SMauro Carvalho Chehab } 5309cd7a67a4SMauro Carvalho Chehab iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) + 5310cd7a67a4SMauro Carvalho Chehab (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) - 53119a0bf528SMauro Carvalho Chehab (1 << 23); 5312cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate); 53139a0bf528SMauro Carvalho Chehab if (status < 0) 53149a0bf528SMauro Carvalho Chehab goto error; 5315cd7a67a4SMauro Carvalho Chehab state->m_iqm_rc_rate = iqm_rc_rate; 53169a0bf528SMauro Carvalho Chehab /* 5317cd7a67a4SMauro Carvalho Chehab LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15)) 53189a0bf528SMauro Carvalho Chehab */ 5319cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate; 5320cd7a67a4SMauro Carvalho Chehab if (adc_frequency == 0) { 53219a0bf528SMauro Carvalho Chehab /* Divide by zero */ 53229a0bf528SMauro Carvalho Chehab status = -EINVAL; 53239a0bf528SMauro Carvalho Chehab goto error; 53249a0bf528SMauro Carvalho Chehab } 5325cd7a67a4SMauro Carvalho Chehab lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) + 5326cd7a67a4SMauro Carvalho Chehab (Frac28a((symb_freq % adc_frequency), adc_frequency) >> 53279a0bf528SMauro Carvalho Chehab 16); 5328cd7a67a4SMauro Carvalho Chehab if (lc_symb_rate > 511) 5329cd7a67a4SMauro Carvalho Chehab lc_symb_rate = 511; 5330cd7a67a4SMauro Carvalho Chehab status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate); 53319a0bf528SMauro Carvalho Chehab 53329a0bf528SMauro Carvalho Chehab error: 53339a0bf528SMauro Carvalho Chehab if (status < 0) 53343a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 53359a0bf528SMauro Carvalho Chehab return status; 53369a0bf528SMauro Carvalho Chehab } 53379a0bf528SMauro Carvalho Chehab 53389a0bf528SMauro Carvalho Chehab /*============================================================================*/ 53399a0bf528SMauro Carvalho Chehab 53409a0bf528SMauro Carvalho Chehab /** 53419a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status. 53429a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 53439a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 53449a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 53459a0bf528SMauro Carvalho Chehab */ 53469a0bf528SMauro Carvalho Chehab 5347cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) 53489a0bf528SMauro Carvalho Chehab { 53499a0bf528SMauro Carvalho Chehab int status; 5350cd7a67a4SMauro Carvalho Chehab u16 result[2] = { 0, 0 }; 53519a0bf528SMauro Carvalho Chehab 53529a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5353cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 53549a0bf528SMauro Carvalho Chehab status = scu_command(state, 53559a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM | 53569a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, 5357cd7a67a4SMauro Carvalho Chehab result); 53589a0bf528SMauro Carvalho Chehab if (status < 0) 53593a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 53609a0bf528SMauro Carvalho Chehab 5361cd7a67a4SMauro Carvalho Chehab if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { 53629a0bf528SMauro Carvalho Chehab /* 0x0000 NOT LOCKED */ 5363cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { 53649a0bf528SMauro Carvalho Chehab /* 0x4000 DEMOD LOCKED */ 5365cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK; 5366cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { 53679a0bf528SMauro Carvalho Chehab /* 0x8000 DEMOD + FEC LOCKED (system lock) */ 5368cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK; 53699a0bf528SMauro Carvalho Chehab } else { 53709a0bf528SMauro Carvalho Chehab /* 0xC000 NEVER LOCKED */ 53719a0bf528SMauro Carvalho Chehab /* (system will never be able to lock to the signal) */ 5372ab5060cdSMauro Carvalho Chehab /* 5373ab5060cdSMauro Carvalho Chehab * TODO: check this, intermediate & standard specific lock 5374ab5060cdSMauro Carvalho Chehab * states are not taken into account here 5375ab5060cdSMauro Carvalho Chehab */ 5376cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK; 53779a0bf528SMauro Carvalho Chehab } 53789a0bf528SMauro Carvalho Chehab return status; 53799a0bf528SMauro Carvalho Chehab } 53809a0bf528SMauro Carvalho Chehab 53819a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M 0x03 53829a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL 0x00 53839a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED 0x01 53849a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON 0x02 53859a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M 0x10 53869a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL 0x10 53879a0bf528SMauro Carvalho Chehab 5388cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state, 5389cd7a67a4SMauro Carvalho Chehab int number_of_parameters) 53909a0bf528SMauro Carvalho Chehab { 53919a0bf528SMauro Carvalho Chehab int status; 5392cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 5393cd7a67a4SMauro Carvalho Chehab u16 set_param_parameters[4] = { 0, 0, 0, 0 }; 53949a0bf528SMauro Carvalho Chehab 5395cd7a67a4SMauro Carvalho Chehab set_param_parameters[0] = state->m_constellation; /* modulation */ 5396cd7a67a4SMauro Carvalho Chehab set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ 53979a0bf528SMauro Carvalho Chehab 5398cd7a67a4SMauro Carvalho Chehab if (number_of_parameters == 2) { 5399cd7a67a4SMauro Carvalho Chehab u16 set_env_parameters[1] = { 0 }; 54009a0bf528SMauro Carvalho Chehab 5401cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C) 5402cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_C; 54039a0bf528SMauro Carvalho Chehab else 5404cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_A; 54059a0bf528SMauro Carvalho Chehab 54069a0bf528SMauro Carvalho Chehab status = scu_command(state, 5407ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5408ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 5409cd7a67a4SMauro Carvalho Chehab 1, set_env_parameters, 1, &cmd_result); 54109a0bf528SMauro Carvalho Chehab if (status < 0) 54119a0bf528SMauro Carvalho Chehab goto error; 54129a0bf528SMauro Carvalho Chehab 54139a0bf528SMauro Carvalho Chehab status = scu_command(state, 5414ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5415ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 5416cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters, 5417cd7a67a4SMauro Carvalho Chehab 1, &cmd_result); 5418cd7a67a4SMauro Carvalho Chehab } else if (number_of_parameters == 4) { 5419cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C) 5420cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_C; 54219a0bf528SMauro Carvalho Chehab else 5422cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_A; 54239a0bf528SMauro Carvalho Chehab 5424cd7a67a4SMauro Carvalho Chehab set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON); 54259a0bf528SMauro Carvalho Chehab /* Env parameters */ 54269a0bf528SMauro Carvalho Chehab /* check for LOCKRANGE Extented */ 5427cd7a67a4SMauro Carvalho Chehab /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */ 54289a0bf528SMauro Carvalho Chehab 54299a0bf528SMauro Carvalho Chehab status = scu_command(state, 5430ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5431ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 5432cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters, 5433cd7a67a4SMauro Carvalho Chehab 1, &cmd_result); 54349a0bf528SMauro Carvalho Chehab } else { 54353a4398f5SMauro Carvalho Chehab pr_warn("Unknown QAM demodulator parameter count %d\n", 54363a4398f5SMauro Carvalho Chehab number_of_parameters); 543794af1b63SMauro Carvalho Chehab status = -EINVAL; 54389a0bf528SMauro Carvalho Chehab } 54399a0bf528SMauro Carvalho Chehab 54409a0bf528SMauro Carvalho Chehab error: 54419a0bf528SMauro Carvalho Chehab if (status < 0) 54423a4398f5SMauro Carvalho Chehab pr_warn("Warning %d on %s\n", status, __func__); 54439a0bf528SMauro Carvalho Chehab return status; 54449a0bf528SMauro Carvalho Chehab } 54459a0bf528SMauro Carvalho Chehab 5446cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 5447cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset) 54489a0bf528SMauro Carvalho Chehab { 54499a0bf528SMauro Carvalho Chehab int status; 5450cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 5451cd7a67a4SMauro Carvalho Chehab int qam_demod_param_count = state->qam_demod_parameter_count; 54529a0bf528SMauro Carvalho Chehab 54539a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 54549a0bf528SMauro Carvalho Chehab /* 54559a0bf528SMauro Carvalho Chehab * STEP 1: reset demodulator 54569a0bf528SMauro Carvalho Chehab * resets FEC DI and FEC RS 54579a0bf528SMauro Carvalho Chehab * resets QAM block 54589a0bf528SMauro Carvalho Chehab * resets SCU variables 54599a0bf528SMauro Carvalho Chehab */ 54609a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP); 54619a0bf528SMauro Carvalho Chehab if (status < 0) 54629a0bf528SMauro Carvalho Chehab goto error; 54639a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP); 54649a0bf528SMauro Carvalho Chehab if (status < 0) 54659a0bf528SMauro Carvalho Chehab goto error; 5466cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state); 54679a0bf528SMauro Carvalho Chehab if (status < 0) 54689a0bf528SMauro Carvalho Chehab goto error; 54699a0bf528SMauro Carvalho Chehab 54709a0bf528SMauro Carvalho Chehab /* 54719a0bf528SMauro Carvalho Chehab * STEP 2: configure demodulator 54729a0bf528SMauro Carvalho Chehab * -set params; resets IQM,QAM,FEC HW; initializes some 54739a0bf528SMauro Carvalho Chehab * SCU variables 54749a0bf528SMauro Carvalho Chehab */ 5475cd7a67a4SMauro Carvalho Chehab status = qam_set_symbolrate(state); 54769a0bf528SMauro Carvalho Chehab if (status < 0) 54779a0bf528SMauro Carvalho Chehab goto error; 54789a0bf528SMauro Carvalho Chehab 54799a0bf528SMauro Carvalho Chehab /* Set params */ 54809a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 54819a0bf528SMauro Carvalho Chehab case QAM_256: 5482cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM256; 54839a0bf528SMauro Carvalho Chehab break; 54849a0bf528SMauro Carvalho Chehab case QAM_AUTO: 54859a0bf528SMauro Carvalho Chehab case QAM_64: 5486cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM64; 54879a0bf528SMauro Carvalho Chehab break; 54889a0bf528SMauro Carvalho Chehab case QAM_16: 5489cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM16; 54909a0bf528SMauro Carvalho Chehab break; 54919a0bf528SMauro Carvalho Chehab case QAM_32: 5492cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM32; 54939a0bf528SMauro Carvalho Chehab break; 54949a0bf528SMauro Carvalho Chehab case QAM_128: 5495cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM128; 54969a0bf528SMauro Carvalho Chehab break; 54979a0bf528SMauro Carvalho Chehab default: 54989a0bf528SMauro Carvalho Chehab status = -EINVAL; 54999a0bf528SMauro Carvalho Chehab break; 55009a0bf528SMauro Carvalho Chehab } 55019a0bf528SMauro Carvalho Chehab if (status < 0) 55029a0bf528SMauro Carvalho Chehab goto error; 55039a0bf528SMauro Carvalho Chehab 55049a0bf528SMauro Carvalho Chehab /* Use the 4-parameter if it's requested or we're probing for 55059a0bf528SMauro Carvalho Chehab * the correct command. */ 55069a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 4 55079a0bf528SMauro Carvalho Chehab || !state->qam_demod_parameter_count) { 5508cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 4; 5509cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count); 55109a0bf528SMauro Carvalho Chehab } 55119a0bf528SMauro Carvalho Chehab 55129a0bf528SMauro Carvalho Chehab /* Use the 2-parameter command if it was requested or if we're 55139a0bf528SMauro Carvalho Chehab * probing for the correct command and the 4-parameter command 55149a0bf528SMauro Carvalho Chehab * failed. */ 55159a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 2 55169a0bf528SMauro Carvalho Chehab || (!state->qam_demod_parameter_count && status < 0)) { 5517cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 2; 5518cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count); 55199a0bf528SMauro Carvalho Chehab } 55209a0bf528SMauro Carvalho Chehab 55219a0bf528SMauro Carvalho Chehab if (status < 0) { 55220fb220f2SMauro Carvalho Chehab dprintk(1, "Could not set demodulator parameters.\n"); 55230fb220f2SMauro Carvalho Chehab dprintk(1, 55240fb220f2SMauro Carvalho Chehab "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n", 55259a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count, 55269a0bf528SMauro Carvalho Chehab state->microcode_name); 55279a0bf528SMauro Carvalho Chehab goto error; 55289a0bf528SMauro Carvalho Chehab } else if (!state->qam_demod_parameter_count) { 55290fb220f2SMauro Carvalho Chehab dprintk(1, 55300fb220f2SMauro Carvalho Chehab "Auto-probing the QAM command parameters was successful - using %d parameters.\n", 5531cd7a67a4SMauro Carvalho Chehab qam_demod_param_count); 55329a0bf528SMauro Carvalho Chehab 55339a0bf528SMauro Carvalho Chehab /* 55349a0bf528SMauro Carvalho Chehab * One of our commands was successful. We don't need to 55359a0bf528SMauro Carvalho Chehab * auto-probe anymore, now that we got the correct command. 55369a0bf528SMauro Carvalho Chehab */ 5537cd7a67a4SMauro Carvalho Chehab state->qam_demod_parameter_count = qam_demod_param_count; 55389a0bf528SMauro Carvalho Chehab } 55399a0bf528SMauro Carvalho Chehab 55409a0bf528SMauro Carvalho Chehab /* 55419a0bf528SMauro Carvalho Chehab * STEP 3: enable the system in a mode where the ADC provides valid 55429a0bf528SMauro Carvalho Chehab * signal setup modulation independent registers 55439a0bf528SMauro Carvalho Chehab */ 55449a0bf528SMauro Carvalho Chehab #if 0 5545cd7a67a4SMauro Carvalho Chehab status = set_frequency(channel, tuner_freq_offset)); 55469a0bf528SMauro Carvalho Chehab if (status < 0) 55479a0bf528SMauro Carvalho Chehab goto error; 55489a0bf528SMauro Carvalho Chehab #endif 5549ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz, 5550ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true); 55519a0bf528SMauro Carvalho Chehab if (status < 0) 55529a0bf528SMauro Carvalho Chehab goto error; 55539a0bf528SMauro Carvalho Chehab 55549a0bf528SMauro Carvalho Chehab /* Setup BER measurement */ 5555ab5060cdSMauro Carvalho Chehab status = set_qam_measurement(state, state->m_constellation, 5556ab5060cdSMauro Carvalho Chehab state->props.symbol_rate); 55579a0bf528SMauro Carvalho Chehab if (status < 0) 55589a0bf528SMauro Carvalho Chehab goto error; 55599a0bf528SMauro Carvalho Chehab 55609a0bf528SMauro Carvalho Chehab /* Reset default values */ 55619a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); 55629a0bf528SMauro Carvalho Chehab if (status < 0) 55639a0bf528SMauro Carvalho Chehab goto error; 55649a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); 55659a0bf528SMauro Carvalho Chehab if (status < 0) 55669a0bf528SMauro Carvalho Chehab goto error; 55679a0bf528SMauro Carvalho Chehab 55689a0bf528SMauro Carvalho Chehab /* Reset default LC values */ 55699a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_RATE_LIMIT__A, 3); 55709a0bf528SMauro Carvalho Chehab if (status < 0) 55719a0bf528SMauro Carvalho Chehab goto error; 55729a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORP__A, 4); 55739a0bf528SMauro Carvalho Chehab if (status < 0) 55749a0bf528SMauro Carvalho Chehab goto error; 55759a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORI__A, 4); 55769a0bf528SMauro Carvalho Chehab if (status < 0) 55779a0bf528SMauro Carvalho Chehab goto error; 55789a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_MODE__A, 7); 55799a0bf528SMauro Carvalho Chehab if (status < 0) 55809a0bf528SMauro Carvalho Chehab goto error; 55819a0bf528SMauro Carvalho Chehab 55829a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB0__A, 1); 55839a0bf528SMauro Carvalho Chehab if (status < 0) 55849a0bf528SMauro Carvalho Chehab goto error; 55859a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB1__A, 1); 55869a0bf528SMauro Carvalho Chehab if (status < 0) 55879a0bf528SMauro Carvalho Chehab goto error; 55889a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB2__A, 1); 55899a0bf528SMauro Carvalho Chehab if (status < 0) 55909a0bf528SMauro Carvalho Chehab goto error; 55919a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB3__A, 1); 55929a0bf528SMauro Carvalho Chehab if (status < 0) 55939a0bf528SMauro Carvalho Chehab goto error; 55949a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB4__A, 2); 55959a0bf528SMauro Carvalho Chehab if (status < 0) 55969a0bf528SMauro Carvalho Chehab goto error; 55979a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB5__A, 2); 55989a0bf528SMauro Carvalho Chehab if (status < 0) 55999a0bf528SMauro Carvalho Chehab goto error; 56009a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB6__A, 2); 56019a0bf528SMauro Carvalho Chehab if (status < 0) 56029a0bf528SMauro Carvalho Chehab goto error; 56039a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB8__A, 2); 56049a0bf528SMauro Carvalho Chehab if (status < 0) 56059a0bf528SMauro Carvalho Chehab goto error; 56069a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB9__A, 2); 56079a0bf528SMauro Carvalho Chehab if (status < 0) 56089a0bf528SMauro Carvalho Chehab goto error; 56099a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB10__A, 2); 56109a0bf528SMauro Carvalho Chehab if (status < 0) 56119a0bf528SMauro Carvalho Chehab goto error; 56129a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB12__A, 2); 56139a0bf528SMauro Carvalho Chehab if (status < 0) 56149a0bf528SMauro Carvalho Chehab goto error; 56159a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB15__A, 3); 56169a0bf528SMauro Carvalho Chehab if (status < 0) 56179a0bf528SMauro Carvalho Chehab goto error; 56189a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB16__A, 3); 56199a0bf528SMauro Carvalho Chehab if (status < 0) 56209a0bf528SMauro Carvalho Chehab goto error; 56219a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB20__A, 4); 56229a0bf528SMauro Carvalho Chehab if (status < 0) 56239a0bf528SMauro Carvalho Chehab goto error; 56249a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB25__A, 4); 56259a0bf528SMauro Carvalho Chehab if (status < 0) 56269a0bf528SMauro Carvalho Chehab goto error; 56279a0bf528SMauro Carvalho Chehab 56289a0bf528SMauro Carvalho Chehab /* Mirroring, QAM-block starting point not inverted */ 5629ab5060cdSMauro Carvalho Chehab status = write16(state, QAM_SY_SP_INV__A, 5630ab5060cdSMauro Carvalho Chehab QAM_SY_SP_INV_SPECTRUM_INV_DIS); 56319a0bf528SMauro Carvalho Chehab if (status < 0) 56329a0bf528SMauro Carvalho Chehab goto error; 56339a0bf528SMauro Carvalho Chehab 56349a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 56359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 56369a0bf528SMauro Carvalho Chehab if (status < 0) 56379a0bf528SMauro Carvalho Chehab goto error; 56389a0bf528SMauro Carvalho Chehab 56399a0bf528SMauro Carvalho Chehab /* STEP 4: modulation specific setup */ 56409a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 56419a0bf528SMauro Carvalho Chehab case QAM_16: 5642cd7a67a4SMauro Carvalho Chehab status = set_qam16(state); 56439a0bf528SMauro Carvalho Chehab break; 56449a0bf528SMauro Carvalho Chehab case QAM_32: 5645cd7a67a4SMauro Carvalho Chehab status = set_qam32(state); 56469a0bf528SMauro Carvalho Chehab break; 56479a0bf528SMauro Carvalho Chehab case QAM_AUTO: 56489a0bf528SMauro Carvalho Chehab case QAM_64: 5649cd7a67a4SMauro Carvalho Chehab status = set_qam64(state); 56509a0bf528SMauro Carvalho Chehab break; 56519a0bf528SMauro Carvalho Chehab case QAM_128: 5652cd7a67a4SMauro Carvalho Chehab status = set_qam128(state); 56539a0bf528SMauro Carvalho Chehab break; 56549a0bf528SMauro Carvalho Chehab case QAM_256: 5655cd7a67a4SMauro Carvalho Chehab status = set_qam256(state); 56569a0bf528SMauro Carvalho Chehab break; 56579a0bf528SMauro Carvalho Chehab default: 56589a0bf528SMauro Carvalho Chehab status = -EINVAL; 56599a0bf528SMauro Carvalho Chehab break; 56609a0bf528SMauro Carvalho Chehab } 56619a0bf528SMauro Carvalho Chehab if (status < 0) 56629a0bf528SMauro Carvalho Chehab goto error; 56639a0bf528SMauro Carvalho Chehab 56649a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 56659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 56669a0bf528SMauro Carvalho Chehab if (status < 0) 56679a0bf528SMauro Carvalho Chehab goto error; 56689a0bf528SMauro Carvalho Chehab 56699a0bf528SMauro Carvalho Chehab /* Re-configure MPEG output, requires knowledge of channel bitrate */ 56709a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.modulation = channel->modulation; */ 56719a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ 5672cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, state->m_operation_mode); 56739a0bf528SMauro Carvalho Chehab if (status < 0) 56749a0bf528SMauro Carvalho Chehab goto error; 56759a0bf528SMauro Carvalho Chehab 5676cd7a67a4SMauro Carvalho Chehab /* start processes */ 5677cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state); 56789a0bf528SMauro Carvalho Chehab if (status < 0) 56799a0bf528SMauro Carvalho Chehab goto error; 56809a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 56819a0bf528SMauro Carvalho Chehab if (status < 0) 56829a0bf528SMauro Carvalho Chehab goto error; 56839a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE); 56849a0bf528SMauro Carvalho Chehab if (status < 0) 56859a0bf528SMauro Carvalho Chehab goto error; 56869a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 56879a0bf528SMauro Carvalho Chehab if (status < 0) 56889a0bf528SMauro Carvalho Chehab goto error; 56899a0bf528SMauro Carvalho Chehab 56909a0bf528SMauro Carvalho Chehab /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */ 5691ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 5692ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START, 5693ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 56949a0bf528SMauro Carvalho Chehab if (status < 0) 56959a0bf528SMauro Carvalho Chehab goto error; 56969a0bf528SMauro Carvalho Chehab 56979a0bf528SMauro Carvalho Chehab /* update global DRXK data container */ 56989a0bf528SMauro Carvalho Chehab /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */ 56999a0bf528SMauro Carvalho Chehab 57009a0bf528SMauro Carvalho Chehab error: 57019a0bf528SMauro Carvalho Chehab if (status < 0) 57023a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 57039a0bf528SMauro Carvalho Chehab return status; 57049a0bf528SMauro Carvalho Chehab } 57059a0bf528SMauro Carvalho Chehab 5706cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state, 5707cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 57089a0bf528SMauro Carvalho Chehab { 57099a0bf528SMauro Carvalho Chehab int status; 57109a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS 57119a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT 57129a0bf528SMauro Carvalho Chehab #include "drxk_filters.h" 57139a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT 57149a0bf528SMauro Carvalho Chehab #endif 57159a0bf528SMauro Carvalho Chehab 57169a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 57179a0bf528SMauro Carvalho Chehab 57189a0bf528SMauro Carvalho Chehab /* added antenna switch */ 5719cd7a67a4SMauro Carvalho Chehab switch_antenna_to_qam(state); 57209a0bf528SMauro Carvalho Chehab 57219a0bf528SMauro Carvalho Chehab /* Ensure correct power-up mode */ 5722cd7a67a4SMauro Carvalho Chehab status = power_up_qam(state); 57239a0bf528SMauro Carvalho Chehab if (status < 0) 57249a0bf528SMauro Carvalho Chehab goto error; 57259a0bf528SMauro Carvalho Chehab /* Reset QAM block */ 5726cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state); 57279a0bf528SMauro Carvalho Chehab if (status < 0) 57289a0bf528SMauro Carvalho Chehab goto error; 57299a0bf528SMauro Carvalho Chehab 57309a0bf528SMauro Carvalho Chehab /* Setup IQM */ 57319a0bf528SMauro Carvalho Chehab 57329a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 57339a0bf528SMauro Carvalho Chehab if (status < 0) 57349a0bf528SMauro Carvalho Chehab goto error; 57359a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 57369a0bf528SMauro Carvalho Chehab if (status < 0) 57379a0bf528SMauro Carvalho Chehab goto error; 57389a0bf528SMauro Carvalho Chehab 57399a0bf528SMauro Carvalho Chehab /* Upload IQM Channel Filter settings by 57409a0bf528SMauro Carvalho Chehab boot loader from ROM table */ 5741cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 57429a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 5743ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, 5744ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS, 5745ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57469a0bf528SMauro Carvalho Chehab break; 57479a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 5748ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, 5749ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 5750ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS, 5751ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57529a0bf528SMauro Carvalho Chehab if (status < 0) 57539a0bf528SMauro Carvalho Chehab goto error; 5754ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state, 5755ab5060cdSMauro Carvalho Chehab IQM_CF_TAP_IM0__A, 5756ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 5757ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS, 5758ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57599a0bf528SMauro Carvalho Chehab break; 57609a0bf528SMauro Carvalho Chehab default: 57619a0bf528SMauro Carvalho Chehab status = -EINVAL; 57629a0bf528SMauro Carvalho Chehab } 57639a0bf528SMauro Carvalho Chehab if (status < 0) 57649a0bf528SMauro Carvalho Chehab goto error; 57659a0bf528SMauro Carvalho Chehab 5766ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B); 57679a0bf528SMauro Carvalho Chehab if (status < 0) 57689a0bf528SMauro Carvalho Chehab goto error; 57699a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SYMMETRIC__A, 0); 57709a0bf528SMauro Carvalho Chehab if (status < 0) 57719a0bf528SMauro Carvalho Chehab goto error; 5772ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_MIDTAP__A, 5773ab5060cdSMauro Carvalho Chehab ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); 57749a0bf528SMauro Carvalho Chehab if (status < 0) 57759a0bf528SMauro Carvalho Chehab goto error; 57769a0bf528SMauro Carvalho Chehab 57779a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 21); 57789a0bf528SMauro Carvalho Chehab if (status < 0) 57799a0bf528SMauro Carvalho Chehab goto error; 57809a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0); 57819a0bf528SMauro Carvalho Chehab if (status < 0) 57829a0bf528SMauro Carvalho Chehab goto error; 57839a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448); 57849a0bf528SMauro Carvalho Chehab if (status < 0) 57859a0bf528SMauro Carvalho Chehab goto error; 57869a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0); 57879a0bf528SMauro Carvalho Chehab if (status < 0) 57889a0bf528SMauro Carvalho Chehab goto error; 57899a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0); 57909a0bf528SMauro Carvalho Chehab if (status < 0) 57919a0bf528SMauro Carvalho Chehab goto error; 57929a0bf528SMauro Carvalho Chehab 57939a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FS_ADJ_SEL__A, 1); 57949a0bf528SMauro Carvalho Chehab if (status < 0) 57959a0bf528SMauro Carvalho Chehab goto error; 57969a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_ADJ_SEL__A, 1); 57979a0bf528SMauro Carvalho Chehab if (status < 0) 57989a0bf528SMauro Carvalho Chehab goto error; 57999a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_ADJ_SEL__A, 1); 58009a0bf528SMauro Carvalho Chehab if (status < 0) 58019a0bf528SMauro Carvalho Chehab goto error; 58029a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 0); 58039a0bf528SMauro Carvalho Chehab if (status < 0) 58049a0bf528SMauro Carvalho Chehab goto error; 58059a0bf528SMauro Carvalho Chehab 58069a0bf528SMauro Carvalho Chehab /* IQM Impulse Noise Processing Unit */ 58079a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_CLP_VAL__A, 500); 58089a0bf528SMauro Carvalho Chehab if (status < 0) 58099a0bf528SMauro Carvalho Chehab goto error; 58109a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 1000); 58119a0bf528SMauro Carvalho Chehab if (status < 0) 58129a0bf528SMauro Carvalho Chehab goto error; 58139a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1); 58149a0bf528SMauro Carvalho Chehab if (status < 0) 58159a0bf528SMauro Carvalho Chehab goto error; 58169a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0); 58179a0bf528SMauro Carvalho Chehab if (status < 0) 58189a0bf528SMauro Carvalho Chehab goto error; 58199a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 1); 58209a0bf528SMauro Carvalho Chehab if (status < 0) 58219a0bf528SMauro Carvalho Chehab goto error; 58229a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 1); 58239a0bf528SMauro Carvalho Chehab if (status < 0) 58249a0bf528SMauro Carvalho Chehab goto error; 58259a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_BYPASS__A, 1); 58269a0bf528SMauro Carvalho Chehab if (status < 0) 58279a0bf528SMauro Carvalho Chehab goto error; 58289a0bf528SMauro Carvalho Chehab 58299a0bf528SMauro Carvalho Chehab /* turn on IQMAF. Must be done before setAgc**() */ 5830cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true); 58319a0bf528SMauro Carvalho Chehab if (status < 0) 58329a0bf528SMauro Carvalho Chehab goto error; 58339a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 0x01); 58349a0bf528SMauro Carvalho Chehab if (status < 0) 58359a0bf528SMauro Carvalho Chehab goto error; 58369a0bf528SMauro Carvalho Chehab 58379a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */ 5838cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state); 58399a0bf528SMauro Carvalho Chehab if (status < 0) 58409a0bf528SMauro Carvalho Chehab goto error; 58419a0bf528SMauro Carvalho Chehab 58429a0bf528SMauro Carvalho Chehab /* Set the FSM step period */ 58439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000); 58449a0bf528SMauro Carvalho Chehab if (status < 0) 58459a0bf528SMauro Carvalho Chehab goto error; 58469a0bf528SMauro Carvalho Chehab 58479a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 58489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 58499a0bf528SMauro Carvalho Chehab if (status < 0) 58509a0bf528SMauro Carvalho Chehab goto error; 58519a0bf528SMauro Carvalho Chehab 58529a0bf528SMauro Carvalho Chehab /* No more resets of the IQM, current standard correctly set => 58539a0bf528SMauro Carvalho Chehab now AGCs can be configured. */ 58549a0bf528SMauro Carvalho Chehab 5855cd7a67a4SMauro Carvalho Chehab status = init_agc(state, true); 58569a0bf528SMauro Carvalho Chehab if (status < 0) 58579a0bf528SMauro Carvalho Chehab goto error; 5858cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg)); 58599a0bf528SMauro Carvalho Chehab if (status < 0) 58609a0bf528SMauro Carvalho Chehab goto error; 58619a0bf528SMauro Carvalho Chehab 58629a0bf528SMauro Carvalho Chehab /* Configure AGC's */ 5863cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true); 58649a0bf528SMauro Carvalho Chehab if (status < 0) 58659a0bf528SMauro Carvalho Chehab goto error; 5866cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true); 58679a0bf528SMauro Carvalho Chehab if (status < 0) 58689a0bf528SMauro Carvalho Chehab goto error; 58699a0bf528SMauro Carvalho Chehab 58709a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 58719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 58729a0bf528SMauro Carvalho Chehab error: 58739a0bf528SMauro Carvalho Chehab if (status < 0) 58743a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 58759a0bf528SMauro Carvalho Chehab return status; 58769a0bf528SMauro Carvalho Chehab } 58779a0bf528SMauro Carvalho Chehab 5878cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state) 58799a0bf528SMauro Carvalho Chehab { 58809a0bf528SMauro Carvalho Chehab int status; 58819a0bf528SMauro Carvalho Chehab u16 value = 0; 58829a0bf528SMauro Carvalho Chehab 58839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 58849a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 5885ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 5886ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 58879a0bf528SMauro Carvalho Chehab if (status < 0) 58889a0bf528SMauro Carvalho Chehab goto error; 58899a0bf528SMauro Carvalho Chehab 58909a0bf528SMauro Carvalho Chehab /* Write magic word to enable pdr reg write */ 58919a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 58929a0bf528SMauro Carvalho Chehab if (status < 0) 58939a0bf528SMauro Carvalho Chehab goto error; 58949a0bf528SMauro Carvalho Chehab 5895cd7a67a4SMauro Carvalho Chehab if (state->m_has_sawsw) { 5896cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0001) { /* UIO-1 */ 58979a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5898ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_TX_CFG__A, 5899ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 59009a0bf528SMauro Carvalho Chehab if (status < 0) 59019a0bf528SMauro Carvalho Chehab goto error; 59029a0bf528SMauro Carvalho Chehab 59039a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 59049a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59059a0bf528SMauro Carvalho Chehab if (status < 0) 59069a0bf528SMauro Carvalho Chehab goto error; 5907cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0001) == 0) 59089a0bf528SMauro Carvalho Chehab value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ 59099a0bf528SMauro Carvalho Chehab else 59109a0bf528SMauro Carvalho Chehab value |= 0x8000; /* write one to 15th bit - 1st UIO */ 59119a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 59129a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59139a0bf528SMauro Carvalho Chehab if (status < 0) 59149a0bf528SMauro Carvalho Chehab goto error; 59159a0bf528SMauro Carvalho Chehab } 5916cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0002) { /* UIO-2 */ 59179a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5918ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_RX_CFG__A, 5919ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 59209a0bf528SMauro Carvalho Chehab if (status < 0) 59219a0bf528SMauro Carvalho Chehab goto error; 59229a0bf528SMauro Carvalho Chehab 59239a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 59249a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59259a0bf528SMauro Carvalho Chehab if (status < 0) 59269a0bf528SMauro Carvalho Chehab goto error; 5927cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0002) == 0) 59289a0bf528SMauro Carvalho Chehab value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ 59299a0bf528SMauro Carvalho Chehab else 59309a0bf528SMauro Carvalho Chehab value |= 0x4000; /* write one to 14th bit - 2st UIO */ 59319a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 59329a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59339a0bf528SMauro Carvalho Chehab if (status < 0) 59349a0bf528SMauro Carvalho Chehab goto error; 59359a0bf528SMauro Carvalho Chehab } 5936cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0004) { /* UIO-3 */ 59379a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5938ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_GPIO_CFG__A, 5939ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 59409a0bf528SMauro Carvalho Chehab if (status < 0) 59419a0bf528SMauro Carvalho Chehab goto error; 59429a0bf528SMauro Carvalho Chehab 59439a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 59449a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59459a0bf528SMauro Carvalho Chehab if (status < 0) 59469a0bf528SMauro Carvalho Chehab goto error; 5947cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0004) == 0) 59489a0bf528SMauro Carvalho Chehab value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ 59499a0bf528SMauro Carvalho Chehab else 59509a0bf528SMauro Carvalho Chehab value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ 59519a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 59529a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59539a0bf528SMauro Carvalho Chehab if (status < 0) 59549a0bf528SMauro Carvalho Chehab goto error; 59559a0bf528SMauro Carvalho Chehab } 59569a0bf528SMauro Carvalho Chehab } 59579a0bf528SMauro Carvalho Chehab /* Write magic word to disable pdr reg write */ 59589a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 59599a0bf528SMauro Carvalho Chehab error: 59609a0bf528SMauro Carvalho Chehab if (status < 0) 59613a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 59629a0bf528SMauro Carvalho Chehab return status; 59639a0bf528SMauro Carvalho Chehab } 59649a0bf528SMauro Carvalho Chehab 5965cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state) 59669a0bf528SMauro Carvalho Chehab { 59679a0bf528SMauro Carvalho Chehab int status = 0; 59689a0bf528SMauro Carvalho Chehab bool gpio_state; 59699a0bf528SMauro Carvalho Chehab 59709a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 59719a0bf528SMauro Carvalho Chehab 59729a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio) 59739a0bf528SMauro Carvalho Chehab return 0; 59749a0bf528SMauro Carvalho Chehab 5975cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio; 59769a0bf528SMauro Carvalho Chehab 59779a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt ^ gpio_state) { 59789a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-T mode. Switch */ 59799a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt) 5980cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 59819a0bf528SMauro Carvalho Chehab else 5982cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 5983cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 59849a0bf528SMauro Carvalho Chehab } 59859a0bf528SMauro Carvalho Chehab if (status < 0) 59863a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 59879a0bf528SMauro Carvalho Chehab return status; 59889a0bf528SMauro Carvalho Chehab } 59899a0bf528SMauro Carvalho Chehab 5990cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state) 59919a0bf528SMauro Carvalho Chehab { 59929a0bf528SMauro Carvalho Chehab int status = 0; 59939a0bf528SMauro Carvalho Chehab bool gpio_state; 59949a0bf528SMauro Carvalho Chehab 59959a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 59969a0bf528SMauro Carvalho Chehab 59979a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio) 59989a0bf528SMauro Carvalho Chehab return 0; 59999a0bf528SMauro Carvalho Chehab 6000cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio; 60019a0bf528SMauro Carvalho Chehab 60029a0bf528SMauro Carvalho Chehab if (!(state->antenna_dvbt ^ gpio_state)) { 60039a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-C mode. Switch */ 60049a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt) 6005cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 60069a0bf528SMauro Carvalho Chehab else 6007cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 6008cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 60099a0bf528SMauro Carvalho Chehab } 60109a0bf528SMauro Carvalho Chehab if (status < 0) 60113a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 60129a0bf528SMauro Carvalho Chehab return status; 60139a0bf528SMauro Carvalho Chehab } 60149a0bf528SMauro Carvalho Chehab 60159a0bf528SMauro Carvalho Chehab 6016cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state) 60179a0bf528SMauro Carvalho Chehab { 60189a0bf528SMauro Carvalho Chehab /* Power down to requested mode */ 60199a0bf528SMauro Carvalho Chehab /* Backup some register settings */ 60209a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected to them in input mode */ 60219a0bf528SMauro Carvalho Chehab /* Analog power down */ 60229a0bf528SMauro Carvalho Chehab /* ADC power down */ 60239a0bf528SMauro Carvalho Chehab /* Power down device */ 60249a0bf528SMauro Carvalho Chehab int status; 60259a0bf528SMauro Carvalho Chehab 60269a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 6027cd7a67a4SMauro Carvalho Chehab if (state->m_b_p_down_open_bridge) { 60289a0bf528SMauro Carvalho Chehab /* Open I2C bridge before power down of DRXK */ 60299a0bf528SMauro Carvalho Chehab status = ConfigureI2CBridge(state, true); 60309a0bf528SMauro Carvalho Chehab if (status < 0) 60319a0bf528SMauro Carvalho Chehab goto error; 60329a0bf528SMauro Carvalho Chehab } 60339a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 6034cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false); 60359a0bf528SMauro Carvalho Chehab if (status < 0) 60369a0bf528SMauro Carvalho Chehab goto error; 60379a0bf528SMauro Carvalho Chehab 6038ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, 6039ab5060cdSMauro Carvalho Chehab SIO_CC_PWD_MODE_LEVEL_CLOCK); 60409a0bf528SMauro Carvalho Chehab if (status < 0) 60419a0bf528SMauro Carvalho Chehab goto error; 60429a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60439a0bf528SMauro Carvalho Chehab if (status < 0) 60449a0bf528SMauro Carvalho Chehab goto error; 6045cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 6046cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state); 60479a0bf528SMauro Carvalho Chehab error: 60489a0bf528SMauro Carvalho Chehab if (status < 0) 60493a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 60509a0bf528SMauro Carvalho Chehab 60519a0bf528SMauro Carvalho Chehab return status; 60529a0bf528SMauro Carvalho Chehab } 60539a0bf528SMauro Carvalho Chehab 60549a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state) 60559a0bf528SMauro Carvalho Chehab { 60569a0bf528SMauro Carvalho Chehab int status = 0, n = 0; 6057cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 6058cd7a67a4SMauro Carvalho Chehab u16 driver_version; 60599a0bf528SMauro Carvalho Chehab 60609a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 6061cd7a67a4SMauro Carvalho Chehab if ((state->m_drxk_state == DRXK_UNINITIALIZED)) { 60629a0bf528SMauro Carvalho Chehab drxk_i2c_lock(state); 6063cd7a67a4SMauro Carvalho Chehab status = power_up_device(state); 60649a0bf528SMauro Carvalho Chehab if (status < 0) 60659a0bf528SMauro Carvalho Chehab goto error; 6066cd7a67a4SMauro Carvalho Chehab status = drxx_open(state); 60679a0bf528SMauro Carvalho Chehab if (status < 0) 60689a0bf528SMauro Carvalho Chehab goto error; 60699a0bf528SMauro Carvalho Chehab /* Soft reset of OFDM-, sys- and osc-clockdomain */ 6070ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_SOFT_RST__A, 6071ab5060cdSMauro Carvalho Chehab SIO_CC_SOFT_RST_OFDM__M 6072ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_SYS__M 6073ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_OSC__M); 60749a0bf528SMauro Carvalho Chehab if (status < 0) 60759a0bf528SMauro Carvalho Chehab goto error; 60769a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60779a0bf528SMauro Carvalho Chehab if (status < 0) 60789a0bf528SMauro Carvalho Chehab goto error; 6079ab5060cdSMauro Carvalho Chehab /* 6080ab5060cdSMauro Carvalho Chehab * TODO is this needed? If yes, how much delay in 6081ab5060cdSMauro Carvalho Chehab * worst case scenario 6082ab5060cdSMauro Carvalho Chehab */ 6083b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 6084cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = true; 6085cd7a67a4SMauro Carvalho Chehab status = get_device_capabilities(state); 60869a0bf528SMauro Carvalho Chehab if (status < 0) 60879a0bf528SMauro Carvalho Chehab goto error; 60889a0bf528SMauro Carvalho Chehab 60899a0bf528SMauro Carvalho Chehab /* Bridge delay, uses oscilator clock */ 60909a0bf528SMauro Carvalho Chehab /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */ 60919a0bf528SMauro Carvalho Chehab /* SDA brdige delay */ 6092cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay = 6093cd7a67a4SMauro Carvalho Chehab (u16) ((state->m_osc_clock_freq / 1000) * 60949a0bf528SMauro Carvalho Chehab HI_I2C_BRIDGE_DELAY) / 1000; 60959a0bf528SMauro Carvalho Chehab /* Clipping */ 6096cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_bridge_delay > 60979a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) { 6098cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay = 60999a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M; 61009a0bf528SMauro Carvalho Chehab } 61019a0bf528SMauro Carvalho Chehab /* SCL bridge delay, same as SDA for now */ 6102cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay += 6103cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay << 61049a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B; 61059a0bf528SMauro Carvalho Chehab 6106cd7a67a4SMauro Carvalho Chehab status = init_hi(state); 61079a0bf528SMauro Carvalho Chehab if (status < 0) 61089a0bf528SMauro Carvalho Chehab goto error; 61099a0bf528SMauro Carvalho Chehab /* disable various processes */ 61109a0bf528SMauro Carvalho Chehab #if NOA1ROM 61119a0bf528SMauro Carvalho Chehab if (!(state->m_DRXK_A1_ROM_CODE) 61129a0bf528SMauro Carvalho Chehab && !(state->m_DRXK_A2_ROM_CODE)) 61139a0bf528SMauro Carvalho Chehab #endif 61149a0bf528SMauro Carvalho Chehab { 6115ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 6116ab5060cdSMauro Carvalho Chehab 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 */ 6122cd7a67a4SMauro Carvalho Chehab status = mpegts_disable(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 */ 6135ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 6136ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_ON); 61379a0bf528SMauro Carvalho Chehab if (status < 0) 61389a0bf528SMauro Carvalho Chehab goto error; 61399a0bf528SMauro Carvalho Chehab 61409a0bf528SMauro Carvalho Chehab /* include boot loader section */ 6141ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_BL_COMM_EXEC__A, 6142ab5060cdSMauro Carvalho Chehab SIO_BL_COMM_EXEC_ACTIVE); 61439a0bf528SMauro Carvalho Chehab if (status < 0) 61449a0bf528SMauro Carvalho Chehab goto error; 6145cd7a67a4SMauro Carvalho Chehab status = bl_chain_cmd(state, 0, 6, 100); 61469a0bf528SMauro Carvalho Chehab if (status < 0) 61479a0bf528SMauro Carvalho Chehab goto error; 61489a0bf528SMauro Carvalho Chehab 61499a0bf528SMauro Carvalho Chehab if (state->fw) { 6150cd7a67a4SMauro Carvalho Chehab status = download_microcode(state, state->fw->data, 61519a0bf528SMauro Carvalho Chehab state->fw->size); 61529a0bf528SMauro Carvalho Chehab if (status < 0) 61539a0bf528SMauro Carvalho Chehab goto error; 61549a0bf528SMauro Carvalho Chehab } 61559a0bf528SMauro Carvalho Chehab 61569a0bf528SMauro Carvalho Chehab /* disable token-ring bus through OFDM block for possible ucode upload */ 6157ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 6158ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); 61599a0bf528SMauro Carvalho Chehab if (status < 0) 61609a0bf528SMauro Carvalho Chehab goto error; 61619a0bf528SMauro Carvalho Chehab 61629a0bf528SMauro Carvalho Chehab /* Run SCU for a little while to initialize microcode version numbers */ 61639a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 61649a0bf528SMauro Carvalho Chehab if (status < 0) 61659a0bf528SMauro Carvalho Chehab goto error; 6166cd7a67a4SMauro Carvalho Chehab status = drxx_open(state); 61679a0bf528SMauro Carvalho Chehab if (status < 0) 61689a0bf528SMauro Carvalho Chehab goto error; 61699a0bf528SMauro Carvalho Chehab /* added for test */ 61709a0bf528SMauro Carvalho Chehab msleep(30); 61719a0bf528SMauro Carvalho Chehab 6172cd7a67a4SMauro Carvalho Chehab power_mode = DRXK_POWER_DOWN_OFDM; 6173cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 61749a0bf528SMauro Carvalho Chehab if (status < 0) 61759a0bf528SMauro Carvalho Chehab goto error; 61769a0bf528SMauro Carvalho Chehab 61779a0bf528SMauro Carvalho Chehab /* Stamp driver version number in SCU data RAM in BCD code 617839c1cb2bSJonathan McCrohan Done to enable field application engineers to retrieve drxdriver version 61799a0bf528SMauro Carvalho Chehab via I2C from SCU RAM. 61809a0bf528SMauro Carvalho Chehab Not using SCU command interface for SCU register access since no 61819a0bf528SMauro Carvalho Chehab microcode may be present. 61829a0bf528SMauro Carvalho Chehab */ 6183cd7a67a4SMauro Carvalho Chehab driver_version = 61849a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 100) % 10) << 12) + 61859a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 10) % 10) << 8) + 61869a0bf528SMauro Carvalho Chehab ((DRXK_VERSION_MAJOR % 10) << 4) + 61879a0bf528SMauro Carvalho Chehab (DRXK_VERSION_MINOR % 10); 6188ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_HI__A, 6189ab5060cdSMauro Carvalho Chehab driver_version); 61909a0bf528SMauro Carvalho Chehab if (status < 0) 61919a0bf528SMauro Carvalho Chehab goto error; 6192cd7a67a4SMauro Carvalho Chehab driver_version = 61939a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 1000) % 10) << 12) + 61949a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 100) % 10) << 8) + 61959a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 10) % 10) << 4) + 61969a0bf528SMauro Carvalho Chehab (DRXK_VERSION_PATCH % 10); 6197ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_LO__A, 6198ab5060cdSMauro Carvalho Chehab driver_version); 61999a0bf528SMauro Carvalho Chehab if (status < 0) 62009a0bf528SMauro Carvalho Chehab goto error; 62019a0bf528SMauro Carvalho Chehab 62023a4398f5SMauro Carvalho Chehab pr_info("DRXK driver version %d.%d.%d\n", 62039a0bf528SMauro Carvalho Chehab DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR, 62049a0bf528SMauro Carvalho Chehab DRXK_VERSION_PATCH); 62059a0bf528SMauro Carvalho Chehab 6206ab5060cdSMauro Carvalho Chehab /* 6207ab5060cdSMauro Carvalho Chehab * Dirty fix of default values for ROM/PATCH microcode 6208ab5060cdSMauro Carvalho Chehab * Dirty because this fix makes it impossible to setup 6209ab5060cdSMauro Carvalho Chehab * suitable values before calling DRX_Open. This solution 6210ab5060cdSMauro Carvalho Chehab * requires changes to RF AGC speed to be done via the CTRL 6211ab5060cdSMauro Carvalho Chehab * function after calling DRX_Open 6212ab5060cdSMauro Carvalho Chehab */ 62139a0bf528SMauro Carvalho Chehab 6214cd7a67a4SMauro Carvalho Chehab /* m_dvbt_rf_agc_cfg.speed = 3; */ 62159a0bf528SMauro Carvalho Chehab 62169a0bf528SMauro Carvalho Chehab /* Reset driver debug flags to 0 */ 62179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0); 62189a0bf528SMauro Carvalho Chehab if (status < 0) 62199a0bf528SMauro Carvalho Chehab goto error; 62209a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 62219a0bf528SMauro Carvalho Chehab /* Setup FEC OC: 62229a0bf528SMauro Carvalho Chehab NOTE: No more full FEC resets allowed afterwards!! */ 62239a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP); 62249a0bf528SMauro Carvalho Chehab if (status < 0) 62259a0bf528SMauro Carvalho Chehab goto error; 62269a0bf528SMauro Carvalho Chehab /* MPEGTS functions are still the same */ 6227cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_init(state); 62289a0bf528SMauro Carvalho Chehab if (status < 0) 62299a0bf528SMauro Carvalho Chehab goto error; 6230cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 62319a0bf528SMauro Carvalho Chehab if (status < 0) 62329a0bf528SMauro Carvalho Chehab goto error; 6233cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_polarity(state); 62349a0bf528SMauro Carvalho Chehab if (status < 0) 62359a0bf528SMauro Carvalho Chehab goto error; 6236cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_pins(state, state->m_enable_mpeg_output); 62379a0bf528SMauro Carvalho Chehab if (status < 0) 62389a0bf528SMauro Carvalho Chehab goto error; 62399a0bf528SMauro Carvalho Chehab /* added: configure GPIO */ 6240cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 62419a0bf528SMauro Carvalho Chehab if (status < 0) 62429a0bf528SMauro Carvalho Chehab goto error; 62439a0bf528SMauro Carvalho Chehab 6244cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED; 62459a0bf528SMauro Carvalho Chehab 6246cd7a67a4SMauro Carvalho Chehab if (state->m_b_power_down) { 6247cd7a67a4SMauro Carvalho Chehab status = power_down_device(state); 62489a0bf528SMauro Carvalho Chehab if (status < 0) 62499a0bf528SMauro Carvalho Chehab goto error; 6250cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_POWERED_DOWN; 62519a0bf528SMauro Carvalho Chehab } else 6252cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED; 62539a0bf528SMauro Carvalho Chehab 62549a0bf528SMauro Carvalho Chehab /* Initialize the supported delivery systems */ 62559a0bf528SMauro Carvalho Chehab n = 0; 6256cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbc) { 62579a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; 62589a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; 62599a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-C", 62609a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name)); 62619a0bf528SMauro Carvalho Chehab } 6262cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbt) { 62639a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBT; 62649a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-T", 62659a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name)); 62669a0bf528SMauro Carvalho Chehab } 62679a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state); 62689a0bf528SMauro Carvalho Chehab } 62699a0bf528SMauro Carvalho Chehab error: 62709a0bf528SMauro Carvalho Chehab if (status < 0) { 6271cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_NO_DEV; 62729a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state); 62733a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 62749a0bf528SMauro Carvalho Chehab } 62759a0bf528SMauro Carvalho Chehab 62769a0bf528SMauro Carvalho Chehab return status; 62779a0bf528SMauro Carvalho Chehab } 62789a0bf528SMauro Carvalho Chehab 62799a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw, 62809a0bf528SMauro Carvalho Chehab void *context) 62819a0bf528SMauro Carvalho Chehab { 62829a0bf528SMauro Carvalho Chehab struct drxk_state *state = context; 62839a0bf528SMauro Carvalho Chehab 62849a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); 62859a0bf528SMauro Carvalho Chehab if (!fw) { 62863a4398f5SMauro Carvalho Chehab pr_err("Could not load firmware file %s.\n", 62879a0bf528SMauro Carvalho Chehab state->microcode_name); 62883a4398f5SMauro Carvalho Chehab pr_info("Copy %s to your hotplug directory!\n", 62899a0bf528SMauro Carvalho Chehab state->microcode_name); 62909a0bf528SMauro Carvalho Chehab state->microcode_name = NULL; 62919a0bf528SMauro Carvalho Chehab 62929a0bf528SMauro Carvalho Chehab /* 62939a0bf528SMauro Carvalho Chehab * As firmware is now load asynchronous, it is not possible 62949a0bf528SMauro Carvalho Chehab * anymore to fail at frontend attach. We might silently 62959a0bf528SMauro Carvalho Chehab * return here, and hope that the driver won't crash. 62969a0bf528SMauro Carvalho Chehab * We might also change all DVB callbacks to return -ENODEV 62979a0bf528SMauro Carvalho Chehab * if the device is not initialized. 62989a0bf528SMauro Carvalho Chehab * As the DRX-K devices have their own internal firmware, 62999a0bf528SMauro Carvalho Chehab * let's just hope that it will match a firmware revision 63009a0bf528SMauro Carvalho Chehab * compatible with this driver and proceed. 63019a0bf528SMauro Carvalho Chehab */ 63029a0bf528SMauro Carvalho Chehab } 63039a0bf528SMauro Carvalho Chehab state->fw = fw; 63049a0bf528SMauro Carvalho Chehab 63059a0bf528SMauro Carvalho Chehab init_drxk(state); 63069a0bf528SMauro Carvalho Chehab } 63079a0bf528SMauro Carvalho Chehab 63089a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe) 63099a0bf528SMauro Carvalho Chehab { 63109a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63119a0bf528SMauro Carvalho Chehab 63129a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 63139a0bf528SMauro Carvalho Chehab if (state->fw) 63149a0bf528SMauro Carvalho Chehab release_firmware(state->fw); 63159a0bf528SMauro Carvalho Chehab 63169a0bf528SMauro Carvalho Chehab kfree(state); 63179a0bf528SMauro Carvalho Chehab } 63189a0bf528SMauro Carvalho Chehab 63199a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe) 63209a0bf528SMauro Carvalho Chehab { 63219a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63229a0bf528SMauro Carvalho Chehab 63239a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 63249a0bf528SMauro Carvalho Chehab 6325cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 63269a0bf528SMauro Carvalho Chehab return -ENODEV; 6327cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 63289a0bf528SMauro Carvalho Chehab return 0; 63299a0bf528SMauro Carvalho Chehab 6330cd7a67a4SMauro Carvalho Chehab shut_down(state); 63319a0bf528SMauro Carvalho Chehab return 0; 63329a0bf528SMauro Carvalho Chehab } 63339a0bf528SMauro Carvalho Chehab 63349a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 63359a0bf528SMauro Carvalho Chehab { 63369a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63379a0bf528SMauro Carvalho Chehab 63389a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", enable ? "enable" : "disable"); 63399a0bf528SMauro Carvalho Chehab 6340cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 63419a0bf528SMauro Carvalho Chehab return -ENODEV; 63429a0bf528SMauro Carvalho Chehab 63439a0bf528SMauro Carvalho Chehab return ConfigureI2CBridge(state, enable ? true : false); 63449a0bf528SMauro Carvalho Chehab } 63459a0bf528SMauro Carvalho Chehab 63469a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe) 63479a0bf528SMauro Carvalho Chehab { 63489a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 63499a0bf528SMauro Carvalho Chehab u32 delsys = p->delivery_system, old_delsys; 63509a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63519a0bf528SMauro Carvalho Chehab u32 IF; 63529a0bf528SMauro Carvalho Chehab 63539a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 63549a0bf528SMauro Carvalho Chehab 6355cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 63569a0bf528SMauro Carvalho Chehab return -ENODEV; 63579a0bf528SMauro Carvalho Chehab 6358cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 63599a0bf528SMauro Carvalho Chehab return -EAGAIN; 63609a0bf528SMauro Carvalho Chehab 63619a0bf528SMauro Carvalho Chehab if (!fe->ops.tuner_ops.get_if_frequency) { 63623a4398f5SMauro Carvalho Chehab pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); 63639a0bf528SMauro Carvalho Chehab return -EINVAL; 63649a0bf528SMauro Carvalho Chehab } 63659a0bf528SMauro Carvalho Chehab 63669a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl) 63679a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1); 63689a0bf528SMauro Carvalho Chehab if (fe->ops.tuner_ops.set_params) 63699a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 63709a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl) 63719a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 0); 63729a0bf528SMauro Carvalho Chehab 63739a0bf528SMauro Carvalho Chehab old_delsys = state->props.delivery_system; 63749a0bf528SMauro Carvalho Chehab state->props = *p; 63759a0bf528SMauro Carvalho Chehab 63769a0bf528SMauro Carvalho Chehab if (old_delsys != delsys) { 6377cd7a67a4SMauro Carvalho Chehab shut_down(state); 63789a0bf528SMauro Carvalho Chehab switch (delsys) { 63799a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A: 63809a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C: 6381cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbc) 63829a0bf528SMauro Carvalho Chehab return -EINVAL; 6383ab5060cdSMauro Carvalho Chehab state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? 6384ab5060cdSMauro Carvalho Chehab true : false; 63859a0bf528SMauro Carvalho Chehab if (state->m_itut_annex_c) 6386cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_C); 63879a0bf528SMauro Carvalho Chehab else 6388cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_A); 63899a0bf528SMauro Carvalho Chehab break; 63909a0bf528SMauro Carvalho Chehab case SYS_DVBT: 6391cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbt) 63929a0bf528SMauro Carvalho Chehab return -EINVAL; 6393cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_DVBT); 63949a0bf528SMauro Carvalho Chehab break; 63959a0bf528SMauro Carvalho Chehab default: 63969a0bf528SMauro Carvalho Chehab return -EINVAL; 63979a0bf528SMauro Carvalho Chehab } 63989a0bf528SMauro Carvalho Chehab } 63999a0bf528SMauro Carvalho Chehab 64009a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.get_if_frequency(fe, &IF); 6401cd7a67a4SMauro Carvalho Chehab start(state, 0, IF); 64029a0bf528SMauro Carvalho Chehab 640339c1cb2bSJonathan McCrohan /* After set_frontend, stats aren't available */ 64048f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 64058f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64068f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64078f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64088f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64098f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64108f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64118f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 64128f3741e0SMauro Carvalho Chehab 64139a0bf528SMauro Carvalho Chehab /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */ 64149a0bf528SMauro Carvalho Chehab 64159a0bf528SMauro Carvalho Chehab return 0; 64169a0bf528SMauro Carvalho Chehab } 64179a0bf528SMauro Carvalho Chehab 641859a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength) 641959a7a23cSMauro Carvalho Chehab { 642059a7a23cSMauro Carvalho Chehab int status; 6421cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc rf_agc, if_agc; 6422cd7a67a4SMauro Carvalho Chehab u32 total_gain = 0; 642359a7a23cSMauro Carvalho Chehab u32 atten = 0; 6424cd7a67a4SMauro Carvalho Chehab u32 agc_range = 0; 642559a7a23cSMauro Carvalho Chehab u16 scu_lvl = 0; 642659a7a23cSMauro Carvalho Chehab u16 scu_coc = 0; 642759a7a23cSMauro Carvalho Chehab /* FIXME: those are part of the tuner presets */ 6428cd7a67a4SMauro Carvalho Chehab u16 tuner_rf_gain = 50; /* Default value on az6007 driver */ 6429cd7a67a4SMauro Carvalho Chehab u16 tuner_if_gain = 40; /* Default value on az6007 driver */ 643059a7a23cSMauro Carvalho Chehab 643159a7a23cSMauro Carvalho Chehab *strength = 0; 643259a7a23cSMauro Carvalho Chehab 6433cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state)) { 6434cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_dvbt_rf_agc_cfg; 6435cd7a67a4SMauro Carvalho Chehab if_agc = state->m_dvbt_if_agc_cfg; 6436cd7a67a4SMauro Carvalho Chehab } else if (is_qam(state)) { 6437cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_qam_rf_agc_cfg; 6438cd7a67a4SMauro Carvalho Chehab if_agc = state->m_qam_if_agc_cfg; 643959a7a23cSMauro Carvalho Chehab } else { 6440cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_atv_rf_agc_cfg; 6441cd7a67a4SMauro Carvalho Chehab if_agc = state->m_atv_if_agc_cfg; 644259a7a23cSMauro Carvalho Chehab } 644359a7a23cSMauro Carvalho Chehab 6444cd7a67a4SMauro Carvalho Chehab if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 6445cd7a67a4SMauro Carvalho Chehab /* SCU output_level */ 644659a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl); 644759a7a23cSMauro Carvalho Chehab if (status < 0) 644859a7a23cSMauro Carvalho Chehab return status; 644959a7a23cSMauro Carvalho Chehab 645059a7a23cSMauro Carvalho Chehab /* SCU c.o.c. */ 645159a7a23cSMauro Carvalho Chehab read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); 645259a7a23cSMauro Carvalho Chehab if (status < 0) 645359a7a23cSMauro Carvalho Chehab return status; 645459a7a23cSMauro Carvalho Chehab 645559a7a23cSMauro Carvalho Chehab if (((u32) scu_lvl + (u32) scu_coc) < 0xffff) 6456cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = scu_lvl + scu_coc; 645759a7a23cSMauro Carvalho Chehab else 6458cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = 0xffff; 645959a7a23cSMauro Carvalho Chehab 646059a7a23cSMauro Carvalho Chehab /* Take RF gain into account */ 6461cd7a67a4SMauro Carvalho Chehab total_gain += tuner_rf_gain; 646259a7a23cSMauro Carvalho Chehab 646359a7a23cSMauro Carvalho Chehab /* clip output value */ 6464cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level < rf_agc.min_output_level) 6465cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.min_output_level; 6466cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level > rf_agc.max_output_level) 6467cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.max_output_level; 646859a7a23cSMauro Carvalho Chehab 6469cd7a67a4SMauro Carvalho Chehab agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level); 6470cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) { 647159a7a23cSMauro Carvalho Chehab atten += 100UL * 6472cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_rf_gain)) * 6473cd7a67a4SMauro Carvalho Chehab ((u32)(rf_agc.output_level - rf_agc.min_output_level)) 6474cd7a67a4SMauro Carvalho Chehab / agc_range; 647559a7a23cSMauro Carvalho Chehab } 647659a7a23cSMauro Carvalho Chehab } 647759a7a23cSMauro Carvalho Chehab 6478cd7a67a4SMauro Carvalho Chehab if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 647959a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 6480cd7a67a4SMauro Carvalho Chehab &if_agc.output_level); 648159a7a23cSMauro Carvalho Chehab if (status < 0) 648259a7a23cSMauro Carvalho Chehab return status; 648359a7a23cSMauro Carvalho Chehab 648459a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, 6485cd7a67a4SMauro Carvalho Chehab &if_agc.top); 648659a7a23cSMauro Carvalho Chehab if (status < 0) 648759a7a23cSMauro Carvalho Chehab return status; 648859a7a23cSMauro Carvalho Chehab 648959a7a23cSMauro Carvalho Chehab /* Take IF gain into account */ 6490cd7a67a4SMauro Carvalho Chehab total_gain += (u32) tuner_if_gain; 649159a7a23cSMauro Carvalho Chehab 649259a7a23cSMauro Carvalho Chehab /* clip output value */ 6493cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level < if_agc.min_output_level) 6494cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.min_output_level; 6495cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level > if_agc.max_output_level) 6496cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.max_output_level; 649759a7a23cSMauro Carvalho Chehab 6498cd7a67a4SMauro Carvalho Chehab agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level); 6499cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) { 650059a7a23cSMauro Carvalho Chehab atten += 100UL * 6501cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_if_gain)) * 6502cd7a67a4SMauro Carvalho Chehab ((u32)(if_agc.output_level - if_agc.min_output_level)) 6503cd7a67a4SMauro Carvalho Chehab / agc_range; 650459a7a23cSMauro Carvalho Chehab } 650559a7a23cSMauro Carvalho Chehab } 650659a7a23cSMauro Carvalho Chehab 650759a7a23cSMauro Carvalho Chehab /* 650859a7a23cSMauro Carvalho Chehab * Convert to 0..65535 scale. 650959a7a23cSMauro Carvalho Chehab * If it can't be measured (AGC is disabled), just show 100%. 651059a7a23cSMauro Carvalho Chehab */ 6511cd7a67a4SMauro Carvalho Chehab if (total_gain > 0) 6512cd7a67a4SMauro Carvalho Chehab *strength = (65535UL * atten / total_gain / 100); 651359a7a23cSMauro Carvalho Chehab else 651459a7a23cSMauro Carvalho Chehab *strength = 65535; 651559a7a23cSMauro Carvalho Chehab 651659a7a23cSMauro Carvalho Chehab return 0; 651759a7a23cSMauro Carvalho Chehab } 651859a7a23cSMauro Carvalho Chehab 65198f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe) 65209a0bf528SMauro Carvalho Chehab { 65218f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 65229a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 65238f3741e0SMauro Carvalho Chehab int status; 65249a0bf528SMauro Carvalho Chehab u32 stat; 65258f3741e0SMauro Carvalho Chehab u16 reg16; 65268f3741e0SMauro Carvalho Chehab u32 post_bit_count; 65278f3741e0SMauro Carvalho Chehab u32 post_bit_err_count; 65288f3741e0SMauro Carvalho Chehab u32 post_bit_error_scale; 65298f3741e0SMauro Carvalho Chehab u32 pre_bit_err_count; 65308f3741e0SMauro Carvalho Chehab u32 pre_bit_count; 65318f3741e0SMauro Carvalho Chehab u32 pkt_count; 65328f3741e0SMauro Carvalho Chehab u32 pkt_error_count; 653359a7a23cSMauro Carvalho Chehab s32 cnr; 65349a0bf528SMauro Carvalho Chehab 6535cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 65369a0bf528SMauro Carvalho Chehab return -ENODEV; 6537cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 65389a0bf528SMauro Carvalho Chehab return -EAGAIN; 65399a0bf528SMauro Carvalho Chehab 65408f3741e0SMauro Carvalho Chehab /* get status */ 65418f3741e0SMauro Carvalho Chehab state->fe_status = 0; 6542cd7a67a4SMauro Carvalho Chehab get_lock_status(state, &stat); 65439a0bf528SMauro Carvalho Chehab if (stat == MPEG_LOCK) 65448f3741e0SMauro Carvalho Chehab state->fe_status |= 0x1f; 65459a0bf528SMauro Carvalho Chehab if (stat == FEC_LOCK) 65468f3741e0SMauro Carvalho Chehab state->fe_status |= 0x0f; 65479a0bf528SMauro Carvalho Chehab if (stat == DEMOD_LOCK) 65488f3741e0SMauro Carvalho Chehab state->fe_status |= 0x07; 65498f3741e0SMauro Carvalho Chehab 655059a7a23cSMauro Carvalho Chehab /* 655159a7a23cSMauro Carvalho Chehab * Estimate signal strength from AGC 655259a7a23cSMauro Carvalho Chehab */ 655359a7a23cSMauro Carvalho Chehab get_strength(state, &c->strength.stat[0].uvalue); 655459a7a23cSMauro Carvalho Chehab c->strength.stat[0].scale = FE_SCALE_RELATIVE; 655559a7a23cSMauro Carvalho Chehab 655659a7a23cSMauro Carvalho Chehab 65578f3741e0SMauro Carvalho Chehab if (stat >= DEMOD_LOCK) { 6558cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &cnr); 65598f3741e0SMauro Carvalho Chehab c->cnr.stat[0].svalue = cnr * 100; 65608f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 65618f3741e0SMauro Carvalho Chehab } else { 65628f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65638f3741e0SMauro Carvalho Chehab } 65648f3741e0SMauro Carvalho Chehab 65658f3741e0SMauro Carvalho Chehab if (stat < FEC_LOCK) { 65668f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65678f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65688f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65698f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65708f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65718f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65728f3741e0SMauro Carvalho Chehab return 0; 65738f3741e0SMauro Carvalho Chehab } 65748f3741e0SMauro Carvalho Chehab 65758f3741e0SMauro Carvalho Chehab /* Get post BER */ 65768f3741e0SMauro Carvalho Chehab 65778f3741e0SMauro Carvalho Chehab /* BER measurement is valid if at least FEC lock is achieved */ 65788f3741e0SMauro Carvalho Chehab 6579ab5060cdSMauro Carvalho Chehab /* 6580ab5060cdSMauro Carvalho Chehab * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be 6581ab5060cdSMauro Carvalho Chehab * written to set nr of symbols or bits over which to measure 6582ab5060cdSMauro Carvalho Chehab * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). 6583ab5060cdSMauro Carvalho Chehab */ 65848f3741e0SMauro Carvalho Chehab 65858f3741e0SMauro Carvalho Chehab /* Read registers for post/preViterbi BER calculation */ 65868f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16); 65878f3741e0SMauro Carvalho Chehab if (status < 0) 65888f3741e0SMauro Carvalho Chehab goto error; 65898f3741e0SMauro Carvalho Chehab pre_bit_err_count = reg16; 65908f3741e0SMauro Carvalho Chehab 65918f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16); 65928f3741e0SMauro Carvalho Chehab if (status < 0) 65938f3741e0SMauro Carvalho Chehab goto error; 65948f3741e0SMauro Carvalho Chehab pre_bit_count = reg16; 65958f3741e0SMauro Carvalho Chehab 65968f3741e0SMauro Carvalho Chehab /* Number of bit-errors */ 65978f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16); 65988f3741e0SMauro Carvalho Chehab if (status < 0) 65998f3741e0SMauro Carvalho Chehab goto error; 66008f3741e0SMauro Carvalho Chehab post_bit_err_count = reg16; 66018f3741e0SMauro Carvalho Chehab 66028f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16); 66038f3741e0SMauro Carvalho Chehab if (status < 0) 66048f3741e0SMauro Carvalho Chehab goto error; 66058f3741e0SMauro Carvalho Chehab post_bit_error_scale = reg16; 66068f3741e0SMauro Carvalho Chehab 66078f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16); 66088f3741e0SMauro Carvalho Chehab if (status < 0) 66098f3741e0SMauro Carvalho Chehab goto error; 66108f3741e0SMauro Carvalho Chehab pkt_count = reg16; 66118f3741e0SMauro Carvalho Chehab 66128f3741e0SMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16); 66138f3741e0SMauro Carvalho Chehab if (status < 0) 66148f3741e0SMauro Carvalho Chehab goto error; 66158f3741e0SMauro Carvalho Chehab pkt_error_count = reg16; 66168f3741e0SMauro Carvalho Chehab write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 66178f3741e0SMauro Carvalho Chehab 66188f3741e0SMauro Carvalho Chehab post_bit_err_count *= post_bit_error_scale; 66198f3741e0SMauro Carvalho Chehab 66208f3741e0SMauro Carvalho Chehab post_bit_count = pkt_count * 204 * 8; 66218f3741e0SMauro Carvalho Chehab 66228f3741e0SMauro Carvalho Chehab /* Store the results */ 66238f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_COUNTER; 66248f3741e0SMauro Carvalho Chehab c->block_error.stat[0].uvalue += pkt_error_count; 66258f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_COUNTER; 66268f3741e0SMauro Carvalho Chehab c->block_count.stat[0].uvalue += pkt_count; 66278f3741e0SMauro Carvalho Chehab 66288f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; 66298f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].uvalue += pre_bit_err_count; 66308f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; 66318f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].uvalue += pre_bit_count; 66328f3741e0SMauro Carvalho Chehab 66338f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 66348f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].uvalue += post_bit_err_count; 66358f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 66368f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].uvalue += post_bit_count; 66378f3741e0SMauro Carvalho Chehab 66388f3741e0SMauro Carvalho Chehab error: 66398f3741e0SMauro Carvalho Chehab return status; 66408f3741e0SMauro Carvalho Chehab } 66418f3741e0SMauro Carvalho Chehab 66428f3741e0SMauro Carvalho Chehab 66438f3741e0SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) 66448f3741e0SMauro Carvalho Chehab { 66458f3741e0SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 66468f3741e0SMauro Carvalho Chehab int rc; 66478f3741e0SMauro Carvalho Chehab 66488f3741e0SMauro Carvalho Chehab dprintk(1, "\n"); 66498f3741e0SMauro Carvalho Chehab 66508f3741e0SMauro Carvalho Chehab rc = drxk_get_stats(fe); 66518f3741e0SMauro Carvalho Chehab if (rc < 0) 66528f3741e0SMauro Carvalho Chehab return rc; 66538f3741e0SMauro Carvalho Chehab 66548f3741e0SMauro Carvalho Chehab *status = state->fe_status; 66558f3741e0SMauro Carvalho Chehab 66569a0bf528SMauro Carvalho Chehab return 0; 66579a0bf528SMauro Carvalho Chehab } 66589a0bf528SMauro Carvalho Chehab 66599a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe, 66609a0bf528SMauro Carvalho Chehab u16 *strength) 66619a0bf528SMauro Carvalho Chehab { 66629a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 6663340e7696SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 66649a0bf528SMauro Carvalho Chehab 66659a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 66669a0bf528SMauro Carvalho Chehab 6667cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 66689a0bf528SMauro Carvalho Chehab return -ENODEV; 6669cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 66709a0bf528SMauro Carvalho Chehab return -EAGAIN; 66719a0bf528SMauro Carvalho Chehab 6672340e7696SMauro Carvalho Chehab *strength = c->strength.stat[0].uvalue; 66739a0bf528SMauro Carvalho Chehab return 0; 66749a0bf528SMauro Carvalho Chehab } 66759a0bf528SMauro Carvalho Chehab 66769a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) 66779a0bf528SMauro Carvalho Chehab { 66789a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 66799a0bf528SMauro Carvalho Chehab s32 snr2; 66809a0bf528SMauro Carvalho Chehab 66819a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 66829a0bf528SMauro Carvalho Chehab 6683cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 66849a0bf528SMauro Carvalho Chehab return -ENODEV; 6685cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 66869a0bf528SMauro Carvalho Chehab return -EAGAIN; 66879a0bf528SMauro Carvalho Chehab 6688cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &snr2); 66898f3741e0SMauro Carvalho Chehab 66908f3741e0SMauro Carvalho Chehab /* No negative SNR, clip to zero */ 66918f3741e0SMauro Carvalho Chehab if (snr2 < 0) 66928f3741e0SMauro Carvalho Chehab snr2 = 0; 66939a0bf528SMauro Carvalho Chehab *snr = snr2 & 0xffff; 66949a0bf528SMauro Carvalho Chehab return 0; 66959a0bf528SMauro Carvalho Chehab } 66969a0bf528SMauro Carvalho Chehab 66979a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 66989a0bf528SMauro Carvalho Chehab { 66999a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 67009a0bf528SMauro Carvalho Chehab u16 err; 67019a0bf528SMauro Carvalho Chehab 67029a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 67039a0bf528SMauro Carvalho Chehab 6704cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 67059a0bf528SMauro Carvalho Chehab return -ENODEV; 6706cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 67079a0bf528SMauro Carvalho Chehab return -EAGAIN; 67089a0bf528SMauro Carvalho Chehab 6709cd7a67a4SMauro Carvalho Chehab dvbtqam_get_acc_pkt_err(state, &err); 67109a0bf528SMauro Carvalho Chehab *ucblocks = (u32) err; 67119a0bf528SMauro Carvalho Chehab return 0; 67129a0bf528SMauro Carvalho Chehab } 67139a0bf528SMauro Carvalho Chehab 6714ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe, 6715ab5060cdSMauro Carvalho Chehab struct dvb_frontend_tune_settings *sets) 67169a0bf528SMauro Carvalho Chehab { 67179a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 67189a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 67199a0bf528SMauro Carvalho Chehab 67209a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 67219a0bf528SMauro Carvalho Chehab 6722cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 67239a0bf528SMauro Carvalho Chehab return -ENODEV; 6724cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 67259a0bf528SMauro Carvalho Chehab return -EAGAIN; 67269a0bf528SMauro Carvalho Chehab 67279a0bf528SMauro Carvalho Chehab switch (p->delivery_system) { 67289a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A: 67299a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C: 67309a0bf528SMauro Carvalho Chehab case SYS_DVBT: 67319a0bf528SMauro Carvalho Chehab sets->min_delay_ms = 3000; 67329a0bf528SMauro Carvalho Chehab sets->max_drift = 0; 67339a0bf528SMauro Carvalho Chehab sets->step_size = 0; 67349a0bf528SMauro Carvalho Chehab return 0; 67359a0bf528SMauro Carvalho Chehab default: 67369a0bf528SMauro Carvalho Chehab return -EINVAL; 67379a0bf528SMauro Carvalho Chehab } 67389a0bf528SMauro Carvalho Chehab } 67399a0bf528SMauro Carvalho Chehab 67409a0bf528SMauro Carvalho Chehab static struct dvb_frontend_ops drxk_ops = { 67419a0bf528SMauro Carvalho Chehab /* .delsys will be filled dynamically */ 67429a0bf528SMauro Carvalho Chehab .info = { 67439a0bf528SMauro Carvalho Chehab .name = "DRXK", 67449a0bf528SMauro Carvalho Chehab .frequency_min = 47000000, 67459a0bf528SMauro Carvalho Chehab .frequency_max = 865000000, 67469a0bf528SMauro Carvalho Chehab /* For DVB-C */ 67479a0bf528SMauro Carvalho Chehab .symbol_rate_min = 870000, 67489a0bf528SMauro Carvalho Chehab .symbol_rate_max = 11700000, 67499a0bf528SMauro Carvalho Chehab /* For DVB-T */ 67509a0bf528SMauro Carvalho Chehab .frequency_stepsize = 166667, 67519a0bf528SMauro Carvalho Chehab 67529a0bf528SMauro Carvalho Chehab .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | 67539a0bf528SMauro Carvalho Chehab FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO | 67549a0bf528SMauro Carvalho Chehab FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 67559a0bf528SMauro Carvalho Chehab FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS | 67569a0bf528SMauro Carvalho Chehab FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER | 67579a0bf528SMauro Carvalho Chehab FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO 67589a0bf528SMauro Carvalho Chehab }, 67599a0bf528SMauro Carvalho Chehab 67609a0bf528SMauro Carvalho Chehab .release = drxk_release, 67619a0bf528SMauro Carvalho Chehab .sleep = drxk_sleep, 67629a0bf528SMauro Carvalho Chehab .i2c_gate_ctrl = drxk_gate_ctrl, 67639a0bf528SMauro Carvalho Chehab 67649a0bf528SMauro Carvalho Chehab .set_frontend = drxk_set_parameters, 67659a0bf528SMauro Carvalho Chehab .get_tune_settings = drxk_get_tune_settings, 67669a0bf528SMauro Carvalho Chehab 67679a0bf528SMauro Carvalho Chehab .read_status = drxk_read_status, 67689a0bf528SMauro Carvalho Chehab .read_signal_strength = drxk_read_signal_strength, 67699a0bf528SMauro Carvalho Chehab .read_snr = drxk_read_snr, 67709a0bf528SMauro Carvalho Chehab .read_ucblocks = drxk_read_ucblocks, 67719a0bf528SMauro Carvalho Chehab }; 67729a0bf528SMauro Carvalho Chehab 67739a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config, 67749a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c) 67759a0bf528SMauro Carvalho Chehab { 67768f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *p; 67779a0bf528SMauro Carvalho Chehab struct drxk_state *state = NULL; 67789a0bf528SMauro Carvalho Chehab u8 adr = config->adr; 67799a0bf528SMauro Carvalho Chehab int status; 67809a0bf528SMauro Carvalho Chehab 67819a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 67829a0bf528SMauro Carvalho Chehab state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); 67839a0bf528SMauro Carvalho Chehab if (!state) 67849a0bf528SMauro Carvalho Chehab return NULL; 67859a0bf528SMauro Carvalho Chehab 67869a0bf528SMauro Carvalho Chehab state->i2c = i2c; 67879a0bf528SMauro Carvalho Chehab state->demod_address = adr; 67889a0bf528SMauro Carvalho Chehab state->single_master = config->single_master; 67899a0bf528SMauro Carvalho Chehab state->microcode_name = config->microcode_name; 67909a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count = config->qam_demod_parameter_count; 67919a0bf528SMauro Carvalho Chehab state->no_i2c_bridge = config->no_i2c_bridge; 67929a0bf528SMauro Carvalho Chehab state->antenna_gpio = config->antenna_gpio; 67939a0bf528SMauro Carvalho Chehab state->antenna_dvbt = config->antenna_dvbt; 6794cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = config->chunk_size; 67959a0bf528SMauro Carvalho Chehab state->enable_merr_cfg = config->enable_merr_cfg; 67969a0bf528SMauro Carvalho Chehab 67979a0bf528SMauro Carvalho Chehab if (config->dynamic_clk) { 67985a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = false; 67995a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = false; 68009a0bf528SMauro Carvalho Chehab } else { 68015a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = true; 68025a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = true; 68039a0bf528SMauro Carvalho Chehab } 68049a0bf528SMauro Carvalho Chehab 68059a0bf528SMauro Carvalho Chehab 68069a0bf528SMauro Carvalho Chehab if (config->mpeg_out_clk_strength) 6807cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; 68089a0bf528SMauro Carvalho Chehab else 6809cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = 0x06; 68109a0bf528SMauro Carvalho Chehab 68119a0bf528SMauro Carvalho Chehab if (config->parallel_ts) 6812cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = true; 68139a0bf528SMauro Carvalho Chehab else 6814cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = false; 68159a0bf528SMauro Carvalho Chehab 68169a0bf528SMauro Carvalho Chehab /* NOTE: as more UIO bits will be used, add them to the mask */ 6817cd7a67a4SMauro Carvalho Chehab state->uio_mask = config->antenna_gpio; 68189a0bf528SMauro Carvalho Chehab 68199a0bf528SMauro Carvalho Chehab /* Default gpio to DVB-C */ 68209a0bf528SMauro Carvalho Chehab if (!state->antenna_dvbt && state->antenna_gpio) 6821cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 68229a0bf528SMauro Carvalho Chehab else 6823cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 68249a0bf528SMauro Carvalho Chehab 68259a0bf528SMauro Carvalho Chehab mutex_init(&state->mutex); 68269a0bf528SMauro Carvalho Chehab 68279a0bf528SMauro Carvalho Chehab memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops)); 68289a0bf528SMauro Carvalho Chehab state->frontend.demodulator_priv = state; 68299a0bf528SMauro Carvalho Chehab 68309a0bf528SMauro Carvalho Chehab init_state(state); 68319a0bf528SMauro Carvalho Chehab 68329a0bf528SMauro Carvalho Chehab /* Load firmware and initialize DRX-K */ 68339a0bf528SMauro Carvalho Chehab if (state->microcode_name) { 68348e30783bSMauro Carvalho Chehab const struct firmware *fw = NULL; 68358e30783bSMauro Carvalho Chehab 68368e30783bSMauro Carvalho Chehab status = request_firmware(&fw, state->microcode_name, 68378e30783bSMauro Carvalho Chehab state->i2c->dev.parent); 68388e30783bSMauro Carvalho Chehab if (status < 0) 68398e30783bSMauro Carvalho Chehab fw = NULL; 68408e30783bSMauro Carvalho Chehab load_firmware_cb(fw, state); 68419a0bf528SMauro Carvalho Chehab } else if (init_drxk(state) < 0) 68429a0bf528SMauro Carvalho Chehab goto error; 68439a0bf528SMauro Carvalho Chehab 68448f3741e0SMauro Carvalho Chehab 68458f3741e0SMauro Carvalho Chehab /* Initialize stats */ 68468f3741e0SMauro Carvalho Chehab p = &state->frontend.dtv_property_cache; 68478f3741e0SMauro Carvalho Chehab p->strength.len = 1; 68488f3741e0SMauro Carvalho Chehab p->cnr.len = 1; 68498f3741e0SMauro Carvalho Chehab p->block_error.len = 1; 68508f3741e0SMauro Carvalho Chehab p->block_count.len = 1; 68518f3741e0SMauro Carvalho Chehab p->pre_bit_error.len = 1; 68528f3741e0SMauro Carvalho Chehab p->pre_bit_count.len = 1; 68538f3741e0SMauro Carvalho Chehab p->post_bit_error.len = 1; 68548f3741e0SMauro Carvalho Chehab p->post_bit_count.len = 1; 68558f3741e0SMauro Carvalho Chehab 68568f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 68578f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68588f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68598f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68608f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68618f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68628f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68638f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68648f3741e0SMauro Carvalho Chehab 68653a4398f5SMauro Carvalho Chehab pr_info("frontend initialized.\n"); 68669a0bf528SMauro Carvalho Chehab return &state->frontend; 68679a0bf528SMauro Carvalho Chehab 68689a0bf528SMauro Carvalho Chehab error: 68693a4398f5SMauro Carvalho Chehab pr_err("not found\n"); 68709a0bf528SMauro Carvalho Chehab kfree(state); 68719a0bf528SMauro Carvalho Chehab return NULL; 68729a0bf528SMauro Carvalho Chehab } 68739a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach); 68749a0bf528SMauro Carvalho Chehab 68759a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver"); 68769a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler"); 68779a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL"); 6878