189ee7f4fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 29a0bf528SMauro Carvalho Chehab /* 39a0bf528SMauro Carvalho Chehab * drxk_hard: DRX-K DVB-C/T demodulator driver 49a0bf528SMauro Carvalho Chehab * 59a0bf528SMauro Carvalho Chehab * Copyright (C) 2010-2011 Digital Devices GmbH 69a0bf528SMauro Carvalho Chehab */ 79a0bf528SMauro Carvalho Chehab 83a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 93a4398f5SMauro Carvalho Chehab 109a0bf528SMauro Carvalho Chehab #include <linux/kernel.h> 119a0bf528SMauro Carvalho Chehab #include <linux/module.h> 129a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h> 139a0bf528SMauro Carvalho Chehab #include <linux/init.h> 149a0bf528SMauro Carvalho Chehab #include <linux/delay.h> 159a0bf528SMauro Carvalho Chehab #include <linux/firmware.h> 169a0bf528SMauro Carvalho Chehab #include <linux/i2c.h> 179a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h> 189a0bf528SMauro Carvalho Chehab #include <asm/div64.h> 199a0bf528SMauro Carvalho Chehab 20fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h> 219a0bf528SMauro Carvalho Chehab #include "drxk.h" 229a0bf528SMauro Carvalho Chehab #include "drxk_hard.h" 23fada1935SMauro Carvalho Chehab #include <media/dvb_math.h> 249a0bf528SMauro Carvalho Chehab 25cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode); 26cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state); 27cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 28cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 29cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state, 30cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 31cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 32cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset); 33cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 34cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode); 35cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state); 36cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 37cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset); 38cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status); 39cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status); 40cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state); 41cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state); 429a0bf528SMauro Carvalho Chehab 43cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state) 449a0bf528SMauro Carvalho Chehab { 45cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_DVBT; 469a0bf528SMauro Carvalho Chehab } 479a0bf528SMauro Carvalho Chehab 48cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state) 499a0bf528SMauro Carvalho Chehab { 50cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_QAM_ITU_A || 51cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_B || 52cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_C; 539a0bf528SMauro Carvalho Chehab } 549a0bf528SMauro Carvalho Chehab 559a0bf528SMauro Carvalho Chehab #define NOA1ROM 0 569a0bf528SMauro Carvalho Chehab 579a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0) 589a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0) 599a0bf528SMauro Carvalho Chehab 609a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83 165 619a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93 250 629a0bf528SMauro Carvalho Chehab 639a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 649a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02) 659a0bf528SMauro Carvalho Chehab #endif 669a0bf528SMauro Carvalho Chehab 679a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 689a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) 699a0bf528SMauro Carvalho Chehab #endif 709a0bf528SMauro Carvalho Chehab 719a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 729a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 739a0bf528SMauro Carvalho Chehab 749a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV 759a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV 4 769a0bf528SMauro Carvalho Chehab #endif 779a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV 789a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV 6 799a0bf528SMauro Carvalho Chehab #endif 809a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV 819a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV 7 829a0bf528SMauro Carvalho Chehab #endif 839a0bf528SMauro Carvalho Chehab 849a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM 859a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM 3 869a0bf528SMauro Carvalho Chehab #endif 879a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM 889a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM 4 899a0bf528SMauro Carvalho Chehab #endif 909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM 919a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM 7 929a0bf528SMauro Carvalho Chehab #endif 939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT 949a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2) 959a0bf528SMauro Carvalho Chehab #endif 969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT 979a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2) 989a0bf528SMauro Carvalho Chehab #endif 999a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT 1009a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7) 1019a0bf528SMauro Carvalho Chehab #endif 1029a0bf528SMauro Carvalho Chehab 1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET 1049a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800) 1059a0bf528SMauro Carvalho Chehab #endif 1069a0bf528SMauro Carvalho Chehab 1079a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ 1089a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L) 1099a0bf528SMauro Carvalho Chehab #endif 1109a0bf528SMauro Carvalho Chehab 1119a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ 1129a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L) 1139a0bf528SMauro Carvalho Chehab #endif 1149a0bf528SMauro Carvalho Chehab 1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ 1169a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L) 1179a0bf528SMauro Carvalho Chehab #endif 1189a0bf528SMauro Carvalho Chehab 1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX 1209a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX (7233000) 1219a0bf528SMauro Carvalho Chehab #endif 1229a0bf528SMauro Carvalho Chehab 1239a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56 1249a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64 1259a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0 1269a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG 24 1279a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32 1289a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40 1299a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM 48 1309a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE 0 1319a0bf528SMauro Carvalho Chehab 1329a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT 100 1339a0bf528SMauro Carvalho Chehab 1349a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS 2 1359a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE 6 1369a0bf528SMauro Carvalho Chehab 1379a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS 28 1389a0bf528SMauro Carvalho Chehab 1399a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH 1409a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH (4) 1419a0bf528SMauro Carvalho Chehab #endif 1429a0bf528SMauro Carvalho Chehab 1439a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16 (40960) 1449a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32 (20480) 1459a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64 (43008) 1469a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128 (20992) 1479a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256 (43520) 1489a0bf528SMauro Carvalho Chehab 1499a0bf528SMauro Carvalho Chehab static unsigned int debug; 1509a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644); 1519a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages"); 1529a0bf528SMauro Carvalho Chehab 1539a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do { \ 1549a0bf528SMauro Carvalho Chehab if (debug >= level) \ 15552ee29feSMauro Carvalho Chehab printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ 1569a0bf528SMauro Carvalho Chehab } while (0) 1579a0bf528SMauro Carvalho Chehab 158ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c) 1599a0bf528SMauro Carvalho Chehab { 1609a0bf528SMauro Carvalho Chehab int i = 0; 1619a0bf528SMauro Carvalho Chehab u32 Q1 = 0; 1629a0bf528SMauro Carvalho Chehab u32 R0 = 0; 1639a0bf528SMauro Carvalho Chehab 1649a0bf528SMauro Carvalho Chehab R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ 165ab5060cdSMauro Carvalho Chehab Q1 = a / c; /* 166ab5060cdSMauro Carvalho Chehab * integer part, only the 4 least significant 167ab5060cdSMauro Carvalho Chehab * bits will be visible in the result 168ab5060cdSMauro Carvalho Chehab */ 1699a0bf528SMauro Carvalho Chehab 1709a0bf528SMauro Carvalho Chehab /* division using radix 16, 7 nibbles in the result */ 1719a0bf528SMauro Carvalho Chehab for (i = 0; i < 7; i++) { 1729a0bf528SMauro Carvalho Chehab Q1 = (Q1 << 4) | (R0 / c); 1739a0bf528SMauro Carvalho Chehab R0 = (R0 % c) << 4; 1749a0bf528SMauro Carvalho Chehab } 1759a0bf528SMauro Carvalho Chehab /* rounding */ 1769a0bf528SMauro Carvalho Chehab if ((R0 >> 3) >= c) 1779a0bf528SMauro Carvalho Chehab Q1++; 1789a0bf528SMauro Carvalho Chehab 1799a0bf528SMauro Carvalho Chehab return Q1; 1809a0bf528SMauro Carvalho Chehab } 1819a0bf528SMauro Carvalho Chehab 182b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value) 1839a0bf528SMauro Carvalho Chehab { 184b5e9eb6fSMauro Carvalho Chehab return (100L * intlog10(value)) >> 24; 1859a0bf528SMauro Carvalho Chehab } 1869a0bf528SMauro Carvalho Chehab 18734eb9751SMauro Carvalho Chehab /***************************************************************************/ 1889a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/ 18934eb9751SMauro Carvalho Chehab /***************************************************************************/ 1909a0bf528SMauro Carvalho Chehab 1919a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state) 1929a0bf528SMauro Carvalho Chehab { 193c060a9feSPeter Rosin i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT); 1949a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = true; 1959a0bf528SMauro Carvalho Chehab 1969a0bf528SMauro Carvalho Chehab return 0; 1979a0bf528SMauro Carvalho Chehab } 1989a0bf528SMauro Carvalho Chehab 1999a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state) 2009a0bf528SMauro Carvalho Chehab { 2019a0bf528SMauro Carvalho Chehab if (!state->drxk_i2c_exclusive_lock) 2029a0bf528SMauro Carvalho Chehab return; 2039a0bf528SMauro Carvalho Chehab 204c060a9feSPeter Rosin i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT); 2059a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = false; 2069a0bf528SMauro Carvalho Chehab } 2079a0bf528SMauro Carvalho Chehab 2089a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, 2099a0bf528SMauro Carvalho Chehab unsigned len) 2109a0bf528SMauro Carvalho Chehab { 2119a0bf528SMauro Carvalho Chehab if (state->drxk_i2c_exclusive_lock) 2129a0bf528SMauro Carvalho Chehab return __i2c_transfer(state->i2c, msgs, len); 2139a0bf528SMauro Carvalho Chehab else 2149a0bf528SMauro Carvalho Chehab return i2c_transfer(state->i2c, msgs, len); 2159a0bf528SMauro Carvalho Chehab } 2169a0bf528SMauro Carvalho Chehab 2179a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) 2189a0bf528SMauro Carvalho Chehab { 2199a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, 2209a0bf528SMauro Carvalho Chehab .buf = val, .len = 1} 2219a0bf528SMauro Carvalho Chehab }; 2229a0bf528SMauro Carvalho Chehab 2239a0bf528SMauro Carvalho Chehab return drxk_i2c_transfer(state, msgs, 1); 2249a0bf528SMauro Carvalho Chehab } 2259a0bf528SMauro Carvalho Chehab 2269a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) 2279a0bf528SMauro Carvalho Chehab { 2289a0bf528SMauro Carvalho Chehab int status; 2299a0bf528SMauro Carvalho Chehab struct i2c_msg msg = { 2309a0bf528SMauro Carvalho Chehab .addr = adr, .flags = 0, .buf = data, .len = len }; 2319a0bf528SMauro Carvalho Chehab 2329a0bf528SMauro Carvalho Chehab dprintk(3, ":"); 2339a0bf528SMauro Carvalho Chehab if (debug > 2) { 2349a0bf528SMauro Carvalho Chehab int i; 2359a0bf528SMauro Carvalho Chehab for (i = 0; i < len; i++) 2360fb220f2SMauro Carvalho Chehab pr_cont(" %02x", data[i]); 2370fb220f2SMauro Carvalho Chehab pr_cont("\n"); 2389a0bf528SMauro Carvalho Chehab } 2399a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, &msg, 1); 2409a0bf528SMauro Carvalho Chehab if (status >= 0 && status != 1) 2419a0bf528SMauro Carvalho Chehab status = -EIO; 2429a0bf528SMauro Carvalho Chehab 2439a0bf528SMauro Carvalho Chehab if (status < 0) 2443a4398f5SMauro Carvalho Chehab pr_err("i2c write error at addr 0x%02x\n", adr); 2459a0bf528SMauro Carvalho Chehab 2469a0bf528SMauro Carvalho Chehab return status; 2479a0bf528SMauro Carvalho Chehab } 2489a0bf528SMauro Carvalho Chehab 2499a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state, 2509a0bf528SMauro Carvalho Chehab u8 adr, u8 *msg, int len, u8 *answ, int alen) 2519a0bf528SMauro Carvalho Chehab { 2529a0bf528SMauro Carvalho Chehab int status; 2539a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[2] = { 2549a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = 0, 2559a0bf528SMauro Carvalho Chehab .buf = msg, .len = len}, 2569a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = I2C_M_RD, 2579a0bf528SMauro Carvalho Chehab .buf = answ, .len = alen} 2589a0bf528SMauro Carvalho Chehab }; 2599a0bf528SMauro Carvalho Chehab 2609a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, msgs, 2); 2619a0bf528SMauro Carvalho Chehab if (status != 2) { 2629a0bf528SMauro Carvalho Chehab if (debug > 2) 2630fb220f2SMauro Carvalho Chehab pr_cont(": ERROR!\n"); 2649a0bf528SMauro Carvalho Chehab if (status >= 0) 2659a0bf528SMauro Carvalho Chehab status = -EIO; 2669a0bf528SMauro Carvalho Chehab 2673a4398f5SMauro Carvalho Chehab pr_err("i2c read error at addr 0x%02x\n", adr); 2689a0bf528SMauro Carvalho Chehab return status; 2699a0bf528SMauro Carvalho Chehab } 2709a0bf528SMauro Carvalho Chehab if (debug > 2) { 2719a0bf528SMauro Carvalho Chehab int i; 2729a0bf528SMauro Carvalho Chehab dprintk(2, ": read from"); 2739a0bf528SMauro Carvalho Chehab for (i = 0; i < len; i++) 2740fb220f2SMauro Carvalho Chehab pr_cont(" %02x", msg[i]); 2750fb220f2SMauro Carvalho Chehab pr_cont(", value = "); 2769a0bf528SMauro Carvalho Chehab for (i = 0; i < alen; i++) 2770fb220f2SMauro Carvalho Chehab pr_cont(" %02x", answ[i]); 2780fb220f2SMauro Carvalho Chehab pr_cont("\n"); 2799a0bf528SMauro Carvalho Chehab } 2809a0bf528SMauro Carvalho Chehab return 0; 2819a0bf528SMauro Carvalho Chehab } 2829a0bf528SMauro Carvalho Chehab 2839a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) 2849a0bf528SMauro Carvalho Chehab { 2859a0bf528SMauro Carvalho Chehab int status; 2869a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[2], len; 2879a0bf528SMauro Carvalho Chehab 2889a0bf528SMauro Carvalho Chehab if (state->single_master) 2899a0bf528SMauro Carvalho Chehab flags |= 0xC0; 2909a0bf528SMauro Carvalho Chehab 2919a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 2929a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01); 2939a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF); 2949a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags; 2959a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF); 2969a0bf528SMauro Carvalho Chehab len = 4; 2979a0bf528SMauro Carvalho Chehab } else { 2989a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF); 2999a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3009a0bf528SMauro Carvalho Chehab len = 2; 3019a0bf528SMauro Carvalho Chehab } 3029a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3039a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 2); 3049a0bf528SMauro Carvalho Chehab if (status < 0) 3059a0bf528SMauro Carvalho Chehab return status; 3069a0bf528SMauro Carvalho Chehab if (data) 3079a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8); 3089a0bf528SMauro Carvalho Chehab 3099a0bf528SMauro Carvalho Chehab return 0; 3109a0bf528SMauro Carvalho Chehab } 3119a0bf528SMauro Carvalho Chehab 3129a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data) 3139a0bf528SMauro Carvalho Chehab { 3149a0bf528SMauro Carvalho Chehab return read16_flags(state, reg, data, 0); 3159a0bf528SMauro Carvalho Chehab } 3169a0bf528SMauro Carvalho Chehab 3179a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) 3189a0bf528SMauro Carvalho Chehab { 3199a0bf528SMauro Carvalho Chehab int status; 3209a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[4], len; 3219a0bf528SMauro Carvalho Chehab 3229a0bf528SMauro Carvalho Chehab if (state->single_master) 3239a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3249a0bf528SMauro Carvalho Chehab 3259a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3269a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01); 3279a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF); 3289a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags; 3299a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF); 3309a0bf528SMauro Carvalho Chehab len = 4; 3319a0bf528SMauro Carvalho Chehab } else { 3329a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF); 3339a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3349a0bf528SMauro Carvalho Chehab len = 2; 3359a0bf528SMauro Carvalho Chehab } 3369a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3379a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 4); 3389a0bf528SMauro Carvalho Chehab if (status < 0) 3399a0bf528SMauro Carvalho Chehab return status; 3409a0bf528SMauro Carvalho Chehab if (data) 3419a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8) | 3429a0bf528SMauro Carvalho Chehab (mm2[2] << 16) | (mm2[3] << 24); 3439a0bf528SMauro Carvalho Chehab 3449a0bf528SMauro Carvalho Chehab return 0; 3459a0bf528SMauro Carvalho Chehab } 3469a0bf528SMauro Carvalho Chehab 3479a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data) 3489a0bf528SMauro Carvalho Chehab { 3499a0bf528SMauro Carvalho Chehab return read32_flags(state, reg, data, 0); 3509a0bf528SMauro Carvalho Chehab } 3519a0bf528SMauro Carvalho Chehab 3529a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) 3539a0bf528SMauro Carvalho Chehab { 3549a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[6], len; 3559a0bf528SMauro Carvalho Chehab 3569a0bf528SMauro Carvalho Chehab if (state->single_master) 3579a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3589a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3599a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01); 3609a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF); 3619a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags; 3629a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF); 3639a0bf528SMauro Carvalho Chehab len = 4; 3649a0bf528SMauro Carvalho Chehab } else { 3659a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF); 3669a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3679a0bf528SMauro Carvalho Chehab len = 2; 3689a0bf528SMauro Carvalho Chehab } 3699a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff; 3709a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff; 3719a0bf528SMauro Carvalho Chehab 3729a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); 3739a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 2); 3749a0bf528SMauro Carvalho Chehab } 3759a0bf528SMauro Carvalho Chehab 3769a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data) 3779a0bf528SMauro Carvalho Chehab { 3789a0bf528SMauro Carvalho Chehab return write16_flags(state, reg, data, 0); 3799a0bf528SMauro Carvalho Chehab } 3809a0bf528SMauro Carvalho Chehab 3819a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) 3829a0bf528SMauro Carvalho Chehab { 3839a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[8], len; 3849a0bf528SMauro Carvalho Chehab 3859a0bf528SMauro Carvalho Chehab if (state->single_master) 3869a0bf528SMauro Carvalho Chehab flags |= 0xC0; 3879a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3889a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01); 3899a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF); 3909a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags; 3919a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF); 3929a0bf528SMauro Carvalho Chehab len = 4; 3939a0bf528SMauro Carvalho Chehab } else { 3949a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF); 3959a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3969a0bf528SMauro Carvalho Chehab len = 2; 3979a0bf528SMauro Carvalho Chehab } 3989a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff; 3999a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff; 4009a0bf528SMauro Carvalho Chehab mm[len + 2] = (data >> 16) & 0xff; 4019a0bf528SMauro Carvalho Chehab mm[len + 3] = (data >> 24) & 0xff; 4029a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); 4039a0bf528SMauro Carvalho Chehab 4049a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 4); 4059a0bf528SMauro Carvalho Chehab } 4069a0bf528SMauro Carvalho Chehab 4079a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data) 4089a0bf528SMauro Carvalho Chehab { 4099a0bf528SMauro Carvalho Chehab return write32_flags(state, reg, data, 0); 4109a0bf528SMauro Carvalho Chehab } 4119a0bf528SMauro Carvalho Chehab 412cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address, 413cd7a67a4SMauro Carvalho Chehab const int block_size, const u8 p_block[]) 4149a0bf528SMauro Carvalho Chehab { 415cd7a67a4SMauro Carvalho Chehab int status = 0, blk_size = block_size; 416cd7a67a4SMauro Carvalho Chehab u8 flags = 0; 4179a0bf528SMauro Carvalho Chehab 4189a0bf528SMauro Carvalho Chehab if (state->single_master) 419cd7a67a4SMauro Carvalho Chehab flags |= 0xC0; 4209a0bf528SMauro Carvalho Chehab 421cd7a67a4SMauro Carvalho Chehab while (blk_size > 0) { 422cd7a67a4SMauro Carvalho Chehab int chunk = blk_size > state->m_chunk_size ? 423cd7a67a4SMauro Carvalho Chehab state->m_chunk_size : blk_size; 424cd7a67a4SMauro Carvalho Chehab u8 *adr_buf = &state->chunk[0]; 425cd7a67a4SMauro Carvalho Chehab u32 adr_length = 0; 4269a0bf528SMauro Carvalho Chehab 427cd7a67a4SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) { 428cd7a67a4SMauro Carvalho Chehab adr_buf[0] = (((address << 1) & 0xFF) | 0x01); 429cd7a67a4SMauro Carvalho Chehab adr_buf[1] = ((address >> 16) & 0xFF); 430cd7a67a4SMauro Carvalho Chehab adr_buf[2] = ((address >> 24) & 0xFF); 431cd7a67a4SMauro Carvalho Chehab adr_buf[3] = ((address >> 7) & 0xFF); 432cd7a67a4SMauro Carvalho Chehab adr_buf[2] |= flags; 433cd7a67a4SMauro Carvalho Chehab adr_length = 4; 434cd7a67a4SMauro Carvalho Chehab if (chunk == state->m_chunk_size) 435cd7a67a4SMauro Carvalho Chehab chunk -= 2; 4369a0bf528SMauro Carvalho Chehab } else { 437cd7a67a4SMauro Carvalho Chehab adr_buf[0] = ((address << 1) & 0xFF); 438cd7a67a4SMauro Carvalho Chehab adr_buf[1] = (((address >> 16) & 0x0F) | 439cd7a67a4SMauro Carvalho Chehab ((address >> 18) & 0xF0)); 440cd7a67a4SMauro Carvalho Chehab adr_length = 2; 4419a0bf528SMauro Carvalho Chehab } 442cd7a67a4SMauro Carvalho Chehab memcpy(&state->chunk[adr_length], p_block, chunk); 443cd7a67a4SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", address, flags); 4449a0bf528SMauro Carvalho Chehab if (debug > 1) { 4459a0bf528SMauro Carvalho Chehab int i; 446cd7a67a4SMauro Carvalho Chehab if (p_block) 447cd7a67a4SMauro Carvalho Chehab for (i = 0; i < chunk; i++) 4480fb220f2SMauro Carvalho Chehab pr_cont(" %02x", p_block[i]); 4490fb220f2SMauro Carvalho Chehab pr_cont("\n"); 4509a0bf528SMauro Carvalho Chehab } 4519a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address, 452cd7a67a4SMauro Carvalho Chehab &state->chunk[0], chunk + adr_length); 4539a0bf528SMauro Carvalho Chehab if (status < 0) { 4543a4398f5SMauro Carvalho Chehab pr_err("%s: i2c write error at addr 0x%02x\n", 455cd7a67a4SMauro Carvalho Chehab __func__, address); 4569a0bf528SMauro Carvalho Chehab break; 4579a0bf528SMauro Carvalho Chehab } 458cd7a67a4SMauro Carvalho Chehab p_block += chunk; 459cd7a67a4SMauro Carvalho Chehab address += (chunk >> 1); 460cd7a67a4SMauro Carvalho Chehab blk_size -= chunk; 4619a0bf528SMauro Carvalho Chehab } 4629a0bf528SMauro Carvalho Chehab return status; 4639a0bf528SMauro Carvalho Chehab } 4649a0bf528SMauro Carvalho Chehab 4659a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP 4669a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20 4679a0bf528SMauro Carvalho Chehab #endif 4689a0bf528SMauro Carvalho Chehab 469cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state) 4709a0bf528SMauro Carvalho Chehab { 4719a0bf528SMauro Carvalho Chehab int status; 4729a0bf528SMauro Carvalho Chehab u8 data = 0; 473cd7a67a4SMauro Carvalho Chehab u16 retry_count = 0; 4749a0bf528SMauro Carvalho Chehab 4759a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 4769a0bf528SMauro Carvalho Chehab 4779a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address, &data); 4789a0bf528SMauro Carvalho Chehab if (status < 0) { 4799a0bf528SMauro Carvalho Chehab do { 4809a0bf528SMauro Carvalho Chehab data = 0; 4819a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address, 4829a0bf528SMauro Carvalho Chehab &data, 1); 483b72852baSMauro Carvalho Chehab usleep_range(10000, 11000); 484cd7a67a4SMauro Carvalho Chehab retry_count++; 4859a0bf528SMauro Carvalho Chehab if (status < 0) 4869a0bf528SMauro Carvalho Chehab continue; 4879a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address, 4889a0bf528SMauro Carvalho Chehab &data); 4899a0bf528SMauro Carvalho Chehab } while (status < 0 && 490cd7a67a4SMauro Carvalho Chehab (retry_count < DRXK_MAX_RETRIES_POWERUP)); 491cd7a67a4SMauro Carvalho Chehab if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP) 4929a0bf528SMauro Carvalho Chehab goto error; 4939a0bf528SMauro Carvalho Chehab } 4949a0bf528SMauro Carvalho Chehab 4959a0bf528SMauro Carvalho Chehab /* Make sure all clk domains are active */ 4969a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE); 4979a0bf528SMauro Carvalho Chehab if (status < 0) 4989a0bf528SMauro Carvalho Chehab goto error; 4999a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 5009a0bf528SMauro Carvalho Chehab if (status < 0) 5019a0bf528SMauro Carvalho Chehab goto error; 5029a0bf528SMauro Carvalho Chehab /* Enable pll lock tests */ 5039a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PLL_LOCK__A, 1); 5049a0bf528SMauro Carvalho Chehab if (status < 0) 5059a0bf528SMauro Carvalho Chehab goto error; 5069a0bf528SMauro Carvalho Chehab 507cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_UP; 5089a0bf528SMauro Carvalho Chehab 5099a0bf528SMauro Carvalho Chehab error: 5109a0bf528SMauro Carvalho Chehab if (status < 0) 5113a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 5129a0bf528SMauro Carvalho Chehab 5139a0bf528SMauro Carvalho Chehab return status; 5149a0bf528SMauro Carvalho Chehab } 5159a0bf528SMauro Carvalho Chehab 5169a0bf528SMauro Carvalho Chehab 5179a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state) 5189a0bf528SMauro Carvalho Chehab { 5199a0bf528SMauro Carvalho Chehab /* 5205a13e40bSMauro Carvalho Chehab * FIXME: most (all?) of the values below should be moved into 5219a0bf528SMauro Carvalho Chehab * struct drxk_config, as they are probably board-specific 5229a0bf528SMauro Carvalho Chehab */ 523cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; 524cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_output_level = 0; 525cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_min_level = 0; 526cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_max_level = 0x7FFF; 527cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_speed = 3; 5289a0bf528SMauro Carvalho Chehab 529cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO; 530cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_output_level = 0; 531cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_min_level = 0; 532cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_max_level = 0x7FFF; 533cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_speed = 3; 534cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_top = 9500; 535cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_cut_off_current = 4000; 5369a0bf528SMauro Carvalho Chehab 537cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO; 538cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_output_level = 0; 539cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_min_level = 0; 540cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_max_level = 0; 541cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_speed = 3; 5429a0bf528SMauro Carvalho Chehab 543cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF; 544cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_output_level = 0; 545cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_min_level = 0; 546cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_max_level = 0; 547cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_top = 9500; 548cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_cut_off_current = 4000; 549cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_speed = 3; 5509a0bf528SMauro Carvalho Chehab 5519a0bf528SMauro Carvalho Chehab u32 ulQual83 = DEFAULT_MER_83; 5529a0bf528SMauro Carvalho Chehab u32 ulQual93 = DEFAULT_MER_93; 5539a0bf528SMauro Carvalho Chehab 554cd7a67a4SMauro Carvalho Chehab u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 555cd7a67a4SMauro Carvalho Chehab u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 5569a0bf528SMauro Carvalho Chehab 5579a0bf528SMauro Carvalho Chehab /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ 5589a0bf528SMauro Carvalho Chehab /* io_pad_cfg_mode output mode is drive always */ 5599a0bf528SMauro Carvalho Chehab /* io_pad_cfg_drive is set to power 2 (23 mA) */ 560cd7a67a4SMauro Carvalho Chehab u32 ul_gpio_cfg = 0x0113; 561cd7a67a4SMauro Carvalho Chehab u32 ul_invert_ts_clock = 0; 562cd7a67a4SMauro Carvalho Chehab u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; 563cd7a67a4SMauro Carvalho Chehab u32 ul_dvbt_bitrate = 50000000; 564cd7a67a4SMauro Carvalho Chehab u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; 5659a0bf528SMauro Carvalho Chehab 566cd7a67a4SMauro Carvalho Chehab u32 ul_insert_rs_byte = 0; 5679a0bf528SMauro Carvalho Chehab 568cd7a67a4SMauro Carvalho Chehab u32 ul_rf_mirror = 1; 569cd7a67a4SMauro Carvalho Chehab u32 ul_power_down = 0; 5709a0bf528SMauro Carvalho Chehab 5719a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5729a0bf528SMauro Carvalho Chehab 573cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 574cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = false; 575cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 576cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false; 577cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 578cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 5799a0bf528SMauro Carvalho Chehab 580cd7a67a4SMauro Carvalho Chehab if (!state->m_chunk_size) 581cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = 124; 5829a0bf528SMauro Carvalho Chehab 583cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 0; 584cd7a67a4SMauro Carvalho Chehab state->m_smart_ant_inverted = false; 585cd7a67a4SMauro Carvalho Chehab state->m_b_p_down_open_bridge = false; 5869a0bf528SMauro Carvalho Chehab 5879a0bf528SMauro Carvalho Chehab /* real system clock frequency in kHz */ 588cd7a67a4SMauro Carvalho Chehab state->m_sys_clock_freq = 151875; 5899a0bf528SMauro Carvalho Chehab /* Timing div, 250ns/Psys */ 5909a0bf528SMauro Carvalho Chehab /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ 591cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) * 5929a0bf528SMauro Carvalho Chehab HI_I2C_DELAY) / 1000; 5939a0bf528SMauro Carvalho Chehab /* Clipping */ 594cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) 595cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; 596cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 5979a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */ 598cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 5999a0bf528SMauro Carvalho Chehab 600cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = (ul_power_down != 0); 6019a0bf528SMauro Carvalho Chehab 602cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = false; 6039a0bf528SMauro Carvalho Chehab 6049a0bf528SMauro Carvalho Chehab /* Init AGC and PGA parameters */ 6059a0bf528SMauro Carvalho Chehab /* VSB IF */ 606949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode; 607949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level; 608949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level; 609949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level; 610949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed; 611cd7a67a4SMauro Carvalho Chehab state->m_vsb_pga_cfg = 140; 6129a0bf528SMauro Carvalho Chehab 6139a0bf528SMauro Carvalho Chehab /* VSB RF */ 614949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode; 615949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level; 616949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level; 617949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level; 618949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed; 619949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top; 620949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current; 621cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.reference = 0x07; 622cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.use_pre_saw = true; 6239a0bf528SMauro Carvalho Chehab 6249a0bf528SMauro Carvalho Chehab state->m_Quality83percent = DEFAULT_MER_83; 6259a0bf528SMauro Carvalho Chehab state->m_Quality93percent = DEFAULT_MER_93; 6269a0bf528SMauro Carvalho Chehab if (ulQual93 <= 500 && ulQual83 < ulQual93) { 6279a0bf528SMauro Carvalho Chehab state->m_Quality83percent = ulQual83; 6289a0bf528SMauro Carvalho Chehab state->m_Quality93percent = ulQual93; 6299a0bf528SMauro Carvalho Chehab } 6309a0bf528SMauro Carvalho Chehab 6319a0bf528SMauro Carvalho Chehab /* ATV IF */ 632949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode; 633949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level; 634949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level; 635949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level; 636949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed; 6379a0bf528SMauro Carvalho Chehab 6389a0bf528SMauro Carvalho Chehab /* ATV RF */ 639949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode; 640949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level; 641949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level; 642949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level; 643949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed; 644949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top; 645949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current; 646cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.reference = 0x04; 647cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.use_pre_saw = true; 6489a0bf528SMauro Carvalho Chehab 6499a0bf528SMauro Carvalho Chehab 6509a0bf528SMauro Carvalho Chehab /* DVBT RF */ 651cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 652cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.output_level = 0; 653cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.min_output_level = 0; 654cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF; 655cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.top = 0x2100; 656cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.cut_off_current = 4000; 657cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.speed = 1; 6589a0bf528SMauro Carvalho Chehab 6599a0bf528SMauro Carvalho Chehab 6609a0bf528SMauro Carvalho Chehab /* DVBT IF */ 661cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 662cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.output_level = 0; 663cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.min_output_level = 0; 664cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.max_output_level = 9000; 665cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.top = 13424; 666cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.cut_off_current = 0; 667cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.speed = 3; 668cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30; 669cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000; 6709a0bf528SMauro Carvalho Chehab /* state->m_dvbtPgaCfg = 140; */ 6719a0bf528SMauro Carvalho Chehab 672cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.reference = 4; 673cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.use_pre_saw = false; 6749a0bf528SMauro Carvalho Chehab 6759a0bf528SMauro Carvalho Chehab /* QAM RF */ 676cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 677cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.output_level = 0; 678cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.min_output_level = 6023; 679cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.max_output_level = 27000; 680cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.top = 0x2380; 681cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.cut_off_current = 4000; 682cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.speed = 3; 6839a0bf528SMauro Carvalho Chehab 6849a0bf528SMauro Carvalho Chehab /* QAM IF */ 685cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 686cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.output_level = 0; 687cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.min_output_level = 0; 688cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.max_output_level = 9000; 689cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.top = 0x0511; 690cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.cut_off_current = 0; 691cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.speed = 3; 692cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ingain_tgt_max = 5119; 693cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50; 6949a0bf528SMauro Carvalho Chehab 695cd7a67a4SMauro Carvalho Chehab state->m_qam_pga_cfg = 140; 696cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.reference = 4; 697cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.use_pre_saw = false; 6989a0bf528SMauro Carvalho Chehab 699cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 700cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_UNINITIALIZED; 7019a0bf528SMauro Carvalho Chehab 7029a0bf528SMauro Carvalho Chehab /* MPEG output configuration */ 703868c9a17SMauro Carvalho Chehab state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG output */ 704cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */ 705cd7a67a4SMauro Carvalho Chehab state->m_invert_data = false; /* If TRUE; invert DATA signals */ 706cd7a67a4SMauro Carvalho Chehab state->m_invert_err = false; /* If TRUE; invert ERR signal */ 707cd7a67a4SMauro Carvalho Chehab state->m_invert_str = false; /* If TRUE; invert STR signals */ 708cd7a67a4SMauro Carvalho Chehab state->m_invert_val = false; /* If TRUE; invert VAL signals */ 709cd7a67a4SMauro Carvalho Chehab state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */ 7109a0bf528SMauro Carvalho Chehab 7119a0bf528SMauro Carvalho Chehab /* If TRUE; static MPEG clockrate will be used; 7129a0bf528SMauro Carvalho Chehab otherwise clockrate will adapt to the bitrate of the TS */ 7139a0bf528SMauro Carvalho Chehab 714cd7a67a4SMauro Carvalho Chehab state->m_dvbt_bitrate = ul_dvbt_bitrate; 715cd7a67a4SMauro Carvalho Chehab state->m_dvbc_bitrate = ul_dvbc_bitrate; 7169a0bf528SMauro Carvalho Chehab 717cd7a67a4SMauro Carvalho Chehab state->m_ts_data_strength = (ul_ts_data_strength & 0x07); 7189a0bf528SMauro Carvalho Chehab 7199a0bf528SMauro Carvalho Chehab /* Maximum bitrate in b/s in case static clockrate is selected */ 720cd7a67a4SMauro Carvalho Chehab state->m_mpeg_ts_static_bitrate = 19392658; 721cd7a67a4SMauro Carvalho Chehab state->m_disable_te_ihandling = false; 7229a0bf528SMauro Carvalho Chehab 723cd7a67a4SMauro Carvalho Chehab if (ul_insert_rs_byte) 724cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = true; 7259a0bf528SMauro Carvalho Chehab 726cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 727cd7a67a4SMauro Carvalho Chehab if (ul_mpeg_lock_time_out < 10000) 728cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out; 729cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 730cd7a67a4SMauro Carvalho Chehab if (ul_demod_lock_time_out < 10000) 731cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = ul_demod_lock_time_out; 7329a0bf528SMauro Carvalho Chehab 7339a0bf528SMauro Carvalho Chehab /* QAM defaults */ 734cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_AUTO; 735cd7a67a4SMauro Carvalho Chehab state->m_qam_interleave_mode = DRXK_QAM_I12_J17; 736cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */ 737cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_prescale = 1; 7389a0bf528SMauro Carvalho Chehab 739cd7a67a4SMauro Carvalho Chehab state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM; 740cd7a67a4SMauro Carvalho Chehab state->m_agcfast_clip_ctrl_delay = 0; 7419a0bf528SMauro Carvalho Chehab 742949dd08dSMauro Carvalho Chehab state->m_gpio_cfg = ul_gpio_cfg; 7439a0bf528SMauro Carvalho Chehab 744cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = false; 745cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_DOWN; 7469a0bf528SMauro Carvalho Chehab 747cd7a67a4SMauro Carvalho Chehab state->m_rfmirror = (ul_rf_mirror == 0); 748cd7a67a4SMauro Carvalho Chehab state->m_if_agc_pol = false; 7499a0bf528SMauro Carvalho Chehab return 0; 7509a0bf528SMauro Carvalho Chehab } 7519a0bf528SMauro Carvalho Chehab 752cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state) 7539a0bf528SMauro Carvalho Chehab { 7549a0bf528SMauro Carvalho Chehab int status = 0; 7559a0bf528SMauro Carvalho Chehab u32 jtag = 0; 7569a0bf528SMauro Carvalho Chehab u16 bid = 0; 7579a0bf528SMauro Carvalho Chehab u16 key = 0; 7589a0bf528SMauro Carvalho Chehab 7599a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 7609a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 761ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 762ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 7639a0bf528SMauro Carvalho Chehab if (status < 0) 7649a0bf528SMauro Carvalho Chehab goto error; 7659a0bf528SMauro Carvalho Chehab /* Check device id */ 7669a0bf528SMauro Carvalho Chehab status = read16(state, SIO_TOP_COMM_KEY__A, &key); 7679a0bf528SMauro Carvalho Chehab if (status < 0) 7689a0bf528SMauro Carvalho Chehab goto error; 7699a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 7709a0bf528SMauro Carvalho Chehab if (status < 0) 7719a0bf528SMauro Carvalho Chehab goto error; 7729a0bf528SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag); 7739a0bf528SMauro Carvalho Chehab if (status < 0) 7749a0bf528SMauro Carvalho Chehab goto error; 7759a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid); 7769a0bf528SMauro Carvalho Chehab if (status < 0) 7779a0bf528SMauro Carvalho Chehab goto error; 7789a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, key); 7799a0bf528SMauro Carvalho Chehab error: 7809a0bf528SMauro Carvalho Chehab if (status < 0) 7813a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 7829a0bf528SMauro Carvalho Chehab return status; 7839a0bf528SMauro Carvalho Chehab } 7849a0bf528SMauro Carvalho Chehab 785cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state) 7869a0bf528SMauro Carvalho Chehab { 787cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_ohw_cfg = 0; 788cd7a67a4SMauro Carvalho Chehab u32 sio_top_jtagid_lo = 0; 7899a0bf528SMauro Carvalho Chehab int status; 7909a0bf528SMauro Carvalho Chehab const char *spin = ""; 7919a0bf528SMauro Carvalho Chehab 7929a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 7939a0bf528SMauro Carvalho Chehab 7949a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 7959a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 796ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 797ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 7989a0bf528SMauro Carvalho Chehab if (status < 0) 7999a0bf528SMauro Carvalho Chehab goto error; 8008418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 8019a0bf528SMauro Carvalho Chehab if (status < 0) 8029a0bf528SMauro Carvalho Chehab goto error; 803cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg); 8049a0bf528SMauro Carvalho Chehab if (status < 0) 8059a0bf528SMauro Carvalho Chehab goto error; 8069a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 8079a0bf528SMauro Carvalho Chehab if (status < 0) 8089a0bf528SMauro Carvalho Chehab goto error; 8099a0bf528SMauro Carvalho Chehab 810cd7a67a4SMauro Carvalho Chehab switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { 8119a0bf528SMauro Carvalho Chehab case 0: 8129a0bf528SMauro Carvalho Chehab /* ignore (bypass ?) */ 8139a0bf528SMauro Carvalho Chehab break; 8149a0bf528SMauro Carvalho Chehab case 1: 8159a0bf528SMauro Carvalho Chehab /* 27 MHz */ 816cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 27000; 8179a0bf528SMauro Carvalho Chehab break; 8189a0bf528SMauro Carvalho Chehab case 2: 8199a0bf528SMauro Carvalho Chehab /* 20.25 MHz */ 820cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250; 8219a0bf528SMauro Carvalho Chehab break; 8229a0bf528SMauro Carvalho Chehab case 3: 8239a0bf528SMauro Carvalho Chehab /* 4 MHz */ 824cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250; 8259a0bf528SMauro Carvalho Chehab break; 8269a0bf528SMauro Carvalho Chehab default: 8273a4398f5SMauro Carvalho Chehab pr_err("Clock Frequency is unknown\n"); 8289a0bf528SMauro Carvalho Chehab return -EINVAL; 8299a0bf528SMauro Carvalho Chehab } 8309a0bf528SMauro Carvalho Chehab /* 8319a0bf528SMauro Carvalho Chehab Determine device capabilities 8329a0bf528SMauro Carvalho Chehab Based on pinning v14 8339a0bf528SMauro Carvalho Chehab */ 834cd7a67a4SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo); 8359a0bf528SMauro Carvalho Chehab if (status < 0) 8369a0bf528SMauro Carvalho Chehab goto error; 8379a0bf528SMauro Carvalho Chehab 8383a4398f5SMauro Carvalho Chehab pr_info("status = 0x%08x\n", sio_top_jtagid_lo); 8399a0bf528SMauro Carvalho Chehab 8409a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 841cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 29) & 0xF) { 8429a0bf528SMauro Carvalho Chehab case 0: 843cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A1; 8449a0bf528SMauro Carvalho Chehab spin = "A1"; 8459a0bf528SMauro Carvalho Chehab break; 8469a0bf528SMauro Carvalho Chehab case 2: 847cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A2; 8489a0bf528SMauro Carvalho Chehab spin = "A2"; 8499a0bf528SMauro Carvalho Chehab break; 8509a0bf528SMauro Carvalho Chehab case 3: 851cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A3; 8529a0bf528SMauro Carvalho Chehab spin = "A3"; 8539a0bf528SMauro Carvalho Chehab break; 8549a0bf528SMauro Carvalho Chehab default: 855cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_UNKNOWN; 8569a0bf528SMauro Carvalho Chehab status = -EINVAL; 8573a4398f5SMauro Carvalho Chehab pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF); 8589a0bf528SMauro Carvalho Chehab goto error2; 8599a0bf528SMauro Carvalho Chehab } 860cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 12) & 0xFF) { 8619a0bf528SMauro Carvalho Chehab case 0x13: 8629a0bf528SMauro Carvalho Chehab /* typeId = DRX3913K_TYPE_ID */ 863cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 864cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 865cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false; 866cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 867cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 868cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 869cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 870cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = false; 871cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = false; 872cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 8739a0bf528SMauro Carvalho Chehab break; 8749a0bf528SMauro Carvalho Chehab case 0x15: 8759a0bf528SMauro Carvalho Chehab /* typeId = DRX3915K_TYPE_ID */ 876cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 877cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 878cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 879cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 880cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 881cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 882cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 883cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 884cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 885cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 8869a0bf528SMauro Carvalho Chehab break; 8879a0bf528SMauro Carvalho Chehab case 0x16: 8889a0bf528SMauro Carvalho Chehab /* typeId = DRX3916K_TYPE_ID */ 889cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 890cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 891cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 892cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 893cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 894cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 895cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 896cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 897cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 898cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 8999a0bf528SMauro Carvalho Chehab break; 9009a0bf528SMauro Carvalho Chehab case 0x18: 9019a0bf528SMauro Carvalho Chehab /* typeId = DRX3918K_TYPE_ID */ 902cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 903cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 904cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 905cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 906cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 907cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false; 908cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 909cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 910cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 911cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9129a0bf528SMauro Carvalho Chehab break; 9139a0bf528SMauro Carvalho Chehab case 0x21: 9149a0bf528SMauro Carvalho Chehab /* typeId = DRX3921K_TYPE_ID */ 915cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 916cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 917cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 918cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 919cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 920cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 921cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 922cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 923cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 924cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9259a0bf528SMauro Carvalho Chehab break; 9269a0bf528SMauro Carvalho Chehab case 0x23: 9279a0bf528SMauro Carvalho Chehab /* typeId = DRX3923K_TYPE_ID */ 928cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 929cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 930cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 931cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 932cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 933cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 934cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 935cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 936cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 937cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9389a0bf528SMauro Carvalho Chehab break; 9399a0bf528SMauro Carvalho Chehab case 0x25: 9409a0bf528SMauro Carvalho Chehab /* typeId = DRX3925K_TYPE_ID */ 941cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 942cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 943cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 944cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true; 945cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 946cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 947cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 948cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 949cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 950cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9519a0bf528SMauro Carvalho Chehab break; 9529a0bf528SMauro Carvalho Chehab case 0x26: 9539a0bf528SMauro Carvalho Chehab /* typeId = DRX3926K_TYPE_ID */ 954cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false; 955cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false; 956cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true; 957cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false; 958cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true; 959cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true; 960cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true; 961cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true; 962cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true; 963cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false; 9649a0bf528SMauro Carvalho Chehab break; 9659a0bf528SMauro Carvalho Chehab default: 9663a4398f5SMauro Carvalho Chehab pr_err("DeviceID 0x%02x not supported\n", 967cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF)); 9689a0bf528SMauro Carvalho Chehab status = -EINVAL; 9699a0bf528SMauro Carvalho Chehab goto error2; 9709a0bf528SMauro Carvalho Chehab } 9719a0bf528SMauro Carvalho Chehab 9723a4398f5SMauro Carvalho Chehab pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", 973cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF), spin, 974cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq / 1000, 975cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq % 1000); 9769a0bf528SMauro Carvalho Chehab 9779a0bf528SMauro Carvalho Chehab error: 9789a0bf528SMauro Carvalho Chehab if (status < 0) 9793a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 9809a0bf528SMauro Carvalho Chehab 9819a0bf528SMauro Carvalho Chehab error2: 9829a0bf528SMauro Carvalho Chehab return status; 9839a0bf528SMauro Carvalho Chehab } 9849a0bf528SMauro Carvalho Chehab 985cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) 9869a0bf528SMauro Carvalho Chehab { 9879a0bf528SMauro Carvalho Chehab int status; 9889a0bf528SMauro Carvalho Chehab bool powerdown_cmd; 9899a0bf528SMauro Carvalho Chehab 9909a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 9919a0bf528SMauro Carvalho Chehab 9929a0bf528SMauro Carvalho Chehab /* Write command */ 9939a0bf528SMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd); 9949a0bf528SMauro Carvalho Chehab if (status < 0) 9959a0bf528SMauro Carvalho Chehab goto error; 9969a0bf528SMauro Carvalho Chehab if (cmd == SIO_HI_RA_RAM_CMD_RESET) 997b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 9989a0bf528SMauro Carvalho Chehab 9999a0bf528SMauro Carvalho Chehab powerdown_cmd = 10009a0bf528SMauro Carvalho Chehab (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && 1001cd7a67a4SMauro Carvalho Chehab ((state->m_hi_cfg_ctrl) & 10029a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == 10039a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); 10045a7f7b79SMauro Carvalho Chehab if (!powerdown_cmd) { 10059a0bf528SMauro Carvalho Chehab /* Wait until command rdy */ 1006cd7a67a4SMauro Carvalho Chehab u32 retry_count = 0; 1007cd7a67a4SMauro Carvalho Chehab u16 wait_cmd; 10089a0bf528SMauro Carvalho Chehab 10099a0bf528SMauro Carvalho Chehab do { 1010b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1011cd7a67a4SMauro Carvalho Chehab retry_count += 1; 10129a0bf528SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_CMD__A, 1013cd7a67a4SMauro Carvalho Chehab &wait_cmd); 1014c386e079SHans Verkuil } while ((status < 0 || wait_cmd) && (retry_count < DRXK_MAX_RETRIES)); 10159a0bf528SMauro Carvalho Chehab if (status < 0) 10169a0bf528SMauro Carvalho Chehab goto error; 1017cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_RES__A, p_result); 10189a0bf528SMauro Carvalho Chehab } 10199a0bf528SMauro Carvalho Chehab error: 10209a0bf528SMauro Carvalho Chehab if (status < 0) 10213a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 10229a0bf528SMauro Carvalho Chehab 10239a0bf528SMauro Carvalho Chehab return status; 10249a0bf528SMauro Carvalho Chehab } 10259a0bf528SMauro Carvalho Chehab 1026cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state) 10279a0bf528SMauro Carvalho Chehab { 10289a0bf528SMauro Carvalho Chehab int status; 10299a0bf528SMauro Carvalho Chehab 10309a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 10319a0bf528SMauro Carvalho Chehab 10329a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 10339a0bf528SMauro Carvalho Chehab 1034ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_6__A, 1035ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timeout); 10369a0bf528SMauro Carvalho Chehab if (status < 0) 10379a0bf528SMauro Carvalho Chehab goto error; 1038ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_5__A, 1039ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_ctrl); 10409a0bf528SMauro Carvalho Chehab if (status < 0) 10419a0bf528SMauro Carvalho Chehab goto error; 1042ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_4__A, 1043ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_wake_up_key); 10449a0bf528SMauro Carvalho Chehab if (status < 0) 10459a0bf528SMauro Carvalho Chehab goto error; 1046ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_3__A, 1047ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_bridge_delay); 10489a0bf528SMauro Carvalho Chehab if (status < 0) 10499a0bf528SMauro Carvalho Chehab goto error; 1050ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 1051ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timing_div); 10529a0bf528SMauro Carvalho Chehab if (status < 0) 10539a0bf528SMauro Carvalho Chehab goto error; 1054ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 1055ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 10569a0bf528SMauro Carvalho Chehab if (status < 0) 10579a0bf528SMauro Carvalho Chehab goto error; 1058b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); 10599a0bf528SMauro Carvalho Chehab if (status < 0) 10609a0bf528SMauro Carvalho Chehab goto error; 10619a0bf528SMauro Carvalho Chehab 1062cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 10639a0bf528SMauro Carvalho Chehab error: 10649a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 10659a0bf528SMauro Carvalho Chehab if (status < 0) 10663a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 10679a0bf528SMauro Carvalho Chehab return status; 10689a0bf528SMauro Carvalho Chehab } 10699a0bf528SMauro Carvalho Chehab 1070cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state) 10719a0bf528SMauro Carvalho Chehab { 10729a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 10739a0bf528SMauro Carvalho Chehab 1074cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 1075cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timeout = 0x96FF; 10769a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */ 1077cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 10789a0bf528SMauro Carvalho Chehab 1079cd7a67a4SMauro Carvalho Chehab return hi_cfg_command(state); 10809a0bf528SMauro Carvalho Chehab } 10819a0bf528SMauro Carvalho Chehab 1082cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) 10839a0bf528SMauro Carvalho Chehab { 108443c4dc3fSColin Ian King int status; 1085cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mclk_cfg = 0; 1086cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mdx_cfg = 0; 10879a0bf528SMauro Carvalho Chehab u16 err_cfg = 0; 10889a0bf528SMauro Carvalho Chehab 10899a0bf528SMauro Carvalho Chehab dprintk(1, ": mpeg %s, %s mode\n", 1090cd7a67a4SMauro Carvalho Chehab mpeg_enable ? "enable" : "disable", 1091cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel ? "parallel" : "serial"); 10929a0bf528SMauro Carvalho Chehab 10939a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 1094ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 1095ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 10969a0bf528SMauro Carvalho Chehab if (status < 0) 10979a0bf528SMauro Carvalho Chehab goto error; 10989a0bf528SMauro Carvalho Chehab 10999a0bf528SMauro Carvalho Chehab /* MPEG TS pad configuration */ 11008418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 11019a0bf528SMauro Carvalho Chehab if (status < 0) 11029a0bf528SMauro Carvalho Chehab goto error; 11039a0bf528SMauro Carvalho Chehab 11045a7f7b79SMauro Carvalho Chehab if (!mpeg_enable) { 11059a0bf528SMauro Carvalho Chehab /* Set MPEG TS pads to inputmode */ 11069a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000); 11079a0bf528SMauro Carvalho Chehab if (status < 0) 11089a0bf528SMauro Carvalho Chehab goto error; 11099a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); 11109a0bf528SMauro Carvalho Chehab if (status < 0) 11119a0bf528SMauro Carvalho Chehab goto error; 11129a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000); 11139a0bf528SMauro Carvalho Chehab if (status < 0) 11149a0bf528SMauro Carvalho Chehab goto error; 11159a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); 11169a0bf528SMauro Carvalho Chehab if (status < 0) 11179a0bf528SMauro Carvalho Chehab goto error; 11189a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000); 11199a0bf528SMauro Carvalho Chehab if (status < 0) 11209a0bf528SMauro Carvalho Chehab goto error; 11219a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 11229a0bf528SMauro Carvalho Chehab if (status < 0) 11239a0bf528SMauro Carvalho Chehab goto error; 11249a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 11259a0bf528SMauro Carvalho Chehab if (status < 0) 11269a0bf528SMauro Carvalho Chehab goto error; 11279a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 11289a0bf528SMauro Carvalho Chehab if (status < 0) 11299a0bf528SMauro Carvalho Chehab goto error; 11309a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 11319a0bf528SMauro Carvalho Chehab if (status < 0) 11329a0bf528SMauro Carvalho Chehab goto error; 11339a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 11349a0bf528SMauro Carvalho Chehab if (status < 0) 11359a0bf528SMauro Carvalho Chehab goto error; 11369a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 11379a0bf528SMauro Carvalho Chehab if (status < 0) 11389a0bf528SMauro Carvalho Chehab goto error; 11399a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 11409a0bf528SMauro Carvalho Chehab if (status < 0) 11419a0bf528SMauro Carvalho Chehab goto error; 11429a0bf528SMauro Carvalho Chehab } else { 11439a0bf528SMauro Carvalho Chehab /* Enable MPEG output */ 1144cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg = 1145cd7a67a4SMauro Carvalho Chehab ((state->m_ts_data_strength << 11469a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003); 1147cd7a67a4SMauro Carvalho Chehab sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength << 11489a0bf528SMauro Carvalho Chehab SIO_PDR_MCLK_CFG_DRIVE__B) | 11499a0bf528SMauro Carvalho Chehab 0x0003); 11509a0bf528SMauro Carvalho Chehab 1151cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg); 11529a0bf528SMauro Carvalho Chehab if (status < 0) 11539a0bf528SMauro Carvalho Chehab goto error; 11549a0bf528SMauro Carvalho Chehab 11559a0bf528SMauro Carvalho Chehab if (state->enable_merr_cfg) 1156cd7a67a4SMauro Carvalho Chehab err_cfg = sio_pdr_mdx_cfg; 11579a0bf528SMauro Carvalho Chehab 11589a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); 11599a0bf528SMauro Carvalho Chehab if (status < 0) 11609a0bf528SMauro Carvalho Chehab goto error; 11619a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); 11629a0bf528SMauro Carvalho Chehab if (status < 0) 11639a0bf528SMauro Carvalho Chehab goto error; 11649a0bf528SMauro Carvalho Chehab 11655a7f7b79SMauro Carvalho Chehab if (state->m_enable_parallel) { 116639c1cb2bSJonathan McCrohan /* parallel -> enable MD1 to MD7 */ 1167ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 1168ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11699a0bf528SMauro Carvalho Chehab if (status < 0) 11709a0bf528SMauro Carvalho Chehab goto error; 1171ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 1172ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11739a0bf528SMauro Carvalho Chehab if (status < 0) 11749a0bf528SMauro Carvalho Chehab goto error; 1175ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 1176ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11779a0bf528SMauro Carvalho Chehab if (status < 0) 11789a0bf528SMauro Carvalho Chehab goto error; 1179ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 1180ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11819a0bf528SMauro Carvalho Chehab if (status < 0) 11829a0bf528SMauro Carvalho Chehab goto error; 1183ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 1184ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11859a0bf528SMauro Carvalho Chehab if (status < 0) 11869a0bf528SMauro Carvalho Chehab goto error; 1187ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 1188ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11899a0bf528SMauro Carvalho Chehab if (status < 0) 11909a0bf528SMauro Carvalho Chehab goto error; 1191ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 1192ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg); 11939a0bf528SMauro Carvalho Chehab if (status < 0) 11949a0bf528SMauro Carvalho Chehab goto error; 11959a0bf528SMauro Carvalho Chehab } else { 1196cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg = ((state->m_ts_data_strength << 11979a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B) 11989a0bf528SMauro Carvalho Chehab | 0x0003); 11999a0bf528SMauro Carvalho Chehab /* serial -> disable MD1 to MD7 */ 12009a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 12019a0bf528SMauro Carvalho Chehab if (status < 0) 12029a0bf528SMauro Carvalho Chehab goto error; 12039a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 12049a0bf528SMauro Carvalho Chehab if (status < 0) 12059a0bf528SMauro Carvalho Chehab goto error; 12069a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 12079a0bf528SMauro Carvalho Chehab if (status < 0) 12089a0bf528SMauro Carvalho Chehab goto error; 12099a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 12109a0bf528SMauro Carvalho Chehab if (status < 0) 12119a0bf528SMauro Carvalho Chehab goto error; 12129a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 12139a0bf528SMauro Carvalho Chehab if (status < 0) 12149a0bf528SMauro Carvalho Chehab goto error; 12159a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 12169a0bf528SMauro Carvalho Chehab if (status < 0) 12179a0bf528SMauro Carvalho Chehab goto error; 12189a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 12199a0bf528SMauro Carvalho Chehab if (status < 0) 12209a0bf528SMauro Carvalho Chehab goto error; 12219a0bf528SMauro Carvalho Chehab } 1222cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg); 12239a0bf528SMauro Carvalho Chehab if (status < 0) 12249a0bf528SMauro Carvalho Chehab goto error; 1225cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg); 12269a0bf528SMauro Carvalho Chehab if (status < 0) 12279a0bf528SMauro Carvalho Chehab goto error; 12289a0bf528SMauro Carvalho Chehab } 12299a0bf528SMauro Carvalho Chehab /* Enable MB output over MPEG pads and ctl input */ 12309a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MON_CFG__A, 0x0000); 12319a0bf528SMauro Carvalho Chehab if (status < 0) 12329a0bf528SMauro Carvalho Chehab goto error; 12339a0bf528SMauro Carvalho Chehab /* Write nomagic word to enable pdr reg write */ 12349a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 12359a0bf528SMauro Carvalho Chehab error: 12369a0bf528SMauro Carvalho Chehab if (status < 0) 12373a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 12389a0bf528SMauro Carvalho Chehab return status; 12399a0bf528SMauro Carvalho Chehab } 12409a0bf528SMauro Carvalho Chehab 1241cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state) 12429a0bf528SMauro Carvalho Chehab { 12439a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 12449a0bf528SMauro Carvalho Chehab 1245cd7a67a4SMauro Carvalho Chehab return mpegts_configure_pins(state, false); 12469a0bf528SMauro Carvalho Chehab } 12479a0bf528SMauro Carvalho Chehab 1248cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state, 1249cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out) 12509a0bf528SMauro Carvalho Chehab { 1251cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0; 12529a0bf528SMauro Carvalho Chehab int status; 12539a0bf528SMauro Carvalho Chehab unsigned long end; 12549a0bf528SMauro Carvalho Chehab 12559a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 12569a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 12579a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN); 12589a0bf528SMauro Carvalho Chehab if (status < 0) 12599a0bf528SMauro Carvalho Chehab goto error; 1260cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset); 12619a0bf528SMauro Carvalho Chehab if (status < 0) 12629a0bf528SMauro Carvalho Chehab goto error; 1263cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements); 12649a0bf528SMauro Carvalho Chehab if (status < 0) 12659a0bf528SMauro Carvalho Chehab goto error; 12669a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 12679a0bf528SMauro Carvalho Chehab if (status < 0) 12689a0bf528SMauro Carvalho Chehab goto error; 12699a0bf528SMauro Carvalho Chehab 1270cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out); 12719a0bf528SMauro Carvalho Chehab do { 1272b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1273cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status); 12749a0bf528SMauro Carvalho Chehab if (status < 0) 12759a0bf528SMauro Carvalho Chehab goto error; 1276cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) && 12779a0bf528SMauro Carvalho Chehab ((time_is_after_jiffies(end)))); 12789a0bf528SMauro Carvalho Chehab 1279cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) { 12803a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 12819a0bf528SMauro Carvalho Chehab status = -EINVAL; 12829a0bf528SMauro Carvalho Chehab goto error2; 12839a0bf528SMauro Carvalho Chehab } 12849a0bf528SMauro Carvalho Chehab error: 12859a0bf528SMauro Carvalho Chehab if (status < 0) 12863a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 12879a0bf528SMauro Carvalho Chehab error2: 12889a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 12899a0bf528SMauro Carvalho Chehab return status; 12909a0bf528SMauro Carvalho Chehab } 12919a0bf528SMauro Carvalho Chehab 12929a0bf528SMauro Carvalho Chehab 1293cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state, 1294cd7a67a4SMauro Carvalho Chehab const u8 p_mc_image[], u32 length) 12959a0bf528SMauro Carvalho Chehab { 1296cd7a67a4SMauro Carvalho Chehab const u8 *p_src = p_mc_image; 1297cd7a67a4SMauro Carvalho Chehab u32 address; 1298cd7a67a4SMauro Carvalho Chehab u16 n_blocks; 1299cd7a67a4SMauro Carvalho Chehab u16 block_size; 13009a0bf528SMauro Carvalho Chehab u32 offset = 0; 13019a0bf528SMauro Carvalho Chehab u32 i; 13029a0bf528SMauro Carvalho Chehab int status = 0; 13039a0bf528SMauro Carvalho Chehab 13049a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 13059a0bf528SMauro Carvalho Chehab 13069a0bf528SMauro Carvalho Chehab /* down the drain (we don't care about MAGIC_WORD) */ 13079a0bf528SMauro Carvalho Chehab #if 0 13089a0bf528SMauro Carvalho Chehab /* For future reference */ 1309cd7a67a4SMauro Carvalho Chehab drain = (p_src[0] << 8) | p_src[1]; 13109a0bf528SMauro Carvalho Chehab #endif 1311cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13129a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 1313cd7a67a4SMauro Carvalho Chehab n_blocks = (p_src[0] << 8) | p_src[1]; 1314cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13159a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13169a0bf528SMauro Carvalho Chehab 1317cd7a67a4SMauro Carvalho Chehab for (i = 0; i < n_blocks; i += 1) { 1318cd7a67a4SMauro Carvalho Chehab address = (p_src[0] << 24) | (p_src[1] << 16) | 1319cd7a67a4SMauro Carvalho Chehab (p_src[2] << 8) | p_src[3]; 1320cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u32); 13219a0bf528SMauro Carvalho Chehab offset += sizeof(u32); 13229a0bf528SMauro Carvalho Chehab 1323cd7a67a4SMauro Carvalho Chehab block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16); 1324cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13259a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13269a0bf528SMauro Carvalho Chehab 13279a0bf528SMauro Carvalho Chehab #if 0 13289a0bf528SMauro Carvalho Chehab /* For future reference */ 1329cd7a67a4SMauro Carvalho Chehab flags = (p_src[0] << 8) | p_src[1]; 13309a0bf528SMauro Carvalho Chehab #endif 1331cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13329a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13339a0bf528SMauro Carvalho Chehab 13349a0bf528SMauro Carvalho Chehab #if 0 13359a0bf528SMauro Carvalho Chehab /* For future reference */ 1336cd7a67a4SMauro Carvalho Chehab block_crc = (p_src[0] << 8) | p_src[1]; 13379a0bf528SMauro Carvalho Chehab #endif 1338cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16); 13399a0bf528SMauro Carvalho Chehab offset += sizeof(u16); 13409a0bf528SMauro Carvalho Chehab 1341cd7a67a4SMauro Carvalho Chehab if (offset + block_size > length) { 13423a4398f5SMauro Carvalho Chehab pr_err("Firmware is corrupted.\n"); 13439a0bf528SMauro Carvalho Chehab return -EINVAL; 13449a0bf528SMauro Carvalho Chehab } 13459a0bf528SMauro Carvalho Chehab 1346cd7a67a4SMauro Carvalho Chehab status = write_block(state, address, block_size, p_src); 13479a0bf528SMauro Carvalho Chehab if (status < 0) { 13483a4398f5SMauro Carvalho Chehab pr_err("Error %d while loading firmware\n", status); 13499a0bf528SMauro Carvalho Chehab break; 13509a0bf528SMauro Carvalho Chehab } 1351cd7a67a4SMauro Carvalho Chehab p_src += block_size; 1352cd7a67a4SMauro Carvalho Chehab offset += block_size; 13539a0bf528SMauro Carvalho Chehab } 13549a0bf528SMauro Carvalho Chehab return status; 13559a0bf528SMauro Carvalho Chehab } 13569a0bf528SMauro Carvalho Chehab 1357cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable) 13589a0bf528SMauro Carvalho Chehab { 13599a0bf528SMauro Carvalho Chehab int status; 13609a0bf528SMauro Carvalho Chehab u16 data = 0; 1361cd7a67a4SMauro Carvalho Chehab u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; 1362cd7a67a4SMauro Carvalho Chehab u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; 13639a0bf528SMauro Carvalho Chehab unsigned long end; 13649a0bf528SMauro Carvalho Chehab 13659a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 13669a0bf528SMauro Carvalho Chehab 13675a7f7b79SMauro Carvalho Chehab if (!enable) { 1368cd7a67a4SMauro Carvalho Chehab desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; 1369cd7a67a4SMauro Carvalho Chehab desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; 13709a0bf528SMauro Carvalho Chehab } 13719a0bf528SMauro Carvalho Chehab 13729a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 1373cd7a67a4SMauro Carvalho Chehab if (status >= 0 && data == desired_status) { 13749a0bf528SMauro Carvalho Chehab /* tokenring already has correct status */ 13759a0bf528SMauro Carvalho Chehab return status; 13769a0bf528SMauro Carvalho Chehab } 13779a0bf528SMauro Carvalho Chehab /* Disable/enable dvbt tokenring bridge */ 1378cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl); 13799a0bf528SMauro Carvalho Chehab 13809a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT); 13819a0bf528SMauro Carvalho Chehab do { 13829a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 1383ab5060cdSMauro Carvalho Chehab if ((status >= 0 && data == desired_status) 1384ab5060cdSMauro Carvalho Chehab || time_is_after_jiffies(end)) 13859a0bf528SMauro Carvalho Chehab break; 1386b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 13879a0bf528SMauro Carvalho Chehab } while (1); 1388cd7a67a4SMauro Carvalho Chehab if (data != desired_status) { 13893a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 13909a0bf528SMauro Carvalho Chehab return -EINVAL; 13919a0bf528SMauro Carvalho Chehab } 13929a0bf528SMauro Carvalho Chehab return status; 13939a0bf528SMauro Carvalho Chehab } 13949a0bf528SMauro Carvalho Chehab 1395cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state) 13969a0bf528SMauro Carvalho Chehab { 13979a0bf528SMauro Carvalho Chehab int status = 0; 1398cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0; 1399cd7a67a4SMauro Carvalho Chehab u16 fec_oc_ipr_mode = 0; 14009a0bf528SMauro Carvalho Chehab 14019a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 14029a0bf528SMauro Carvalho Chehab 140339c1cb2bSJonathan McCrohan /* Graceful shutdown (byte boundaries) */ 1404cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 14059a0bf528SMauro Carvalho Chehab if (status < 0) 14069a0bf528SMauro Carvalho Chehab goto error; 1407cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M; 1408cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 14099a0bf528SMauro Carvalho Chehab if (status < 0) 14109a0bf528SMauro Carvalho Chehab goto error; 14119a0bf528SMauro Carvalho Chehab 14129a0bf528SMauro Carvalho Chehab /* Suppress MCLK during absence of data */ 1413cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode); 14149a0bf528SMauro Carvalho Chehab if (status < 0) 14159a0bf528SMauro Carvalho Chehab goto error; 1416cd7a67a4SMauro Carvalho Chehab fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; 1417cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode); 14189a0bf528SMauro Carvalho Chehab 14199a0bf528SMauro Carvalho Chehab error: 14209a0bf528SMauro Carvalho Chehab if (status < 0) 14213a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 14229a0bf528SMauro Carvalho Chehab 14239a0bf528SMauro Carvalho Chehab return status; 14249a0bf528SMauro Carvalho Chehab } 14259a0bf528SMauro Carvalho Chehab 14269a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state, 1427cd7a67a4SMauro Carvalho Chehab u16 cmd, u8 parameter_len, 1428cd7a67a4SMauro Carvalho Chehab u16 *parameter, u8 result_len, u16 *result) 14299a0bf528SMauro Carvalho Chehab { 14309a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15 14319a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine! 14329a0bf528SMauro Carvalho Chehab #endif 1433cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0; 14349a0bf528SMauro Carvalho Chehab int status = -EINVAL; 14359a0bf528SMauro Carvalho Chehab unsigned long end; 14369a0bf528SMauro Carvalho Chehab u8 buffer[34]; 14379a0bf528SMauro Carvalho Chehab int cnt = 0, ii; 14389a0bf528SMauro Carvalho Chehab const char *p; 14399a0bf528SMauro Carvalho Chehab char errname[30]; 14409a0bf528SMauro Carvalho Chehab 14419a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 14429a0bf528SMauro Carvalho Chehab 1443cd7a67a4SMauro Carvalho Chehab if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) || 1444cd7a67a4SMauro Carvalho Chehab ((result_len > 0) && (result == NULL))) { 14453a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 14469a0bf528SMauro Carvalho Chehab return status; 14479a0bf528SMauro Carvalho Chehab } 14489a0bf528SMauro Carvalho Chehab 14499a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 14509a0bf528SMauro Carvalho Chehab 14519a0bf528SMauro Carvalho Chehab /* assume that the command register is ready 14529a0bf528SMauro Carvalho Chehab since it is checked afterwards */ 1453daad52c8SMauro Carvalho Chehab if (parameter) { 1454cd7a67a4SMauro Carvalho Chehab for (ii = parameter_len - 1; ii >= 0; ii -= 1) { 14559a0bf528SMauro Carvalho Chehab buffer[cnt++] = (parameter[ii] & 0xFF); 14569a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF); 14579a0bf528SMauro Carvalho Chehab } 1458daad52c8SMauro Carvalho Chehab } 14599a0bf528SMauro Carvalho Chehab buffer[cnt++] = (cmd & 0xFF); 14609a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((cmd >> 8) & 0xFF); 14619a0bf528SMauro Carvalho Chehab 14629a0bf528SMauro Carvalho Chehab write_block(state, SCU_RAM_PARAM_0__A - 1463cd7a67a4SMauro Carvalho Chehab (parameter_len - 1), cnt, buffer); 14649a0bf528SMauro Carvalho Chehab /* Wait until SCU has processed command */ 14659a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME); 14669a0bf528SMauro Carvalho Chehab do { 1467b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 1468cd7a67a4SMauro Carvalho Chehab status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd); 14699a0bf528SMauro Carvalho Chehab if (status < 0) 14709a0bf528SMauro Carvalho Chehab goto error; 1471cd7a67a4SMauro Carvalho Chehab } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); 1472cd7a67a4SMauro Carvalho Chehab if (cur_cmd != DRX_SCU_READY) { 14733a4398f5SMauro Carvalho Chehab pr_err("SCU not ready\n"); 14749a0bf528SMauro Carvalho Chehab status = -EIO; 14759a0bf528SMauro Carvalho Chehab goto error2; 14769a0bf528SMauro Carvalho Chehab } 14779a0bf528SMauro Carvalho Chehab /* read results */ 1478cd7a67a4SMauro Carvalho Chehab if ((result_len > 0) && (result != NULL)) { 14799a0bf528SMauro Carvalho Chehab s16 err; 14809a0bf528SMauro Carvalho Chehab int ii; 14819a0bf528SMauro Carvalho Chehab 1482cd7a67a4SMauro Carvalho Chehab for (ii = result_len - 1; ii >= 0; ii -= 1) { 1483ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_PARAM_0__A - ii, 1484ab5060cdSMauro Carvalho Chehab &result[ii]); 14859a0bf528SMauro Carvalho Chehab if (status < 0) 14869a0bf528SMauro Carvalho Chehab goto error; 14879a0bf528SMauro Carvalho Chehab } 14889a0bf528SMauro Carvalho Chehab 14899a0bf528SMauro Carvalho Chehab /* Check if an error was reported by SCU */ 14909a0bf528SMauro Carvalho Chehab err = (s16)result[0]; 14919a0bf528SMauro Carvalho Chehab if (err >= 0) 14929a0bf528SMauro Carvalho Chehab goto error; 14939a0bf528SMauro Carvalho Chehab 14949a0bf528SMauro Carvalho Chehab /* check for the known error codes */ 14959a0bf528SMauro Carvalho Chehab switch (err) { 14969a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKCMD: 14979a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKCMD"; 14989a0bf528SMauro Carvalho Chehab break; 14999a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKSTD: 15009a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKSTD"; 15019a0bf528SMauro Carvalho Chehab break; 15029a0bf528SMauro Carvalho Chehab case SCU_RESULT_SIZE: 15039a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_SIZE"; 15049a0bf528SMauro Carvalho Chehab break; 15059a0bf528SMauro Carvalho Chehab case SCU_RESULT_INVPAR: 15069a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_INVPAR"; 15079a0bf528SMauro Carvalho Chehab break; 15089a0bf528SMauro Carvalho Chehab default: /* Other negative values are errors */ 15099a0bf528SMauro Carvalho Chehab sprintf(errname, "ERROR: %d\n", err); 15109a0bf528SMauro Carvalho Chehab p = errname; 15119a0bf528SMauro Carvalho Chehab } 15123a4398f5SMauro Carvalho Chehab pr_err("%s while sending cmd 0x%04x with params:", p, cmd); 15139a0bf528SMauro Carvalho Chehab print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt); 15149a0bf528SMauro Carvalho Chehab status = -EINVAL; 15159a0bf528SMauro Carvalho Chehab goto error2; 15169a0bf528SMauro Carvalho Chehab } 15179a0bf528SMauro Carvalho Chehab 15189a0bf528SMauro Carvalho Chehab error: 15199a0bf528SMauro Carvalho Chehab if (status < 0) 15203a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 15219a0bf528SMauro Carvalho Chehab error2: 15229a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 15239a0bf528SMauro Carvalho Chehab return status; 15249a0bf528SMauro Carvalho Chehab } 15259a0bf528SMauro Carvalho Chehab 1526cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active) 15279a0bf528SMauro Carvalho Chehab { 15289a0bf528SMauro Carvalho Chehab u16 data = 0; 15299a0bf528SMauro Carvalho Chehab int status; 15309a0bf528SMauro Carvalho Chehab 15319a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 15329a0bf528SMauro Carvalho Chehab 15339a0bf528SMauro Carvalho Chehab /* Configure IQM */ 15349a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 15359a0bf528SMauro Carvalho Chehab if (status < 0) 15369a0bf528SMauro Carvalho Chehab goto error; 15379a0bf528SMauro Carvalho Chehab 15389a0bf528SMauro Carvalho Chehab if (!active) { 15399a0bf528SMauro Carvalho Chehab data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY 15409a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_AMP_STANDBY 15419a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_PD_STANDBY 15429a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY 15439a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY); 15449a0bf528SMauro Carvalho Chehab } else { 15459a0bf528SMauro Carvalho Chehab data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY) 15469a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_AMP_STANDBY) 15479a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_PD_STANDBY) 15489a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY) 15499a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY) 15509a0bf528SMauro Carvalho Chehab ); 15519a0bf528SMauro Carvalho Chehab } 15529a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 15539a0bf528SMauro Carvalho Chehab 15549a0bf528SMauro Carvalho Chehab error: 15559a0bf528SMauro Carvalho Chehab if (status < 0) 15563a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 15579a0bf528SMauro Carvalho Chehab return status; 15589a0bf528SMauro Carvalho Chehab } 15599a0bf528SMauro Carvalho Chehab 1560cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) 15619a0bf528SMauro Carvalho Chehab { 15629a0bf528SMauro Carvalho Chehab int status = 0; 1563cd7a67a4SMauro Carvalho Chehab u16 sio_cc_pwd_mode = 0; 15649a0bf528SMauro Carvalho Chehab 15659a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 15669a0bf528SMauro Carvalho Chehab 15679a0bf528SMauro Carvalho Chehab /* Check arguments */ 15689a0bf528SMauro Carvalho Chehab if (mode == NULL) 15699a0bf528SMauro Carvalho Chehab return -EINVAL; 15709a0bf528SMauro Carvalho Chehab 15719a0bf528SMauro Carvalho Chehab switch (*mode) { 15729a0bf528SMauro Carvalho Chehab case DRX_POWER_UP: 1573cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; 15749a0bf528SMauro Carvalho Chehab break; 15759a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_OFDM: 1576cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM; 15779a0bf528SMauro Carvalho Chehab break; 15789a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_CORE: 1579cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; 15809a0bf528SMauro Carvalho Chehab break; 15819a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_PLL: 1582cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; 15839a0bf528SMauro Carvalho Chehab break; 15849a0bf528SMauro Carvalho Chehab case DRX_POWER_DOWN: 1585cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; 15869a0bf528SMauro Carvalho Chehab break; 15879a0bf528SMauro Carvalho Chehab default: 15889a0bf528SMauro Carvalho Chehab /* Unknow sleep mode */ 15899a0bf528SMauro Carvalho Chehab return -EINVAL; 15909a0bf528SMauro Carvalho Chehab } 15919a0bf528SMauro Carvalho Chehab 15929a0bf528SMauro Carvalho Chehab /* If already in requested power mode, do nothing */ 1593cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode == *mode) 15949a0bf528SMauro Carvalho Chehab return 0; 15959a0bf528SMauro Carvalho Chehab 15969a0bf528SMauro Carvalho Chehab /* For next steps make sure to start from DRX_POWER_UP mode */ 1597cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode != DRX_POWER_UP) { 1598cd7a67a4SMauro Carvalho Chehab status = power_up_device(state); 15999a0bf528SMauro Carvalho Chehab if (status < 0) 16009a0bf528SMauro Carvalho Chehab goto error; 1601cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, true); 16029a0bf528SMauro Carvalho Chehab if (status < 0) 16039a0bf528SMauro Carvalho Chehab goto error; 16049a0bf528SMauro Carvalho Chehab } 16059a0bf528SMauro Carvalho Chehab 16069a0bf528SMauro Carvalho Chehab if (*mode == DRX_POWER_UP) { 16072c149601SMasahiro Yamada /* Restore analog & pin configuration */ 16089a0bf528SMauro Carvalho Chehab } else { 16099a0bf528SMauro Carvalho Chehab /* Power down to requested mode */ 16109a0bf528SMauro Carvalho Chehab /* Backup some register settings */ 16119a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected 16129a0bf528SMauro Carvalho Chehab to them in input mode */ 16139a0bf528SMauro Carvalho Chehab /* Analog power down */ 16149a0bf528SMauro Carvalho Chehab /* ADC power down */ 16159a0bf528SMauro Carvalho Chehab /* Power down device */ 16169a0bf528SMauro Carvalho Chehab /* stop all comm_exec */ 16179a0bf528SMauro Carvalho Chehab /* Stop and power down previous standard */ 1618cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 16199a0bf528SMauro Carvalho Chehab case OM_DVBT: 1620cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 16219a0bf528SMauro Carvalho Chehab if (status < 0) 16229a0bf528SMauro Carvalho Chehab goto error; 1623cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, false); 16249a0bf528SMauro Carvalho Chehab if (status < 0) 16259a0bf528SMauro Carvalho Chehab goto error; 16269a0bf528SMauro Carvalho Chehab break; 16279a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 16289a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1629cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 16309a0bf528SMauro Carvalho Chehab if (status < 0) 16319a0bf528SMauro Carvalho Chehab goto error; 1632cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state); 16339a0bf528SMauro Carvalho Chehab if (status < 0) 16349a0bf528SMauro Carvalho Chehab goto error; 16359a0bf528SMauro Carvalho Chehab break; 16369a0bf528SMauro Carvalho Chehab default: 16379a0bf528SMauro Carvalho Chehab break; 16389a0bf528SMauro Carvalho Chehab } 1639cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false); 16409a0bf528SMauro Carvalho Chehab if (status < 0) 16419a0bf528SMauro Carvalho Chehab goto error; 1642cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode); 16439a0bf528SMauro Carvalho Chehab if (status < 0) 16449a0bf528SMauro Carvalho Chehab goto error; 16459a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 16469a0bf528SMauro Carvalho Chehab if (status < 0) 16479a0bf528SMauro Carvalho Chehab goto error; 16489a0bf528SMauro Carvalho Chehab 16499a0bf528SMauro Carvalho Chehab if (*mode != DRXK_POWER_DOWN_OFDM) { 1650cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |= 16519a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 1652cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state); 16539a0bf528SMauro Carvalho Chehab if (status < 0) 16549a0bf528SMauro Carvalho Chehab goto error; 16559a0bf528SMauro Carvalho Chehab } 16569a0bf528SMauro Carvalho Chehab } 1657cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = *mode; 16589a0bf528SMauro Carvalho Chehab 16599a0bf528SMauro Carvalho Chehab error: 16609a0bf528SMauro Carvalho Chehab if (status < 0) 16613a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 16629a0bf528SMauro Carvalho Chehab 16639a0bf528SMauro Carvalho Chehab return status; 16649a0bf528SMauro Carvalho Chehab } 16659a0bf528SMauro Carvalho Chehab 1666cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) 16679a0bf528SMauro Carvalho Chehab { 1668cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 1669cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 16709a0bf528SMauro Carvalho Chehab u16 data = 0; 16719a0bf528SMauro Carvalho Chehab int status; 16729a0bf528SMauro Carvalho Chehab 16739a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 16749a0bf528SMauro Carvalho Chehab 16759a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data); 16769a0bf528SMauro Carvalho Chehab if (status < 0) 16779a0bf528SMauro Carvalho Chehab goto error; 16789a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) { 16799a0bf528SMauro Carvalho Chehab /* Send OFDM stop command */ 1680ab5060cdSMauro Carvalho Chehab status = scu_command(state, 1681ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 1682ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 1683ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 16849a0bf528SMauro Carvalho Chehab if (status < 0) 16859a0bf528SMauro Carvalho Chehab goto error; 16869a0bf528SMauro Carvalho Chehab /* Send OFDM reset command */ 1687ab5060cdSMauro Carvalho Chehab status = scu_command(state, 1688ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 1689ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 1690ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 16919a0bf528SMauro Carvalho Chehab if (status < 0) 16929a0bf528SMauro Carvalho Chehab goto error; 16939a0bf528SMauro Carvalho Chehab } 16949a0bf528SMauro Carvalho Chehab 16959a0bf528SMauro Carvalho Chehab /* Reset datapath for OFDM, processors first */ 16969a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 16979a0bf528SMauro Carvalho Chehab if (status < 0) 16989a0bf528SMauro Carvalho Chehab goto error; 16999a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 17009a0bf528SMauro Carvalho Chehab if (status < 0) 17019a0bf528SMauro Carvalho Chehab goto error; 17029a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 17039a0bf528SMauro Carvalho Chehab if (status < 0) 17049a0bf528SMauro Carvalho Chehab goto error; 17059a0bf528SMauro Carvalho Chehab 17069a0bf528SMauro Carvalho Chehab /* powerdown AFE */ 1707cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false); 17089a0bf528SMauro Carvalho Chehab if (status < 0) 17099a0bf528SMauro Carvalho Chehab goto error; 17109a0bf528SMauro Carvalho Chehab 17119a0bf528SMauro Carvalho Chehab /* powerdown to OFDM mode */ 1712cd7a67a4SMauro Carvalho Chehab if (set_power_mode) { 1713cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 17149a0bf528SMauro Carvalho Chehab if (status < 0) 17159a0bf528SMauro Carvalho Chehab goto error; 17169a0bf528SMauro Carvalho Chehab } 17179a0bf528SMauro Carvalho Chehab error: 17189a0bf528SMauro Carvalho Chehab if (status < 0) 17193a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 17209a0bf528SMauro Carvalho Chehab return status; 17219a0bf528SMauro Carvalho Chehab } 17229a0bf528SMauro Carvalho Chehab 1723cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state, 1724cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 17259a0bf528SMauro Carvalho Chehab { 17269a0bf528SMauro Carvalho Chehab int status = 0; 17279a0bf528SMauro Carvalho Chehab 17289a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 17299a0bf528SMauro Carvalho Chehab /* 17309a0bf528SMauro Carvalho Chehab Stop and power down previous standard 17319a0bf528SMauro Carvalho Chehab TODO investigate total power down instead of partial 17329a0bf528SMauro Carvalho Chehab power down depending on "previous" standard. 17339a0bf528SMauro Carvalho Chehab */ 17349a0bf528SMauro Carvalho Chehab 17359a0bf528SMauro Carvalho Chehab /* disable HW lock indicator */ 1736ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 1737ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 17389a0bf528SMauro Carvalho Chehab if (status < 0) 17399a0bf528SMauro Carvalho Chehab goto error; 17409a0bf528SMauro Carvalho Chehab 17419a0bf528SMauro Carvalho Chehab /* Device is already at the required mode */ 1742cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == o_mode) 17439a0bf528SMauro Carvalho Chehab return 0; 17449a0bf528SMauro Carvalho Chehab 1745cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 17469a0bf528SMauro Carvalho Chehab /* OM_NONE was added for start up */ 17479a0bf528SMauro Carvalho Chehab case OM_NONE: 17489a0bf528SMauro Carvalho Chehab break; 17499a0bf528SMauro Carvalho Chehab case OM_DVBT: 1750cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 17519a0bf528SMauro Carvalho Chehab if (status < 0) 17529a0bf528SMauro Carvalho Chehab goto error; 1753cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, true); 17549a0bf528SMauro Carvalho Chehab if (status < 0) 17559a0bf528SMauro Carvalho Chehab goto error; 1756cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 17579a0bf528SMauro Carvalho Chehab break; 1758df561f66SGustavo A. R. Silva case OM_QAM_ITU_A: 17599a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1760cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 17619a0bf528SMauro Carvalho Chehab if (status < 0) 17629a0bf528SMauro Carvalho Chehab goto error; 1763cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state); 17649a0bf528SMauro Carvalho Chehab if (status < 0) 17659a0bf528SMauro Carvalho Chehab goto error; 1766cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE; 17679a0bf528SMauro Carvalho Chehab break; 17689a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 17699a0bf528SMauro Carvalho Chehab default: 17709a0bf528SMauro Carvalho Chehab status = -EINVAL; 17719a0bf528SMauro Carvalho Chehab goto error; 17729a0bf528SMauro Carvalho Chehab } 17739a0bf528SMauro Carvalho Chehab 17749a0bf528SMauro Carvalho Chehab /* 17759a0bf528SMauro Carvalho Chehab Power up new standard 17769a0bf528SMauro Carvalho Chehab */ 1777cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 17789a0bf528SMauro Carvalho Chehab case OM_DVBT: 17799a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-T\n"); 1780cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode; 1781cd7a67a4SMauro Carvalho Chehab status = set_dvbt_standard(state, o_mode); 17829a0bf528SMauro Carvalho Chehab if (status < 0) 17839a0bf528SMauro Carvalho Chehab goto error; 17849a0bf528SMauro Carvalho Chehab break; 1785df561f66SGustavo A. R. Silva case OM_QAM_ITU_A: 17869a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 17879a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-C Annex %c\n", 1788cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C'); 1789cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode; 1790cd7a67a4SMauro Carvalho Chehab status = set_qam_standard(state, o_mode); 17919a0bf528SMauro Carvalho Chehab if (status < 0) 17929a0bf528SMauro Carvalho Chehab goto error; 17939a0bf528SMauro Carvalho Chehab break; 17949a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 17959a0bf528SMauro Carvalho Chehab default: 17969a0bf528SMauro Carvalho Chehab status = -EINVAL; 17979a0bf528SMauro Carvalho Chehab } 17989a0bf528SMauro Carvalho Chehab error: 17999a0bf528SMauro Carvalho Chehab if (status < 0) 18003a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 18019a0bf528SMauro Carvalho Chehab return status; 18029a0bf528SMauro Carvalho Chehab } 18039a0bf528SMauro Carvalho Chehab 1804cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq, 1805cd7a67a4SMauro Carvalho Chehab s32 intermediate_frequency) 18069a0bf528SMauro Carvalho Chehab { 18079a0bf528SMauro Carvalho Chehab int status = -EINVAL; 18089a0bf528SMauro Carvalho Chehab 1809cd7a67a4SMauro Carvalho Chehab u16 i_freqk_hz; 1810cd7a67a4SMauro Carvalho Chehab s32 offsetk_hz = offset_freq / 1000; 18119a0bf528SMauro Carvalho Chehab 18129a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 1813cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state != DRXK_STOPPED && 1814cd7a67a4SMauro Carvalho Chehab state->m_drxk_state != DRXK_DTV_STARTED) 18159a0bf528SMauro Carvalho Chehab goto error; 18169a0bf528SMauro Carvalho Chehab 1817cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON); 18189a0bf528SMauro Carvalho Chehab 1819cd7a67a4SMauro Carvalho Chehab if (intermediate_frequency < 0) { 1820cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect; 1821cd7a67a4SMauro Carvalho Chehab intermediate_frequency = -intermediate_frequency; 18229a0bf528SMauro Carvalho Chehab } 18239a0bf528SMauro Carvalho Chehab 1824cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 18259a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 18269a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1827cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000); 1828cd7a67a4SMauro Carvalho Chehab status = set_qam(state, i_freqk_hz, offsetk_hz); 18299a0bf528SMauro Carvalho Chehab if (status < 0) 18309a0bf528SMauro Carvalho Chehab goto error; 1831cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED; 18329a0bf528SMauro Carvalho Chehab break; 18339a0bf528SMauro Carvalho Chehab case OM_DVBT: 1834cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000); 1835cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 18369a0bf528SMauro Carvalho Chehab if (status < 0) 18379a0bf528SMauro Carvalho Chehab goto error; 1838cd7a67a4SMauro Carvalho Chehab status = set_dvbt(state, i_freqk_hz, offsetk_hz); 18399a0bf528SMauro Carvalho Chehab if (status < 0) 18409a0bf528SMauro Carvalho Chehab goto error; 1841cd7a67a4SMauro Carvalho Chehab status = dvbt_start(state); 18429a0bf528SMauro Carvalho Chehab if (status < 0) 18439a0bf528SMauro Carvalho Chehab goto error; 1844cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED; 18459a0bf528SMauro Carvalho Chehab break; 18469a0bf528SMauro Carvalho Chehab default: 18479a0bf528SMauro Carvalho Chehab break; 18489a0bf528SMauro Carvalho Chehab } 18499a0bf528SMauro Carvalho Chehab error: 18509a0bf528SMauro Carvalho Chehab if (status < 0) 18513a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 18529a0bf528SMauro Carvalho Chehab return status; 18539a0bf528SMauro Carvalho Chehab } 18549a0bf528SMauro Carvalho Chehab 1855cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state) 18569a0bf528SMauro Carvalho Chehab { 18579a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 18589a0bf528SMauro Carvalho Chehab 1859cd7a67a4SMauro Carvalho Chehab mpegts_stop(state); 18609a0bf528SMauro Carvalho Chehab return 0; 18619a0bf528SMauro Carvalho Chehab } 18629a0bf528SMauro Carvalho Chehab 1863cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status) 18649a0bf528SMauro Carvalho Chehab { 18659a0bf528SMauro Carvalho Chehab int status = -EINVAL; 18669a0bf528SMauro Carvalho Chehab 18679a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 18689a0bf528SMauro Carvalho Chehab 1869cd7a67a4SMauro Carvalho Chehab if (p_lock_status == NULL) 18709a0bf528SMauro Carvalho Chehab goto error; 18719a0bf528SMauro Carvalho Chehab 1872cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 18739a0bf528SMauro Carvalho Chehab 18749a0bf528SMauro Carvalho Chehab /* define the SCU command code */ 1875cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 18769a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 18779a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B: 18789a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 1879cd7a67a4SMauro Carvalho Chehab status = get_qam_lock_status(state, p_lock_status); 18809a0bf528SMauro Carvalho Chehab break; 18819a0bf528SMauro Carvalho Chehab case OM_DVBT: 1882cd7a67a4SMauro Carvalho Chehab status = get_dvbt_lock_status(state, p_lock_status); 18839a0bf528SMauro Carvalho Chehab break; 18849a0bf528SMauro Carvalho Chehab default: 1885b73bb2abSDaniel Scheller pr_debug("Unsupported operation mode %d in %s\n", 1886b73bb2abSDaniel Scheller state->m_operation_mode, __func__); 1887b73bb2abSDaniel Scheller return 0; 18889a0bf528SMauro Carvalho Chehab } 18899a0bf528SMauro Carvalho Chehab error: 18909a0bf528SMauro Carvalho Chehab if (status < 0) 18913a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 18929a0bf528SMauro Carvalho Chehab return status; 18939a0bf528SMauro Carvalho Chehab } 18949a0bf528SMauro Carvalho Chehab 1895cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state) 18969a0bf528SMauro Carvalho Chehab { 18979a0bf528SMauro Carvalho Chehab int status; 18989a0bf528SMauro Carvalho Chehab 1899cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0; 19009a0bf528SMauro Carvalho Chehab 19019a0bf528SMauro Carvalho Chehab /* Allow OC to sync again */ 1902cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 19039a0bf528SMauro Carvalho Chehab if (status < 0) 19049a0bf528SMauro Carvalho Chehab goto error; 1905cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; 1906cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 19079a0bf528SMauro Carvalho Chehab if (status < 0) 19089a0bf528SMauro Carvalho Chehab goto error; 19099a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_UNLOCK__A, 1); 19109a0bf528SMauro Carvalho Chehab error: 19119a0bf528SMauro Carvalho Chehab if (status < 0) 19123a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 19139a0bf528SMauro Carvalho Chehab return status; 19149a0bf528SMauro Carvalho Chehab } 19159a0bf528SMauro Carvalho Chehab 1916cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state) 19179a0bf528SMauro Carvalho Chehab { 19189a0bf528SMauro Carvalho Chehab int status; 19199a0bf528SMauro Carvalho Chehab 19209a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 19219a0bf528SMauro Carvalho Chehab 19229a0bf528SMauro Carvalho Chehab /* Rate integration settings */ 19239a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000); 19249a0bf528SMauro Carvalho Chehab if (status < 0) 19259a0bf528SMauro Carvalho Chehab goto error; 19269a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C); 19279a0bf528SMauro Carvalho Chehab if (status < 0) 19289a0bf528SMauro Carvalho Chehab goto error; 19299a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A); 19309a0bf528SMauro Carvalho Chehab if (status < 0) 19319a0bf528SMauro Carvalho Chehab goto error; 19329a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008); 19339a0bf528SMauro Carvalho Chehab if (status < 0) 19349a0bf528SMauro Carvalho Chehab goto error; 19359a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006); 19369a0bf528SMauro Carvalho Chehab if (status < 0) 19379a0bf528SMauro Carvalho Chehab goto error; 19389a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680); 19399a0bf528SMauro Carvalho Chehab if (status < 0) 19409a0bf528SMauro Carvalho Chehab goto error; 19419a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080); 19429a0bf528SMauro Carvalho Chehab if (status < 0) 19439a0bf528SMauro Carvalho Chehab goto error; 19449a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4); 19459a0bf528SMauro Carvalho Chehab if (status < 0) 19469a0bf528SMauro Carvalho Chehab goto error; 19479a0bf528SMauro Carvalho Chehab 19489a0bf528SMauro Carvalho Chehab /* Additional configuration */ 19499a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_OCR_INVERT__A, 0); 19509a0bf528SMauro Carvalho Chehab if (status < 0) 19519a0bf528SMauro Carvalho Chehab goto error; 19529a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_LWM__A, 2); 19539a0bf528SMauro Carvalho Chehab if (status < 0) 19549a0bf528SMauro Carvalho Chehab goto error; 19559a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_HWM__A, 12); 19569a0bf528SMauro Carvalho Chehab error: 19579a0bf528SMauro Carvalho Chehab if (status < 0) 19583a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 19599a0bf528SMauro Carvalho Chehab 19609a0bf528SMauro Carvalho Chehab return status; 19619a0bf528SMauro Carvalho Chehab } 19629a0bf528SMauro Carvalho Chehab 1963cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state, 1964cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 19659a0bf528SMauro Carvalho Chehab { 19669a0bf528SMauro Carvalho Chehab int status; 19679a0bf528SMauro Carvalho Chehab 1968cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */ 1969cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */ 1970cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */ 1971cd7a67a4SMauro Carvalho Chehab u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */ 1972cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */ 1973cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */ 1974cd7a67a4SMauro Carvalho Chehab u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */ 1975cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_mode = 0; 1976cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_int_upd_rate = 0; 1977cd7a67a4SMauro Carvalho Chehab u32 max_bit_rate = 0; 1978cd7a67a4SMauro Carvalho Chehab bool static_clk = false; 19799a0bf528SMauro Carvalho Chehab 19809a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 19819a0bf528SMauro Carvalho Chehab 19829a0bf528SMauro Carvalho Chehab /* Check insertion of the Reed-Solomon parity bytes */ 1983cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode); 19849a0bf528SMauro Carvalho Chehab if (status < 0) 19859a0bf528SMauro Carvalho Chehab goto error; 1986cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode); 19879a0bf528SMauro Carvalho Chehab if (status < 0) 19889a0bf528SMauro Carvalho Chehab goto error; 1989cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M); 1990cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); 19915a7f7b79SMauro Carvalho Chehab if (state->m_insert_rs_byte) { 19929a0bf528SMauro Carvalho Chehab /* enable parity symbol forward */ 1993cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M; 19949a0bf528SMauro Carvalho Chehab /* MVAL disable during parity bytes */ 1995cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; 19969a0bf528SMauro Carvalho Chehab /* TS burst length to 204 */ 1997cd7a67a4SMauro Carvalho Chehab fec_oc_dto_burst_len = 204; 19989a0bf528SMauro Carvalho Chehab } 19999a0bf528SMauro Carvalho Chehab 200039c1cb2bSJonathan McCrohan /* Check serial or parallel output */ 2001cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); 20025a7f7b79SMauro Carvalho Chehab if (!state->m_enable_parallel) { 20039a0bf528SMauro Carvalho Chehab /* MPEG data output is serial -> set ipr_mode[0] */ 2004cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; 20059a0bf528SMauro Carvalho Chehab } 20069a0bf528SMauro Carvalho Chehab 2007cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 20089a0bf528SMauro Carvalho Chehab case OM_DVBT: 2009cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbt_bitrate; 2010cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 3; 2011cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xC00000; 2012cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbt_static_clk; 20139a0bf528SMauro Carvalho Chehab break; 2014df561f66SGustavo A. R. Silva case OM_QAM_ITU_A: 20159a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 2016cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 0x0004; 2017cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */ 2018cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbc_bitrate; 2019cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbc_static_clk; 20209a0bf528SMauro Carvalho Chehab break; 20219a0bf528SMauro Carvalho Chehab default: 20229a0bf528SMauro Carvalho Chehab status = -EINVAL; 20239a0bf528SMauro Carvalho Chehab } /* switch (standard) */ 20249a0bf528SMauro Carvalho Chehab if (status < 0) 20259a0bf528SMauro Carvalho Chehab goto error; 20269a0bf528SMauro Carvalho Chehab 20279a0bf528SMauro Carvalho Chehab /* Configure DTO's */ 2028cd7a67a4SMauro Carvalho Chehab if (static_clk) { 2029cd7a67a4SMauro Carvalho Chehab u32 bit_rate = 0; 20309a0bf528SMauro Carvalho Chehab 20319a0bf528SMauro Carvalho Chehab /* Rational DTO for MCLK source (static MCLK rate), 20329a0bf528SMauro Carvalho Chehab Dynamic DTO for optimal grouping 20339a0bf528SMauro Carvalho Chehab (avoid intra-packet gaps), 20349a0bf528SMauro Carvalho Chehab DTO offset enable to sync TS burst with MSTRT */ 2035cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M | 20369a0bf528SMauro Carvalho Chehab FEC_OC_DTO_MODE_OFFSET_ENABLE__M); 2037cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M | 20389a0bf528SMauro Carvalho Chehab FEC_OC_FCT_MODE_VIRT_ENA__M); 20399a0bf528SMauro Carvalho Chehab 20409a0bf528SMauro Carvalho Chehab /* Check user defined bitrate */ 2041cd7a67a4SMauro Carvalho Chehab bit_rate = max_bit_rate; 2042cd7a67a4SMauro Carvalho Chehab if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */ 2043cd7a67a4SMauro Carvalho Chehab bit_rate = 75900000UL; 20449a0bf528SMauro Carvalho Chehab } 20459a0bf528SMauro Carvalho Chehab /* Rational DTO period: 20469a0bf528SMauro Carvalho Chehab dto_period = (Fsys / bitrate) - 2 20479a0bf528SMauro Carvalho Chehab 2048cd7a67a4SMauro Carvalho Chehab result should be floored, 20499a0bf528SMauro Carvalho Chehab to make sure >= requested bitrate 20509a0bf528SMauro Carvalho Chehab */ 2051cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = (u16) (((state->m_sys_clock_freq) 2052cd7a67a4SMauro Carvalho Chehab * 1000) / bit_rate); 2053cd7a67a4SMauro Carvalho Chehab if (fec_oc_dto_period <= 2) 2054cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = 0; 20559a0bf528SMauro Carvalho Chehab else 2056cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period -= 2; 2057cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 8; 20589a0bf528SMauro Carvalho Chehab } else { 2059cd7a67a4SMauro Carvalho Chehab /* (commonAttr->static_clk == false) => dynamic mode */ 2060cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M; 2061cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE; 2062cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 5; 20639a0bf528SMauro Carvalho Chehab } 20649a0bf528SMauro Carvalho Chehab 20659a0bf528SMauro Carvalho Chehab /* Write appropriate registers with requested configuration */ 2066cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len); 20679a0bf528SMauro Carvalho Chehab if (status < 0) 20689a0bf528SMauro Carvalho Chehab goto error; 2069cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period); 20709a0bf528SMauro Carvalho Chehab if (status < 0) 20719a0bf528SMauro Carvalho Chehab goto error; 2072cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode); 20739a0bf528SMauro Carvalho Chehab if (status < 0) 20749a0bf528SMauro Carvalho Chehab goto error; 2075cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode); 20769a0bf528SMauro Carvalho Chehab if (status < 0) 20779a0bf528SMauro Carvalho Chehab goto error; 2078cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode); 20799a0bf528SMauro Carvalho Chehab if (status < 0) 20809a0bf528SMauro Carvalho Chehab goto error; 2081cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode); 20829a0bf528SMauro Carvalho Chehab if (status < 0) 20839a0bf528SMauro Carvalho Chehab goto error; 20849a0bf528SMauro Carvalho Chehab 20859a0bf528SMauro Carvalho Chehab /* Rate integration settings */ 2086cd7a67a4SMauro Carvalho Chehab status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate); 20879a0bf528SMauro Carvalho Chehab if (status < 0) 20889a0bf528SMauro Carvalho Chehab goto error; 2089ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, 2090ab5060cdSMauro Carvalho Chehab fec_oc_tmd_int_upd_rate); 20919a0bf528SMauro Carvalho Chehab if (status < 0) 20929a0bf528SMauro Carvalho Chehab goto error; 2093cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode); 20949a0bf528SMauro Carvalho Chehab error: 20959a0bf528SMauro Carvalho Chehab if (status < 0) 20963a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 20979a0bf528SMauro Carvalho Chehab return status; 20989a0bf528SMauro Carvalho Chehab } 20999a0bf528SMauro Carvalho Chehab 2100cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state) 21019a0bf528SMauro Carvalho Chehab { 2102cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_invert = 0; 21039a0bf528SMauro Carvalho Chehab 21049a0bf528SMauro Carvalho Chehab /* Data mask for the output data byte */ 2105cd7a67a4SMauro Carvalho Chehab u16 invert_data_mask = 21069a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M | 21079a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M | 21089a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M | 21099a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M; 21109a0bf528SMauro Carvalho Chehab 21119a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 21129a0bf528SMauro Carvalho Chehab 21139a0bf528SMauro Carvalho Chehab /* Control selective inversion of output bits */ 2114cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(invert_data_mask)); 21155a7f7b79SMauro Carvalho Chehab if (state->m_invert_data) 2116cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= invert_data_mask; 2117cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M)); 21185a7f7b79SMauro Carvalho Chehab if (state->m_invert_err) 2119cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M; 2120cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); 21215a7f7b79SMauro Carvalho Chehab if (state->m_invert_str) 2122cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M; 2123cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); 21245a7f7b79SMauro Carvalho Chehab if (state->m_invert_val) 2125cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M; 2126cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); 21275a7f7b79SMauro Carvalho Chehab if (state->m_invert_clk) 2128cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M; 21299a0bf528SMauro Carvalho Chehab 2130cd7a67a4SMauro Carvalho Chehab return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert); 21319a0bf528SMauro Carvalho Chehab } 21329a0bf528SMauro Carvalho Chehab 21339a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000 21349a0bf528SMauro Carvalho Chehab 2135cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state, 2136cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv) 21379a0bf528SMauro Carvalho Chehab { 21389a0bf528SMauro Carvalho Chehab int status = -EINVAL; 21399a0bf528SMauro Carvalho Chehab u16 data = 0; 2140cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_if_agc_settings; 21419a0bf528SMauro Carvalho Chehab 21429a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 21439a0bf528SMauro Carvalho Chehab 2144cd7a67a4SMauro Carvalho Chehab if (p_agc_cfg == NULL) 21459a0bf528SMauro Carvalho Chehab goto error; 21469a0bf528SMauro Carvalho Chehab 2147cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) { 21489a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO: 21499a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */ 21509a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 21519a0bf528SMauro Carvalho Chehab if (status < 0) 21529a0bf528SMauro Carvalho Chehab goto error; 21539a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 21549a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 21559a0bf528SMauro Carvalho Chehab if (status < 0) 21569a0bf528SMauro Carvalho Chehab goto error; 21579a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 21589a0bf528SMauro Carvalho Chehab if (status < 0) 21599a0bf528SMauro Carvalho Chehab goto error; 21609a0bf528SMauro Carvalho Chehab 21619a0bf528SMauro Carvalho Chehab /* Enable SCU RF AGC loop */ 21629a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 21639a0bf528SMauro Carvalho Chehab 21649a0bf528SMauro Carvalho Chehab /* Polarity */ 2165cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol) 21669a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21679a0bf528SMauro Carvalho Chehab else 21689a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21699a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 21709a0bf528SMauro Carvalho Chehab if (status < 0) 21719a0bf528SMauro Carvalho Chehab goto error; 21729a0bf528SMauro Carvalho Chehab 21739a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */ 21749a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 21759a0bf528SMauro Carvalho Chehab if (status < 0) 21769a0bf528SMauro Carvalho Chehab goto error; 21779a0bf528SMauro Carvalho Chehab 21789a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M; 2179cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed << 21809a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_RAGC_RED__B) 21819a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_RAGC_RED__M); 21829a0bf528SMauro Carvalho Chehab 21839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 21849a0bf528SMauro Carvalho Chehab if (status < 0) 21859a0bf528SMauro Carvalho Chehab goto error; 21869a0bf528SMauro Carvalho Chehab 2187cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state)) 2188cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_dvbt_if_agc_cfg; 2189cd7a67a4SMauro Carvalho Chehab else if (is_qam(state)) 2190cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_qam_if_agc_cfg; 21919a0bf528SMauro Carvalho Chehab else 2192cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_atv_if_agc_cfg; 2193cd7a67a4SMauro Carvalho Chehab if (p_if_agc_settings == NULL) { 21949a0bf528SMauro Carvalho Chehab status = -EINVAL; 21959a0bf528SMauro Carvalho Chehab goto error; 21969a0bf528SMauro Carvalho Chehab } 21979a0bf528SMauro Carvalho Chehab 21989a0bf528SMauro Carvalho Chehab /* Set TOP, only if IF-AGC is in AUTO mode */ 219989fffac8SMauro Carvalho Chehab if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) { 2200ab5060cdSMauro Carvalho Chehab status = write16(state, 2201ab5060cdSMauro Carvalho Chehab SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2202ab5060cdSMauro Carvalho Chehab p_agc_cfg->top); 22039a0bf528SMauro Carvalho Chehab if (status < 0) 22049a0bf528SMauro Carvalho Chehab goto error; 220589fffac8SMauro Carvalho Chehab } 22069a0bf528SMauro Carvalho Chehab 22079a0bf528SMauro Carvalho Chehab /* Cut-Off current */ 2208ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 2209ab5060cdSMauro Carvalho Chehab p_agc_cfg->cut_off_current); 22109a0bf528SMauro Carvalho Chehab if (status < 0) 22119a0bf528SMauro Carvalho Chehab goto error; 22129a0bf528SMauro Carvalho Chehab 22139a0bf528SMauro Carvalho Chehab /* Max. output level */ 2214ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_MAX__A, 2215ab5060cdSMauro Carvalho Chehab p_agc_cfg->max_output_level); 22169a0bf528SMauro Carvalho Chehab if (status < 0) 22179a0bf528SMauro Carvalho Chehab goto error; 22189a0bf528SMauro Carvalho Chehab 22199a0bf528SMauro Carvalho Chehab break; 22209a0bf528SMauro Carvalho Chehab 22219a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER: 22229a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */ 22239a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 22249a0bf528SMauro Carvalho Chehab if (status < 0) 22259a0bf528SMauro Carvalho Chehab goto error; 22269a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22279a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 22289a0bf528SMauro Carvalho Chehab if (status < 0) 22299a0bf528SMauro Carvalho Chehab goto error; 22309a0bf528SMauro Carvalho Chehab 22319a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */ 22329a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22339a0bf528SMauro Carvalho Chehab if (status < 0) 22349a0bf528SMauro Carvalho Chehab goto error; 22359a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 2236cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol) 22379a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22389a0bf528SMauro Carvalho Chehab else 22399a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22419a0bf528SMauro Carvalho Chehab if (status < 0) 22429a0bf528SMauro Carvalho Chehab goto error; 22439a0bf528SMauro Carvalho Chehab 22449a0bf528SMauro Carvalho Chehab /* SCU c.o.c. to 0, enabling full control range */ 22459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0); 22469a0bf528SMauro Carvalho Chehab if (status < 0) 22479a0bf528SMauro Carvalho Chehab goto error; 22489a0bf528SMauro Carvalho Chehab 22499a0bf528SMauro Carvalho Chehab /* Write value to output pin */ 2250ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 2251ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level); 22529a0bf528SMauro Carvalho Chehab if (status < 0) 22539a0bf528SMauro Carvalho Chehab goto error; 22549a0bf528SMauro Carvalho Chehab break; 22559a0bf528SMauro Carvalho Chehab 22569a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF: 22579a0bf528SMauro Carvalho Chehab /* Disable RF AGC DAC */ 22589a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 22599a0bf528SMauro Carvalho Chehab if (status < 0) 22609a0bf528SMauro Carvalho Chehab goto error; 22619a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22629a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 22639a0bf528SMauro Carvalho Chehab if (status < 0) 22649a0bf528SMauro Carvalho Chehab goto error; 22659a0bf528SMauro Carvalho Chehab 22669a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */ 22679a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22689a0bf528SMauro Carvalho Chehab if (status < 0) 22699a0bf528SMauro Carvalho Chehab goto error; 22709a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 22719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22729a0bf528SMauro Carvalho Chehab if (status < 0) 22739a0bf528SMauro Carvalho Chehab goto error; 22749a0bf528SMauro Carvalho Chehab break; 22759a0bf528SMauro Carvalho Chehab 22769a0bf528SMauro Carvalho Chehab default: 22779a0bf528SMauro Carvalho Chehab status = -EINVAL; 22789a0bf528SMauro Carvalho Chehab 22799a0bf528SMauro Carvalho Chehab } 22809a0bf528SMauro Carvalho Chehab error: 22819a0bf528SMauro Carvalho Chehab if (status < 0) 22823a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 22839a0bf528SMauro Carvalho Chehab return status; 22849a0bf528SMauro Carvalho Chehab } 22859a0bf528SMauro Carvalho Chehab 22869a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000 22879a0bf528SMauro Carvalho Chehab 2288cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state, 2289cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv) 22909a0bf528SMauro Carvalho Chehab { 22919a0bf528SMauro Carvalho Chehab u16 data = 0; 22929a0bf528SMauro Carvalho Chehab int status = 0; 2293cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_rf_agc_settings; 22949a0bf528SMauro Carvalho Chehab 22959a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 22969a0bf528SMauro Carvalho Chehab 2297cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) { 22989a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO: 22999a0bf528SMauro Carvalho Chehab 23009a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */ 23019a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 23029a0bf528SMauro Carvalho Chehab if (status < 0) 23039a0bf528SMauro Carvalho Chehab goto error; 23049a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23059a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 23069a0bf528SMauro Carvalho Chehab if (status < 0) 23079a0bf528SMauro Carvalho Chehab goto error; 23089a0bf528SMauro Carvalho Chehab 23099a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23109a0bf528SMauro Carvalho Chehab if (status < 0) 23119a0bf528SMauro Carvalho Chehab goto error; 23129a0bf528SMauro Carvalho Chehab 23139a0bf528SMauro Carvalho Chehab /* Enable SCU IF AGC loop */ 23149a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23159a0bf528SMauro Carvalho Chehab 23169a0bf528SMauro Carvalho Chehab /* Polarity */ 2317cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol) 23189a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23199a0bf528SMauro Carvalho Chehab else 23209a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23229a0bf528SMauro Carvalho Chehab if (status < 0) 23239a0bf528SMauro Carvalho Chehab goto error; 23249a0bf528SMauro Carvalho Chehab 23259a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */ 23269a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 23279a0bf528SMauro Carvalho Chehab if (status < 0) 23289a0bf528SMauro Carvalho Chehab goto error; 23299a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M; 2330cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed << 23319a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_IAGC_RED__B) 23329a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_IAGC_RED__M); 23339a0bf528SMauro Carvalho Chehab 23349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 23359a0bf528SMauro Carvalho Chehab if (status < 0) 23369a0bf528SMauro Carvalho Chehab goto error; 23379a0bf528SMauro Carvalho Chehab 2338cd7a67a4SMauro Carvalho Chehab if (is_qam(state)) 2339cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_qam_rf_agc_cfg; 23409a0bf528SMauro Carvalho Chehab else 2341cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_atv_rf_agc_cfg; 2342cd7a67a4SMauro Carvalho Chehab if (p_rf_agc_settings == NULL) 23439a0bf528SMauro Carvalho Chehab return -1; 23449a0bf528SMauro Carvalho Chehab /* Restore TOP */ 2345ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2346ab5060cdSMauro Carvalho Chehab p_rf_agc_settings->top); 23479a0bf528SMauro Carvalho Chehab if (status < 0) 23489a0bf528SMauro Carvalho Chehab goto error; 23499a0bf528SMauro Carvalho Chehab break; 23509a0bf528SMauro Carvalho Chehab 23519a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER: 23529a0bf528SMauro Carvalho Chehab 23539a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */ 23549a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 23559a0bf528SMauro Carvalho Chehab if (status < 0) 23569a0bf528SMauro Carvalho Chehab goto error; 23579a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23589a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 23599a0bf528SMauro Carvalho Chehab if (status < 0) 23609a0bf528SMauro Carvalho Chehab goto error; 23619a0bf528SMauro Carvalho Chehab 23629a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23639a0bf528SMauro Carvalho Chehab if (status < 0) 23649a0bf528SMauro Carvalho Chehab goto error; 23659a0bf528SMauro Carvalho Chehab 23669a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */ 23679a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23689a0bf528SMauro Carvalho Chehab 23699a0bf528SMauro Carvalho Chehab /* Polarity */ 2370cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol) 23719a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23729a0bf528SMauro Carvalho Chehab else 23739a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23759a0bf528SMauro Carvalho Chehab if (status < 0) 23769a0bf528SMauro Carvalho Chehab goto error; 23779a0bf528SMauro Carvalho Chehab 23789a0bf528SMauro Carvalho Chehab /* Write value to output pin */ 2379ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 2380ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level); 23819a0bf528SMauro Carvalho Chehab if (status < 0) 23829a0bf528SMauro Carvalho Chehab goto error; 23839a0bf528SMauro Carvalho Chehab break; 23849a0bf528SMauro Carvalho Chehab 23859a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF: 23869a0bf528SMauro Carvalho Chehab 23879a0bf528SMauro Carvalho Chehab /* Disable If AGC DAC */ 23889a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data); 23899a0bf528SMauro Carvalho Chehab if (status < 0) 23909a0bf528SMauro Carvalho Chehab goto error; 23919a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23929a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data); 23939a0bf528SMauro Carvalho Chehab if (status < 0) 23949a0bf528SMauro Carvalho Chehab goto error; 23959a0bf528SMauro Carvalho Chehab 23969a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */ 23979a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23989a0bf528SMauro Carvalho Chehab if (status < 0) 23999a0bf528SMauro Carvalho Chehab goto error; 24009a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 24019a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 24029a0bf528SMauro Carvalho Chehab if (status < 0) 24039a0bf528SMauro Carvalho Chehab goto error; 24049a0bf528SMauro Carvalho Chehab break; 2405cd7a67a4SMauro Carvalho Chehab } /* switch (agcSettingsIf->ctrl_mode) */ 24069a0bf528SMauro Carvalho Chehab 24079a0bf528SMauro Carvalho Chehab /* always set the top to support 24089a0bf528SMauro Carvalho Chehab configurations without if-loop */ 2409cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top); 24109a0bf528SMauro Carvalho Chehab error: 24119a0bf528SMauro Carvalho Chehab if (status < 0) 24123a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 24139a0bf528SMauro Carvalho Chehab return status; 24149a0bf528SMauro Carvalho Chehab } 24159a0bf528SMauro Carvalho Chehab 2416cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state, 2417cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise) 24189a0bf528SMauro Carvalho Chehab { 24199a0bf528SMauro Carvalho Chehab int status = 0; 2420cd7a67a4SMauro Carvalho Chehab u16 qam_sl_err_power = 0; /* accum. error between 24219a0bf528SMauro Carvalho Chehab raw and sliced symbols */ 2422cd7a67a4SMauro Carvalho Chehab u32 qam_sl_sig_power = 0; /* used for MER, depends of 24239a0bf528SMauro Carvalho Chehab QAM modulation */ 2424cd7a67a4SMauro Carvalho Chehab u32 qam_sl_mer = 0; /* QAM MER */ 24259a0bf528SMauro Carvalho Chehab 24269a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 24279a0bf528SMauro Carvalho Chehab 24289a0bf528SMauro Carvalho Chehab /* MER calculation */ 24299a0bf528SMauro Carvalho Chehab 24309a0bf528SMauro Carvalho Chehab /* get the register value needed for MER */ 2431cd7a67a4SMauro Carvalho Chehab status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power); 24329a0bf528SMauro Carvalho Chehab if (status < 0) { 24333a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 24349a0bf528SMauro Carvalho Chehab return -EINVAL; 24359a0bf528SMauro Carvalho Chehab } 24369a0bf528SMauro Carvalho Chehab 24379a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 24389a0bf528SMauro Carvalho Chehab case QAM_16: 2439cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; 24409a0bf528SMauro Carvalho Chehab break; 24419a0bf528SMauro Carvalho Chehab case QAM_32: 2442cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; 24439a0bf528SMauro Carvalho Chehab break; 24449a0bf528SMauro Carvalho Chehab case QAM_64: 2445cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; 24469a0bf528SMauro Carvalho Chehab break; 24479a0bf528SMauro Carvalho Chehab case QAM_128: 2448cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; 24499a0bf528SMauro Carvalho Chehab break; 24509a0bf528SMauro Carvalho Chehab default: 24519a0bf528SMauro Carvalho Chehab case QAM_256: 2452cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; 24539a0bf528SMauro Carvalho Chehab break; 24549a0bf528SMauro Carvalho Chehab } 24559a0bf528SMauro Carvalho Chehab 2456cd7a67a4SMauro Carvalho Chehab if (qam_sl_err_power > 0) { 2457cd7a67a4SMauro Carvalho Chehab qam_sl_mer = log10times100(qam_sl_sig_power) - 2458cd7a67a4SMauro Carvalho Chehab log10times100((u32) qam_sl_err_power); 24599a0bf528SMauro Carvalho Chehab } 2460cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = qam_sl_mer; 24619a0bf528SMauro Carvalho Chehab 24629a0bf528SMauro Carvalho Chehab return status; 24639a0bf528SMauro Carvalho Chehab } 24649a0bf528SMauro Carvalho Chehab 2465cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state, 2466cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise) 24679a0bf528SMauro Carvalho Chehab { 24689a0bf528SMauro Carvalho Chehab int status; 2469cd7a67a4SMauro Carvalho Chehab u16 reg_data = 0; 2470cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_i = 0; 2471cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_q = 0; 2472cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_sqr_err_exp = 0; 2473cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_tps_pwr_ofs = 0; 2474cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_req_smb_cnt = 0; 2475cd7a67a4SMauro Carvalho Chehab u32 tps_cnt = 0; 2476cd7a67a4SMauro Carvalho Chehab u32 sqr_err_iq = 0; 24779a0bf528SMauro Carvalho Chehab u32 a = 0; 24789a0bf528SMauro Carvalho Chehab u32 b = 0; 24799a0bf528SMauro Carvalho Chehab u32 c = 0; 2480cd7a67a4SMauro Carvalho Chehab u32 i_mer = 0; 2481cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0; 24829a0bf528SMauro Carvalho Chehab 24839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 24849a0bf528SMauro Carvalho Chehab 2485ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, 2486ab5060cdSMauro Carvalho Chehab &eq_reg_td_tps_pwr_ofs); 24879a0bf528SMauro Carvalho Chehab if (status < 0) 24889a0bf528SMauro Carvalho Chehab goto error; 2489ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, 2490ab5060cdSMauro Carvalho Chehab &eq_reg_td_req_smb_cnt); 24919a0bf528SMauro Carvalho Chehab if (status < 0) 24929a0bf528SMauro Carvalho Chehab goto error; 2493ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, 2494ab5060cdSMauro Carvalho Chehab &eq_reg_td_sqr_err_exp); 24959a0bf528SMauro Carvalho Chehab if (status < 0) 24969a0bf528SMauro Carvalho Chehab goto error; 2497ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, 2498ab5060cdSMauro Carvalho Chehab ®_data); 24999a0bf528SMauro Carvalho Chehab if (status < 0) 25009a0bf528SMauro Carvalho Chehab goto error; 25019a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_I operational range */ 2502cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i = (u32) reg_data; 2503cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) && 2504cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_i < 0x00000FFFUL)) { 2505cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i += 0x00010000UL; 25069a0bf528SMauro Carvalho Chehab } 2507cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data); 25089a0bf528SMauro Carvalho Chehab if (status < 0) 25099a0bf528SMauro Carvalho Chehab goto error; 25109a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_Q operational range */ 2511cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q = (u32) reg_data; 2512cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) && 2513cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_q < 0x00000FFFUL)) 2514cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q += 0x00010000UL; 25159a0bf528SMauro Carvalho Chehab 2516ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, 2517ab5060cdSMauro Carvalho Chehab &transmission_params); 25189a0bf528SMauro Carvalho Chehab if (status < 0) 25199a0bf528SMauro Carvalho Chehab goto error; 25209a0bf528SMauro Carvalho Chehab 25219a0bf528SMauro Carvalho Chehab /* Check input data for MER */ 25229a0bf528SMauro Carvalho Chehab 25239a0bf528SMauro Carvalho Chehab /* MER calculation (in 0.1 dB) without math.h */ 2524cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0)) 2525cd7a67a4SMauro Carvalho Chehab i_mer = 0; 2526cd7a67a4SMauro Carvalho Chehab else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) { 25279a0bf528SMauro Carvalho Chehab /* No error at all, this must be the HW reset value 25289a0bf528SMauro Carvalho Chehab * Apparently no first measurement yet 25299a0bf528SMauro Carvalho Chehab * Set MER to 0.0 */ 2530cd7a67a4SMauro Carvalho Chehab i_mer = 0; 25319a0bf528SMauro Carvalho Chehab } else { 2532cd7a67a4SMauro Carvalho Chehab sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) << 2533cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_exp; 2534cd7a67a4SMauro Carvalho Chehab if ((transmission_params & 25359a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_PARAM_MODE__M) 25369a0bf528SMauro Carvalho Chehab == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K) 2537cd7a67a4SMauro Carvalho Chehab tps_cnt = 17; 25389a0bf528SMauro Carvalho Chehab else 2539cd7a67a4SMauro Carvalho Chehab tps_cnt = 68; 25409a0bf528SMauro Carvalho Chehab 25419a0bf528SMauro Carvalho Chehab /* IMER = 100 * log10 (x) 2542cd7a67a4SMauro Carvalho Chehab where x = (eq_reg_td_tps_pwr_ofs^2 * 2543cd7a67a4SMauro Carvalho Chehab eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq 25449a0bf528SMauro Carvalho Chehab 25459a0bf528SMauro Carvalho Chehab => IMER = a + b -c 2546cd7a67a4SMauro Carvalho Chehab where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2) 2547cd7a67a4SMauro Carvalho Chehab b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt) 2548cd7a67a4SMauro Carvalho Chehab c = 100 * log10 (sqr_err_iq) 25499a0bf528SMauro Carvalho Chehab */ 25509a0bf528SMauro Carvalho Chehab 25519a0bf528SMauro Carvalho Chehab /* log(x) x = 9bits * 9bits->18 bits */ 2552cd7a67a4SMauro Carvalho Chehab a = log10times100(eq_reg_td_tps_pwr_ofs * 2553cd7a67a4SMauro Carvalho Chehab eq_reg_td_tps_pwr_ofs); 25549a0bf528SMauro Carvalho Chehab /* log(x) x = 16bits * 7bits->23 bits */ 2555cd7a67a4SMauro Carvalho Chehab b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt); 25569a0bf528SMauro Carvalho Chehab /* log(x) x = (16bits + 16bits) << 15 ->32 bits */ 2557cd7a67a4SMauro Carvalho Chehab c = log10times100(sqr_err_iq); 25589a0bf528SMauro Carvalho Chehab 2559cd7a67a4SMauro Carvalho Chehab i_mer = a + b - c; 25609a0bf528SMauro Carvalho Chehab } 2561cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = i_mer; 25629a0bf528SMauro Carvalho Chehab 25639a0bf528SMauro Carvalho Chehab error: 25649a0bf528SMauro Carvalho Chehab if (status < 0) 25653a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 25669a0bf528SMauro Carvalho Chehab return status; 25679a0bf528SMauro Carvalho Chehab } 25689a0bf528SMauro Carvalho Chehab 2569cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) 25709a0bf528SMauro Carvalho Chehab { 25719a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 25729a0bf528SMauro Carvalho Chehab 2573cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = 0; 2574cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 25759a0bf528SMauro Carvalho Chehab case OM_DVBT: 2576cd7a67a4SMauro Carvalho Chehab return get_dvbt_signal_to_noise(state, p_signal_to_noise); 25779a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 25789a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 2579cd7a67a4SMauro Carvalho Chehab return get_qam_signal_to_noise(state, p_signal_to_noise); 25809a0bf528SMauro Carvalho Chehab default: 25819a0bf528SMauro Carvalho Chehab break; 25829a0bf528SMauro Carvalho Chehab } 25839a0bf528SMauro Carvalho Chehab return 0; 25849a0bf528SMauro Carvalho Chehab } 25859a0bf528SMauro Carvalho Chehab 25869a0bf528SMauro Carvalho Chehab #if 0 2587cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) 25889a0bf528SMauro Carvalho Chehab { 25899a0bf528SMauro Carvalho Chehab /* SNR Values for quasi errorfree reception rom Nordig 2.2 */ 25909a0bf528SMauro Carvalho Chehab int status = 0; 25919a0bf528SMauro Carvalho Chehab 25929a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 25939a0bf528SMauro Carvalho Chehab 25949a0bf528SMauro Carvalho Chehab static s32 QE_SN[] = { 25959a0bf528SMauro Carvalho Chehab 51, /* QPSK 1/2 */ 25969a0bf528SMauro Carvalho Chehab 69, /* QPSK 2/3 */ 25979a0bf528SMauro Carvalho Chehab 79, /* QPSK 3/4 */ 25989a0bf528SMauro Carvalho Chehab 89, /* QPSK 5/6 */ 25999a0bf528SMauro Carvalho Chehab 97, /* QPSK 7/8 */ 26009a0bf528SMauro Carvalho Chehab 108, /* 16-QAM 1/2 */ 26019a0bf528SMauro Carvalho Chehab 131, /* 16-QAM 2/3 */ 26029a0bf528SMauro Carvalho Chehab 146, /* 16-QAM 3/4 */ 26039a0bf528SMauro Carvalho Chehab 156, /* 16-QAM 5/6 */ 26049a0bf528SMauro Carvalho Chehab 160, /* 16-QAM 7/8 */ 26059a0bf528SMauro Carvalho Chehab 165, /* 64-QAM 1/2 */ 26069a0bf528SMauro Carvalho Chehab 187, /* 64-QAM 2/3 */ 26079a0bf528SMauro Carvalho Chehab 202, /* 64-QAM 3/4 */ 26089a0bf528SMauro Carvalho Chehab 216, /* 64-QAM 5/6 */ 26099a0bf528SMauro Carvalho Chehab 225, /* 64-QAM 7/8 */ 26109a0bf528SMauro Carvalho Chehab }; 26119a0bf528SMauro Carvalho Chehab 2612cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 26139a0bf528SMauro Carvalho Chehab 26149a0bf528SMauro Carvalho Chehab do { 2615cd7a67a4SMauro Carvalho Chehab s32 signal_to_noise = 0; 2616cd7a67a4SMauro Carvalho Chehab u16 constellation = 0; 2617cd7a67a4SMauro Carvalho Chehab u16 code_rate = 0; 2618cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel; 2619cd7a67a4SMauro Carvalho Chehab u32 ber_quality; 26209a0bf528SMauro Carvalho Chehab 2621cd7a67a4SMauro Carvalho Chehab status = get_dvbt_signal_to_noise(state, &signal_to_noise); 26229a0bf528SMauro Carvalho Chehab if (status < 0) 26239a0bf528SMauro Carvalho Chehab break; 2624ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, 2625ab5060cdSMauro Carvalho Chehab &constellation); 26269a0bf528SMauro Carvalho Chehab if (status < 0) 26279a0bf528SMauro Carvalho Chehab break; 2628cd7a67a4SMauro Carvalho Chehab constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; 26299a0bf528SMauro Carvalho Chehab 2630ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, 2631ab5060cdSMauro Carvalho Chehab &code_rate); 26329a0bf528SMauro Carvalho Chehab if (status < 0) 26339a0bf528SMauro Carvalho Chehab break; 2634cd7a67a4SMauro Carvalho Chehab code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; 26359a0bf528SMauro Carvalho Chehab 2636cd7a67a4SMauro Carvalho Chehab if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || 2637cd7a67a4SMauro Carvalho Chehab code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) 26389a0bf528SMauro Carvalho Chehab break; 2639cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 2640cd7a67a4SMauro Carvalho Chehab QE_SN[constellation * 5 + code_rate]; 2641cd7a67a4SMauro Carvalho Chehab ber_quality = 100; 26429a0bf528SMauro Carvalho Chehab 2643cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70) 2644cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 2645cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30) 2646cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) * 2647cd7a67a4SMauro Carvalho Chehab ber_quality) / 100; 26489a0bf528SMauro Carvalho Chehab else 2649cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality; 26509a0bf528SMauro Carvalho Chehab } while (0); 26519a0bf528SMauro Carvalho Chehab return 0; 26529a0bf528SMauro Carvalho Chehab }; 26539a0bf528SMauro Carvalho Chehab 2654cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality) 26559a0bf528SMauro Carvalho Chehab { 26569a0bf528SMauro Carvalho Chehab int status = 0; 2657cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 26589a0bf528SMauro Carvalho Chehab 26599a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 26609a0bf528SMauro Carvalho Chehab 26619a0bf528SMauro Carvalho Chehab do { 2662cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise = 0; 2663cd7a67a4SMauro Carvalho Chehab u32 ber_quality = 100; 2664cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel = 0; 26659a0bf528SMauro Carvalho Chehab 2666cd7a67a4SMauro Carvalho Chehab status = get_qam_signal_to_noise(state, &signal_to_noise); 26679a0bf528SMauro Carvalho Chehab if (status < 0) 26689a0bf528SMauro Carvalho Chehab break; 26699a0bf528SMauro Carvalho Chehab 26709a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 26719a0bf528SMauro Carvalho Chehab case QAM_16: 2672cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 200; 26739a0bf528SMauro Carvalho Chehab break; 26749a0bf528SMauro Carvalho Chehab case QAM_32: 2675cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 230; 26769a0bf528SMauro Carvalho Chehab break; /* Not in NorDig */ 26779a0bf528SMauro Carvalho Chehab case QAM_64: 2678cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 260; 26799a0bf528SMauro Carvalho Chehab break; 26809a0bf528SMauro Carvalho Chehab case QAM_128: 2681cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 290; 26829a0bf528SMauro Carvalho Chehab break; 26839a0bf528SMauro Carvalho Chehab default: 26849a0bf528SMauro Carvalho Chehab case QAM_256: 2685cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 320; 26869a0bf528SMauro Carvalho Chehab break; 26879a0bf528SMauro Carvalho Chehab } 26889a0bf528SMauro Carvalho Chehab 2689cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70) 2690cd7a67a4SMauro Carvalho Chehab *p_quality = 0; 2691cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30) 2692cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) * 2693cd7a67a4SMauro Carvalho Chehab ber_quality) / 100; 26949a0bf528SMauro Carvalho Chehab else 2695cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality; 26969a0bf528SMauro Carvalho Chehab } while (0); 26979a0bf528SMauro Carvalho Chehab 26989a0bf528SMauro Carvalho Chehab return status; 26999a0bf528SMauro Carvalho Chehab } 27009a0bf528SMauro Carvalho Chehab 2701cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality) 27029a0bf528SMauro Carvalho Chehab { 27039a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27049a0bf528SMauro Carvalho Chehab 2705cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) { 27069a0bf528SMauro Carvalho Chehab case OM_DVBT: 2707cd7a67a4SMauro Carvalho Chehab return get_dvbt_quality(state, p_quality); 27089a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 2709cd7a67a4SMauro Carvalho Chehab return get_dvbc_quality(state, p_quality); 27109a0bf528SMauro Carvalho Chehab default: 27119a0bf528SMauro Carvalho Chehab break; 27129a0bf528SMauro Carvalho Chehab } 27139a0bf528SMauro Carvalho Chehab 27149a0bf528SMauro Carvalho Chehab return 0; 27159a0bf528SMauro Carvalho Chehab } 27169a0bf528SMauro Carvalho Chehab #endif 27179a0bf528SMauro Carvalho Chehab 27189a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */ 27199a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040 27209a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A 0x420060 27219a0bf528SMauro Carvalho Chehab 27229a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A) 27239a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7) 27249a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ 27259a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE 27269a0bf528SMauro Carvalho Chehab 27279a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F) 27289a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F) 27299a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF) 27309a0bf528SMauro Carvalho Chehab 2731cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) 27329a0bf528SMauro Carvalho Chehab { 27339a0bf528SMauro Carvalho Chehab int status = -EINVAL; 27349a0bf528SMauro Carvalho Chehab 27359a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27369a0bf528SMauro Carvalho Chehab 2737cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 27389a0bf528SMauro Carvalho Chehab return 0; 2739cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_POWERED_DOWN) 27409a0bf528SMauro Carvalho Chehab goto error; 27419a0bf528SMauro Carvalho Chehab 27429a0bf528SMauro Carvalho Chehab if (state->no_i2c_bridge) 27439a0bf528SMauro Carvalho Chehab return 0; 27449a0bf528SMauro Carvalho Chehab 2745ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 2746ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 27479a0bf528SMauro Carvalho Chehab if (status < 0) 27489a0bf528SMauro Carvalho Chehab goto error; 2749cd7a67a4SMauro Carvalho Chehab if (b_enable_bridge) { 2750ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 2751ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); 27529a0bf528SMauro Carvalho Chehab if (status < 0) 27539a0bf528SMauro Carvalho Chehab goto error; 27549a0bf528SMauro Carvalho Chehab } else { 2755ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 2756ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); 27579a0bf528SMauro Carvalho Chehab if (status < 0) 27589a0bf528SMauro Carvalho Chehab goto error; 27599a0bf528SMauro Carvalho Chehab } 27609a0bf528SMauro Carvalho Chehab 2761b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); 27629a0bf528SMauro Carvalho Chehab 27639a0bf528SMauro Carvalho Chehab error: 27649a0bf528SMauro Carvalho Chehab if (status < 0) 27653a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 27669a0bf528SMauro Carvalho Chehab return status; 27679a0bf528SMauro Carvalho Chehab } 27689a0bf528SMauro Carvalho Chehab 2769cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state, 2770cd7a67a4SMauro Carvalho Chehab struct s_cfg_pre_saw *p_pre_saw_cfg) 27719a0bf528SMauro Carvalho Chehab { 27729a0bf528SMauro Carvalho Chehab int status = -EINVAL; 27739a0bf528SMauro Carvalho Chehab 27749a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27759a0bf528SMauro Carvalho Chehab 2776cd7a67a4SMauro Carvalho Chehab if ((p_pre_saw_cfg == NULL) 2777cd7a67a4SMauro Carvalho Chehab || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M)) 27789a0bf528SMauro Carvalho Chehab goto error; 27799a0bf528SMauro Carvalho Chehab 2780cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference); 27819a0bf528SMauro Carvalho Chehab error: 27829a0bf528SMauro Carvalho Chehab if (status < 0) 27833a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 27849a0bf528SMauro Carvalho Chehab return status; 27859a0bf528SMauro Carvalho Chehab } 27869a0bf528SMauro Carvalho Chehab 2787cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, 2788cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out) 27899a0bf528SMauro Carvalho Chehab { 2790cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0; 2791cd7a67a4SMauro Carvalho Chehab u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF); 2792cd7a67a4SMauro Carvalho Chehab u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF); 27939a0bf528SMauro Carvalho Chehab int status; 27949a0bf528SMauro Carvalho Chehab unsigned long end; 27959a0bf528SMauro Carvalho Chehab 27969a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 27979a0bf528SMauro Carvalho Chehab 27989a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex); 27999a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT); 28009a0bf528SMauro Carvalho Chehab if (status < 0) 28019a0bf528SMauro Carvalho Chehab goto error; 28029a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_HDR__A, blockbank); 28039a0bf528SMauro Carvalho Chehab if (status < 0) 28049a0bf528SMauro Carvalho Chehab goto error; 28059a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_ADDR__A, offset); 28069a0bf528SMauro Carvalho Chehab if (status < 0) 28079a0bf528SMauro Carvalho Chehab goto error; 2808cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset); 28099a0bf528SMauro Carvalho Chehab if (status < 0) 28109a0bf528SMauro Carvalho Chehab goto error; 2811cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements); 28129a0bf528SMauro Carvalho Chehab if (status < 0) 28139a0bf528SMauro Carvalho Chehab goto error; 28149a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 28159a0bf528SMauro Carvalho Chehab if (status < 0) 28169a0bf528SMauro Carvalho Chehab goto error; 28179a0bf528SMauro Carvalho Chehab 2818cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out); 28199a0bf528SMauro Carvalho Chehab do { 2820cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status); 28219a0bf528SMauro Carvalho Chehab if (status < 0) 28229a0bf528SMauro Carvalho Chehab goto error; 2823cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) && time_is_after_jiffies(end)); 2824cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) { 28253a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n"); 28269a0bf528SMauro Carvalho Chehab status = -EINVAL; 28279a0bf528SMauro Carvalho Chehab goto error2; 28289a0bf528SMauro Carvalho Chehab } 28299a0bf528SMauro Carvalho Chehab error: 28309a0bf528SMauro Carvalho Chehab if (status < 0) 28313a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 28329a0bf528SMauro Carvalho Chehab error2: 28339a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex); 28349a0bf528SMauro Carvalho Chehab return status; 28359a0bf528SMauro Carvalho Chehab 28369a0bf528SMauro Carvalho Chehab } 28379a0bf528SMauro Carvalho Chehab 2838cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count) 28399a0bf528SMauro Carvalho Chehab { 28409a0bf528SMauro Carvalho Chehab u16 data = 0; 28419a0bf528SMauro Carvalho Chehab int status; 28429a0bf528SMauro Carvalho Chehab 28439a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 28449a0bf528SMauro Carvalho Chehab 2845cd7a67a4SMauro Carvalho Chehab /* start measurement */ 28469a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE); 28479a0bf528SMauro Carvalho Chehab if (status < 0) 28489a0bf528SMauro Carvalho Chehab goto error; 28499a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 1); 28509a0bf528SMauro Carvalho Chehab if (status < 0) 28519a0bf528SMauro Carvalho Chehab goto error; 28529a0bf528SMauro Carvalho Chehab 28539a0bf528SMauro Carvalho Chehab *count = 0; 28549a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE0__A, &data); 28559a0bf528SMauro Carvalho Chehab if (status < 0) 28569a0bf528SMauro Carvalho Chehab goto error; 28579a0bf528SMauro Carvalho Chehab if (data == 127) 28589a0bf528SMauro Carvalho Chehab *count = *count + 1; 28599a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE1__A, &data); 28609a0bf528SMauro Carvalho Chehab if (status < 0) 28619a0bf528SMauro Carvalho Chehab goto error; 28629a0bf528SMauro Carvalho Chehab if (data == 127) 28639a0bf528SMauro Carvalho Chehab *count = *count + 1; 28649a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE2__A, &data); 28659a0bf528SMauro Carvalho Chehab if (status < 0) 28669a0bf528SMauro Carvalho Chehab goto error; 28679a0bf528SMauro Carvalho Chehab if (data == 127) 28689a0bf528SMauro Carvalho Chehab *count = *count + 1; 28699a0bf528SMauro Carvalho Chehab 28709a0bf528SMauro Carvalho Chehab error: 28719a0bf528SMauro Carvalho Chehab if (status < 0) 28723a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 28739a0bf528SMauro Carvalho Chehab return status; 28749a0bf528SMauro Carvalho Chehab } 28759a0bf528SMauro Carvalho Chehab 2876cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state) 28779a0bf528SMauro Carvalho Chehab { 28789a0bf528SMauro Carvalho Chehab u16 count = 0; 28799a0bf528SMauro Carvalho Chehab int status; 28809a0bf528SMauro Carvalho Chehab 28819a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 28829a0bf528SMauro Carvalho Chehab 2883cd7a67a4SMauro Carvalho Chehab status = adc_sync_measurement(state, &count); 28849a0bf528SMauro Carvalho Chehab if (status < 0) 28859a0bf528SMauro Carvalho Chehab goto error; 28869a0bf528SMauro Carvalho Chehab 28879a0bf528SMauro Carvalho Chehab if (count == 1) { 288839c1cb2bSJonathan McCrohan /* Try sampling on a different edge */ 2889cd7a67a4SMauro Carvalho Chehab u16 clk_neg = 0; 28909a0bf528SMauro Carvalho Chehab 2891cd7a67a4SMauro Carvalho Chehab status = read16(state, IQM_AF_CLKNEG__A, &clk_neg); 28929a0bf528SMauro Carvalho Chehab if (status < 0) 28939a0bf528SMauro Carvalho Chehab goto error; 2894cd7a67a4SMauro Carvalho Chehab if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) == 28959a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { 2896cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 2897cd7a67a4SMauro Carvalho Chehab clk_neg |= 28989a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG; 28999a0bf528SMauro Carvalho Chehab } else { 2900cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 2901cd7a67a4SMauro Carvalho Chehab clk_neg |= 29029a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS; 29039a0bf528SMauro Carvalho Chehab } 2904cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_CLKNEG__A, clk_neg); 29059a0bf528SMauro Carvalho Chehab if (status < 0) 29069a0bf528SMauro Carvalho Chehab goto error; 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 29129a0bf528SMauro Carvalho Chehab if (count < 2) 29139a0bf528SMauro Carvalho Chehab status = -EINVAL; 29149a0bf528SMauro Carvalho Chehab error: 29159a0bf528SMauro Carvalho Chehab if (status < 0) 29163a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 29179a0bf528SMauro Carvalho Chehab return status; 29189a0bf528SMauro Carvalho Chehab } 29199a0bf528SMauro Carvalho Chehab 2920cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state, 2921cd7a67a4SMauro Carvalho Chehab u16 intermediate_freqk_hz, 2922cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset, bool is_dtv) 29239a0bf528SMauro Carvalho Chehab { 2924cd7a67a4SMauro Carvalho Chehab bool select_pos_image = false; 2925cd7a67a4SMauro Carvalho Chehab u32 rf_freq_residual = tuner_freq_offset; 2926cd7a67a4SMauro Carvalho Chehab u32 fm_frequency_shift = 0; 2927cd7a67a4SMauro Carvalho Chehab bool tuner_mirror = !state->m_b_mirror_freq_spect; 2928cd7a67a4SMauro Carvalho Chehab u32 adc_freq; 2929cd7a67a4SMauro Carvalho Chehab bool adc_flip; 29309a0bf528SMauro Carvalho Chehab int status; 2931cd7a67a4SMauro Carvalho Chehab u32 if_freq_actual; 2932cd7a67a4SMauro Carvalho Chehab u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3); 2933cd7a67a4SMauro Carvalho Chehab u32 frequency_shift; 2934cd7a67a4SMauro Carvalho Chehab bool image_to_select; 29359a0bf528SMauro Carvalho Chehab 29369a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 29379a0bf528SMauro Carvalho Chehab 29389a0bf528SMauro Carvalho Chehab /* 29399a0bf528SMauro Carvalho Chehab Program frequency shifter 29409a0bf528SMauro Carvalho Chehab No need to account for mirroring on RF 29419a0bf528SMauro Carvalho Chehab */ 2942cd7a67a4SMauro Carvalho Chehab if (is_dtv) { 2943cd7a67a4SMauro Carvalho Chehab if ((state->m_operation_mode == OM_QAM_ITU_A) || 2944cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_C) || 2945cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_DVBT)) 2946cd7a67a4SMauro Carvalho Chehab select_pos_image = true; 29479a0bf528SMauro Carvalho Chehab else 2948cd7a67a4SMauro Carvalho Chehab select_pos_image = false; 29499a0bf528SMauro Carvalho Chehab } 2950cd7a67a4SMauro Carvalho Chehab if (tuner_mirror) 29519a0bf528SMauro Carvalho Chehab /* tuner doesn't mirror */ 2952cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz + 2953cd7a67a4SMauro Carvalho Chehab rf_freq_residual + fm_frequency_shift; 29549a0bf528SMauro Carvalho Chehab else 29559a0bf528SMauro Carvalho Chehab /* tuner mirrors */ 2956cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz - 2957cd7a67a4SMauro Carvalho Chehab rf_freq_residual - fm_frequency_shift; 2958cd7a67a4SMauro Carvalho Chehab if (if_freq_actual > sampling_frequency / 2) { 29599a0bf528SMauro Carvalho Chehab /* adc mirrors */ 2960cd7a67a4SMauro Carvalho Chehab adc_freq = sampling_frequency - if_freq_actual; 2961cd7a67a4SMauro Carvalho Chehab adc_flip = true; 29629a0bf528SMauro Carvalho Chehab } else { 29639a0bf528SMauro Carvalho Chehab /* adc doesn't mirror */ 2964cd7a67a4SMauro Carvalho Chehab adc_freq = if_freq_actual; 2965cd7a67a4SMauro Carvalho Chehab adc_flip = false; 29669a0bf528SMauro Carvalho Chehab } 29679a0bf528SMauro Carvalho Chehab 2968cd7a67a4SMauro Carvalho Chehab frequency_shift = adc_freq; 2969cd7a67a4SMauro Carvalho Chehab image_to_select = state->m_rfmirror ^ tuner_mirror ^ 2970cd7a67a4SMauro Carvalho Chehab adc_flip ^ select_pos_image; 2971cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs = 2972cd7a67a4SMauro Carvalho Chehab Frac28a((frequency_shift), sampling_frequency); 29739a0bf528SMauro Carvalho Chehab 2974cd7a67a4SMauro Carvalho Chehab if (image_to_select) 2975cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1; 29769a0bf528SMauro Carvalho Chehab 29779a0bf528SMauro Carvalho Chehab /* Program frequency shifter with tuner offset compensation */ 2978cd7a67a4SMauro Carvalho Chehab /* frequency_shift += tuner_freq_offset; TODO */ 29799a0bf528SMauro Carvalho Chehab status = write32(state, IQM_FS_RATE_OFS_LO__A, 2980cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs); 29819a0bf528SMauro Carvalho Chehab if (status < 0) 29823a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 29839a0bf528SMauro Carvalho Chehab return status; 29849a0bf528SMauro Carvalho Chehab } 29859a0bf528SMauro Carvalho Chehab 2986cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv) 29879a0bf528SMauro Carvalho Chehab { 2988cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt = 0; 2989cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_min = 0; 2990cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_max = 0; 2991cd7a67a4SMauro Carvalho Chehab u16 clp_cyclen = 0; 2992cd7a67a4SMauro Carvalho Chehab u16 clp_sum_min = 0; 2993cd7a67a4SMauro Carvalho Chehab u16 clp_dir_to = 0; 2994cd7a67a4SMauro Carvalho Chehab u16 sns_sum_min = 0; 2995cd7a67a4SMauro Carvalho Chehab u16 sns_sum_max = 0; 2996cd7a67a4SMauro Carvalho Chehab u16 clp_sum_max = 0; 2997cd7a67a4SMauro Carvalho Chehab u16 sns_dir_to = 0; 2998cd7a67a4SMauro Carvalho Chehab u16 ki_innergain_min = 0; 2999cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt = 0; 3000cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_min = 0; 3001cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_max = 0; 30029a0bf528SMauro Carvalho Chehab u16 data = 0; 3003cd7a67a4SMauro Carvalho Chehab u16 fast_clp_ctrl_delay = 0; 3004cd7a67a4SMauro Carvalho Chehab u16 clp_ctrl_mode = 0; 30059a0bf528SMauro Carvalho Chehab int status = 0; 30069a0bf528SMauro Carvalho Chehab 30079a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 30089a0bf528SMauro Carvalho Chehab 30099a0bf528SMauro Carvalho Chehab /* Common settings */ 3010cd7a67a4SMauro Carvalho Chehab sns_sum_max = 1023; 3011cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_min = 2047; 3012cd7a67a4SMauro Carvalho Chehab clp_cyclen = 500; 3013cd7a67a4SMauro Carvalho Chehab clp_sum_max = 1023; 30149a0bf528SMauro Carvalho Chehab 30159a0bf528SMauro Carvalho Chehab /* AGCInit() not available for DVBT; init done in microcode */ 3016cd7a67a4SMauro Carvalho Chehab if (!is_qam(state)) { 30173a4398f5SMauro Carvalho Chehab pr_err("%s: mode %d is not DVB-C\n", 30183a4398f5SMauro Carvalho Chehab __func__, state->m_operation_mode); 30199a0bf528SMauro Carvalho Chehab return -EINVAL; 30209a0bf528SMauro Carvalho Chehab } 30219a0bf528SMauro Carvalho Chehab 30229a0bf528SMauro Carvalho Chehab /* FIXME: Analog TV AGC require different settings */ 30239a0bf528SMauro Carvalho Chehab 30249a0bf528SMauro Carvalho Chehab /* Standard specific settings */ 3025cd7a67a4SMauro Carvalho Chehab clp_sum_min = 8; 3026cd7a67a4SMauro Carvalho Chehab clp_dir_to = (u16) -9; 3027cd7a67a4SMauro Carvalho Chehab clp_ctrl_mode = 0; 3028cd7a67a4SMauro Carvalho Chehab sns_sum_min = 8; 3029cd7a67a4SMauro Carvalho Chehab sns_dir_to = (u16) -9; 3030cd7a67a4SMauro Carvalho Chehab ki_innergain_min = (u16) -1030; 3031cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_max = 0x2380; 3032cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt = 0x2380; 3033cd7a67a4SMauro Carvalho Chehab ingain_tgt_min = 0x0511; 3034cd7a67a4SMauro Carvalho Chehab ingain_tgt = 0x0511; 3035cd7a67a4SMauro Carvalho Chehab ingain_tgt_max = 5119; 3036cd7a67a4SMauro Carvalho Chehab fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay; 30379a0bf528SMauro Carvalho Chehab 3038ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 3039ab5060cdSMauro Carvalho Chehab fast_clp_ctrl_delay); 30409a0bf528SMauro Carvalho Chehab if (status < 0) 30419a0bf528SMauro Carvalho Chehab goto error; 30429a0bf528SMauro Carvalho Chehab 3043cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode); 30449a0bf528SMauro Carvalho Chehab if (status < 0) 30459a0bf528SMauro Carvalho Chehab goto error; 3046cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt); 30479a0bf528SMauro Carvalho Chehab if (status < 0) 30489a0bf528SMauro Carvalho Chehab goto error; 3049cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min); 30509a0bf528SMauro Carvalho Chehab if (status < 0) 30519a0bf528SMauro Carvalho Chehab goto error; 3052cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max); 30539a0bf528SMauro Carvalho Chehab if (status < 0) 30549a0bf528SMauro Carvalho Chehab goto error; 3055ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, 3056ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_min); 30579a0bf528SMauro Carvalho Chehab if (status < 0) 30589a0bf528SMauro Carvalho Chehab goto error; 3059ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 3060ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_max); 30619a0bf528SMauro Carvalho Chehab if (status < 0) 30629a0bf528SMauro Carvalho Chehab goto error; 30639a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0); 30649a0bf528SMauro Carvalho Chehab if (status < 0) 30659a0bf528SMauro Carvalho Chehab goto error; 30669a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0); 30679a0bf528SMauro Carvalho Chehab if (status < 0) 30689a0bf528SMauro Carvalho Chehab goto error; 30699a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0); 30709a0bf528SMauro Carvalho Chehab if (status < 0) 30719a0bf528SMauro Carvalho Chehab goto error; 30729a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0); 30739a0bf528SMauro Carvalho Chehab if (status < 0) 30749a0bf528SMauro Carvalho Chehab goto error; 3075cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max); 30769a0bf528SMauro Carvalho Chehab if (status < 0) 30779a0bf528SMauro Carvalho Chehab goto error; 3078cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max); 30799a0bf528SMauro Carvalho Chehab if (status < 0) 30809a0bf528SMauro Carvalho Chehab goto error; 30819a0bf528SMauro Carvalho Chehab 3082ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, 3083ab5060cdSMauro Carvalho Chehab ki_innergain_min); 30849a0bf528SMauro Carvalho Chehab if (status < 0) 30859a0bf528SMauro Carvalho Chehab goto error; 3086ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 3087ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt); 30889a0bf528SMauro Carvalho Chehab if (status < 0) 30899a0bf528SMauro Carvalho Chehab goto error; 3090cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen); 30919a0bf528SMauro Carvalho Chehab if (status < 0) 30929a0bf528SMauro Carvalho Chehab goto error; 30939a0bf528SMauro Carvalho Chehab 30949a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023); 30959a0bf528SMauro Carvalho Chehab if (status < 0) 30969a0bf528SMauro Carvalho Chehab goto error; 30979a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023); 30989a0bf528SMauro Carvalho Chehab if (status < 0) 30999a0bf528SMauro Carvalho Chehab goto error; 31009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50); 31019a0bf528SMauro Carvalho Chehab if (status < 0) 31029a0bf528SMauro Carvalho Chehab goto error; 31039a0bf528SMauro Carvalho Chehab 31049a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20); 31059a0bf528SMauro Carvalho Chehab if (status < 0) 31069a0bf528SMauro Carvalho Chehab goto error; 3107cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min); 31089a0bf528SMauro Carvalho Chehab if (status < 0) 31099a0bf528SMauro Carvalho Chehab goto error; 3110cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min); 31119a0bf528SMauro Carvalho Chehab if (status < 0) 31129a0bf528SMauro Carvalho Chehab goto error; 3113cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to); 31149a0bf528SMauro Carvalho Chehab if (status < 0) 31159a0bf528SMauro Carvalho Chehab goto error; 3116cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to); 31179a0bf528SMauro Carvalho Chehab if (status < 0) 31189a0bf528SMauro Carvalho Chehab goto error; 31199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff); 31209a0bf528SMauro Carvalho Chehab if (status < 0) 31219a0bf528SMauro Carvalho Chehab goto error; 31229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0); 31239a0bf528SMauro Carvalho Chehab if (status < 0) 31249a0bf528SMauro Carvalho Chehab goto error; 31259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117); 31269a0bf528SMauro Carvalho Chehab if (status < 0) 31279a0bf528SMauro Carvalho Chehab goto error; 31289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657); 31299a0bf528SMauro Carvalho Chehab if (status < 0) 31309a0bf528SMauro Carvalho Chehab goto error; 31319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0); 31329a0bf528SMauro Carvalho Chehab if (status < 0) 31339a0bf528SMauro Carvalho Chehab goto error; 31349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0); 31359a0bf528SMauro Carvalho Chehab if (status < 0) 31369a0bf528SMauro Carvalho Chehab goto error; 31379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0); 31389a0bf528SMauro Carvalho Chehab if (status < 0) 31399a0bf528SMauro Carvalho Chehab goto error; 31409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1); 31419a0bf528SMauro Carvalho Chehab if (status < 0) 31429a0bf528SMauro Carvalho Chehab goto error; 31439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0); 31449a0bf528SMauro Carvalho Chehab if (status < 0) 31459a0bf528SMauro Carvalho Chehab goto error; 31469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0); 31479a0bf528SMauro Carvalho Chehab if (status < 0) 31489a0bf528SMauro Carvalho Chehab goto error; 31499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0); 31509a0bf528SMauro Carvalho Chehab if (status < 0) 31519a0bf528SMauro Carvalho Chehab goto error; 31529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1); 31539a0bf528SMauro Carvalho Chehab if (status < 0) 31549a0bf528SMauro Carvalho Chehab goto error; 31559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500); 31569a0bf528SMauro Carvalho Chehab if (status < 0) 31579a0bf528SMauro Carvalho Chehab goto error; 31589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500); 31599a0bf528SMauro Carvalho Chehab if (status < 0) 31609a0bf528SMauro Carvalho Chehab goto error; 31619a0bf528SMauro Carvalho Chehab 31629a0bf528SMauro Carvalho Chehab /* Initialize inner-loop KI gain factors */ 31639a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI__A, &data); 31649a0bf528SMauro Carvalho Chehab if (status < 0) 31659a0bf528SMauro Carvalho Chehab goto error; 31669a0bf528SMauro Carvalho Chehab 31679a0bf528SMauro Carvalho Chehab data = 0x0657; 31689a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RF__M; 31699a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B); 31709a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_IF__M; 31719a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B); 31729a0bf528SMauro Carvalho Chehab 31739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI__A, data); 31749a0bf528SMauro Carvalho Chehab error: 31759a0bf528SMauro Carvalho Chehab if (status < 0) 31763a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 31779a0bf528SMauro Carvalho Chehab return status; 31789a0bf528SMauro Carvalho Chehab } 31799a0bf528SMauro Carvalho Chehab 3180cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err) 31819a0bf528SMauro Carvalho Chehab { 31829a0bf528SMauro Carvalho Chehab int status; 31839a0bf528SMauro Carvalho Chehab 31849a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3185cd7a67a4SMauro Carvalho Chehab if (packet_err == NULL) 31869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 31879a0bf528SMauro Carvalho Chehab else 3188ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 3189ab5060cdSMauro Carvalho Chehab packet_err); 31909a0bf528SMauro Carvalho Chehab if (status < 0) 31913a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 31929a0bf528SMauro Carvalho Chehab return status; 31939a0bf528SMauro Carvalho Chehab } 31949a0bf528SMauro Carvalho Chehab 3195cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state, 31969a0bf528SMauro Carvalho Chehab u16 cmd, u16 subcmd, 31979a0bf528SMauro Carvalho Chehab u16 param0, u16 param1, u16 param2, 31989a0bf528SMauro Carvalho Chehab u16 param3, u16 param4) 31999a0bf528SMauro Carvalho Chehab { 3200cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0; 3201cd7a67a4SMauro Carvalho Chehab u16 err_code = 0; 3202cd7a67a4SMauro Carvalho Chehab u16 retry_cnt = 0; 3203cd7a67a4SMauro Carvalho Chehab u16 sc_exec = 0; 32049a0bf528SMauro Carvalho Chehab int status; 32059a0bf528SMauro Carvalho Chehab 32069a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3207cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec); 3208cd7a67a4SMauro Carvalho Chehab if (sc_exec != 1) { 32099a0bf528SMauro Carvalho Chehab /* SC is not running */ 32109a0bf528SMauro Carvalho Chehab status = -EINVAL; 32119a0bf528SMauro Carvalho Chehab } 32129a0bf528SMauro Carvalho Chehab if (status < 0) 32139a0bf528SMauro Carvalho Chehab goto error; 32149a0bf528SMauro Carvalho Chehab 32159a0bf528SMauro Carvalho Chehab /* Wait until sc is ready to receive command */ 3216cd7a67a4SMauro Carvalho Chehab retry_cnt = 0; 32179a0bf528SMauro Carvalho Chehab do { 3218b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 3219cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 3220cd7a67a4SMauro Carvalho Chehab retry_cnt++; 3221cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 3222cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32239a0bf528SMauro Carvalho Chehab goto error; 32249a0bf528SMauro Carvalho Chehab 32259a0bf528SMauro Carvalho Chehab /* Write sub-command */ 32269a0bf528SMauro Carvalho Chehab switch (cmd) { 32279a0bf528SMauro Carvalho Chehab /* All commands using sub-cmd */ 32289a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 32299a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32309a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32319a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd); 32329a0bf528SMauro Carvalho Chehab if (status < 0) 32339a0bf528SMauro Carvalho Chehab goto error; 32349a0bf528SMauro Carvalho Chehab break; 32359a0bf528SMauro Carvalho Chehab default: 32369a0bf528SMauro Carvalho Chehab /* Do nothing */ 32379a0bf528SMauro Carvalho Chehab break; 32389a0bf528SMauro Carvalho Chehab } 32399a0bf528SMauro Carvalho Chehab 32409a0bf528SMauro Carvalho Chehab /* Write needed parameters and the command */ 32412f60f13cSMauro Carvalho Chehab status = 0; 32429a0bf528SMauro Carvalho Chehab switch (cmd) { 32439a0bf528SMauro Carvalho Chehab /* All commands using 5 parameters */ 32449a0bf528SMauro Carvalho Chehab /* All commands using 4 parameters */ 32459a0bf528SMauro Carvalho Chehab /* All commands using 3 parameters */ 32469a0bf528SMauro Carvalho Chehab /* All commands using 2 parameters */ 32479a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 32489a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32499a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32502f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1); 3251df561f66SGustavo A. R. Silva fallthrough; /* All commands using 1 parameters */ 32529a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 32539a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO: 32542f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0); 3255df561f66SGustavo A. R. Silva fallthrough; /* All commands using 0 parameters */ 32569a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 32579a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL: 32589a0bf528SMauro Carvalho Chehab /* Write command */ 32592f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd); 32609a0bf528SMauro Carvalho Chehab break; 32619a0bf528SMauro Carvalho Chehab default: 32629a0bf528SMauro Carvalho Chehab /* Unknown command */ 32639a0bf528SMauro Carvalho Chehab status = -EINVAL; 32649a0bf528SMauro Carvalho Chehab } 32659a0bf528SMauro Carvalho Chehab if (status < 0) 32669a0bf528SMauro Carvalho Chehab goto error; 32679a0bf528SMauro Carvalho Chehab 32689a0bf528SMauro Carvalho Chehab /* Wait until sc is ready processing command */ 3269cd7a67a4SMauro Carvalho Chehab retry_cnt = 0; 32709a0bf528SMauro Carvalho Chehab do { 3271b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 3272cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 3273cd7a67a4SMauro Carvalho Chehab retry_cnt++; 3274cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 3275cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32769a0bf528SMauro Carvalho Chehab goto error; 32779a0bf528SMauro Carvalho Chehab 32789a0bf528SMauro Carvalho Chehab /* Check for illegal cmd */ 3279cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code); 3280cd7a67a4SMauro Carvalho Chehab if (err_code == 0xFFFF) { 32819a0bf528SMauro Carvalho Chehab /* illegal command */ 32829a0bf528SMauro Carvalho Chehab status = -EINVAL; 32839a0bf528SMauro Carvalho Chehab } 32849a0bf528SMauro Carvalho Chehab if (status < 0) 32859a0bf528SMauro Carvalho Chehab goto error; 32869a0bf528SMauro Carvalho Chehab 328739c1cb2bSJonathan McCrohan /* Retrieve results parameters from SC */ 32889a0bf528SMauro Carvalho Chehab switch (cmd) { 32899a0bf528SMauro Carvalho Chehab /* All commands yielding 5 results */ 32909a0bf528SMauro Carvalho Chehab /* All commands yielding 4 results */ 32919a0bf528SMauro Carvalho Chehab /* All commands yielding 3 results */ 32929a0bf528SMauro Carvalho Chehab /* All commands yielding 2 results */ 32939a0bf528SMauro Carvalho Chehab /* All commands yielding 1 result */ 32949a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO: 32959a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 32969a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0)); 3297af7ab662SGustavo A. R. Silva break; 32989a0bf528SMauro Carvalho Chehab /* All commands yielding 0 results */ 32999a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 33009a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_TIMER: 33019a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START: 33029a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 33039a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 33049a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL: 33059a0bf528SMauro Carvalho Chehab break; 33069a0bf528SMauro Carvalho Chehab default: 33079a0bf528SMauro Carvalho Chehab /* Unknown command */ 33089a0bf528SMauro Carvalho Chehab status = -EINVAL; 33099a0bf528SMauro Carvalho Chehab break; 33109a0bf528SMauro Carvalho Chehab } /* switch (cmd->cmd) */ 33119a0bf528SMauro Carvalho Chehab error: 33129a0bf528SMauro Carvalho Chehab if (status < 0) 33133a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33149a0bf528SMauro Carvalho Chehab return status; 33159a0bf528SMauro Carvalho Chehab } 33169a0bf528SMauro Carvalho Chehab 3317cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state) 33189a0bf528SMauro Carvalho Chehab { 3319cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRX_POWER_UP; 33209a0bf528SMauro Carvalho Chehab int status; 33219a0bf528SMauro Carvalho Chehab 33229a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3323cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 33249a0bf528SMauro Carvalho Chehab if (status < 0) 33253a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33269a0bf528SMauro Carvalho Chehab return status; 33279a0bf528SMauro Carvalho Chehab } 33289a0bf528SMauro Carvalho Chehab 3329cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled) 33309a0bf528SMauro Carvalho Chehab { 33319a0bf528SMauro Carvalho Chehab int status; 33329a0bf528SMauro Carvalho Chehab 33339a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33345a7f7b79SMauro Carvalho Chehab if (*enabled) 33359a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 0); 33369a0bf528SMauro Carvalho Chehab else 33379a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1); 33389a0bf528SMauro Carvalho Chehab if (status < 0) 33393a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33409a0bf528SMauro Carvalho Chehab return status; 33419a0bf528SMauro Carvalho Chehab } 33429a0bf528SMauro Carvalho Chehab 33439a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K 4000 3344cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) 33459a0bf528SMauro Carvalho Chehab { 33469a0bf528SMauro Carvalho Chehab 33479a0bf528SMauro Carvalho Chehab int status; 33489a0bf528SMauro Carvalho Chehab 33499a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33505a7f7b79SMauro Carvalho Chehab if (*enabled) { 33519a0bf528SMauro Carvalho Chehab /* write mask to 1 */ 33529a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 33539a0bf528SMauro Carvalho Chehab DEFAULT_FR_THRES_8K); 33549a0bf528SMauro Carvalho Chehab } else { 33559a0bf528SMauro Carvalho Chehab /* write mask to 0 */ 33569a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0); 33579a0bf528SMauro Carvalho Chehab } 33589a0bf528SMauro Carvalho Chehab if (status < 0) 33593a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33609a0bf528SMauro Carvalho Chehab 33619a0bf528SMauro Carvalho Chehab return status; 33629a0bf528SMauro Carvalho Chehab } 33639a0bf528SMauro Carvalho Chehab 3364cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, 3365cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t *echo_thres) 33669a0bf528SMauro Carvalho Chehab { 33679a0bf528SMauro Carvalho Chehab u16 data = 0; 33689a0bf528SMauro Carvalho Chehab int status; 33699a0bf528SMauro Carvalho Chehab 33709a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 33719a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data); 33729a0bf528SMauro Carvalho Chehab if (status < 0) 33739a0bf528SMauro Carvalho Chehab goto error; 33749a0bf528SMauro Carvalho Chehab 3375cd7a67a4SMauro Carvalho Chehab switch (echo_thres->fft_mode) { 33769a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_2K: 33779a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M; 3378cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold << 33799a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_2K__B) 33809a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M)); 33819a0bf528SMauro Carvalho Chehab break; 33829a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_8K: 33839a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M; 3384cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold << 33859a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_8K__B) 33869a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M)); 33879a0bf528SMauro Carvalho Chehab break; 33889a0bf528SMauro Carvalho Chehab default: 33899a0bf528SMauro Carvalho Chehab return -EINVAL; 33909a0bf528SMauro Carvalho Chehab } 33919a0bf528SMauro Carvalho Chehab 33929a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data); 33939a0bf528SMauro Carvalho Chehab error: 33949a0bf528SMauro Carvalho Chehab if (status < 0) 33953a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 33969a0bf528SMauro Carvalho Chehab return status; 33979a0bf528SMauro Carvalho Chehab } 33989a0bf528SMauro Carvalho Chehab 3399cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, 3400cd7a67a4SMauro Carvalho Chehab enum drxk_cfg_dvbt_sqi_speed *speed) 34019a0bf528SMauro Carvalho Chehab { 34029a0bf528SMauro Carvalho Chehab int status = -EINVAL; 34039a0bf528SMauro Carvalho Chehab 34049a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 34059a0bf528SMauro Carvalho Chehab 34069a0bf528SMauro Carvalho Chehab switch (*speed) { 34079a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_FAST: 34089a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_MEDIUM: 34099a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_SLOW: 34109a0bf528SMauro Carvalho Chehab break; 34119a0bf528SMauro Carvalho Chehab default: 34129a0bf528SMauro Carvalho Chehab goto error; 34139a0bf528SMauro Carvalho Chehab } 34149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A, 34159a0bf528SMauro Carvalho Chehab (u16) *speed); 34169a0bf528SMauro Carvalho Chehab error: 34179a0bf528SMauro Carvalho Chehab if (status < 0) 34183a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 34199a0bf528SMauro Carvalho Chehab return status; 34209a0bf528SMauro Carvalho Chehab } 34219a0bf528SMauro Carvalho Chehab 34229a0bf528SMauro Carvalho Chehab /*============================================================================*/ 34239a0bf528SMauro Carvalho Chehab 342434eb9751SMauro Carvalho Chehab /* 34259a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets 34269a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 34279a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 34289a0bf528SMauro Carvalho Chehab * 34299a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard 34309a0bf528SMauro Carvalho Chehab * 34319a0bf528SMauro Carvalho Chehab */ 3432cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state) 34339a0bf528SMauro Carvalho Chehab { 34349a0bf528SMauro Carvalho Chehab int status; 34359a0bf528SMauro Carvalho Chehab bool setincenable = false; 34369a0bf528SMauro Carvalho Chehab bool setfrenable = true; 34379a0bf528SMauro Carvalho Chehab 3438cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K }; 3439cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K }; 34409a0bf528SMauro Carvalho Chehab 34419a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3442cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_inc_enable(state, &setincenable); 34439a0bf528SMauro Carvalho Chehab if (status < 0) 34449a0bf528SMauro Carvalho Chehab goto error; 3445cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_fr_enable(state, &setfrenable); 34469a0bf528SMauro Carvalho Chehab if (status < 0) 34479a0bf528SMauro Carvalho Chehab goto error; 3448cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k); 34499a0bf528SMauro Carvalho Chehab if (status < 0) 34509a0bf528SMauro Carvalho Chehab goto error; 3451cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k); 34529a0bf528SMauro Carvalho Chehab if (status < 0) 34539a0bf528SMauro Carvalho Chehab goto error; 3454ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, 3455ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max); 34569a0bf528SMauro Carvalho Chehab error: 34579a0bf528SMauro Carvalho Chehab if (status < 0) 34583a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 34599a0bf528SMauro Carvalho Chehab return status; 34609a0bf528SMauro Carvalho Chehab } 34619a0bf528SMauro Carvalho Chehab 34629a0bf528SMauro Carvalho Chehab /*============================================================================*/ 34639a0bf528SMauro Carvalho Chehab 346434eb9751SMauro Carvalho Chehab /* 34659a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT. 34669a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 34679a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 34689a0bf528SMauro Carvalho Chehab * 34699a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode 34709a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used. 34719a0bf528SMauro Carvalho Chehab */ 3472cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state, 3473cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 34749a0bf528SMauro Carvalho Chehab { 3475cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 34769a0bf528SMauro Carvalho Chehab u16 data = 0; 34779a0bf528SMauro Carvalho Chehab int status; 34789a0bf528SMauro Carvalho Chehab 34799a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 34809a0bf528SMauro Carvalho Chehab 3481cd7a67a4SMauro Carvalho Chehab power_up_dvbt(state); 34829a0bf528SMauro Carvalho Chehab /* added antenna switch */ 3483cd7a67a4SMauro Carvalho Chehab switch_antenna_to_dvbt(state); 34849a0bf528SMauro Carvalho Chehab /* send OFDM reset command */ 3485ab5060cdSMauro Carvalho Chehab status = scu_command(state, 3486ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM 3487ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 3488ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 34899a0bf528SMauro Carvalho Chehab if (status < 0) 34909a0bf528SMauro Carvalho Chehab goto error; 34919a0bf528SMauro Carvalho Chehab 34929a0bf528SMauro Carvalho Chehab /* send OFDM setenv command */ 3493ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 3494ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 3495ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 34969a0bf528SMauro Carvalho Chehab if (status < 0) 34979a0bf528SMauro Carvalho Chehab goto error; 34989a0bf528SMauro Carvalho Chehab 34999a0bf528SMauro Carvalho Chehab /* reset datapath for OFDM, processors first */ 35009a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 35019a0bf528SMauro Carvalho Chehab if (status < 0) 35029a0bf528SMauro Carvalho Chehab goto error; 35039a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 35049a0bf528SMauro Carvalho Chehab if (status < 0) 35059a0bf528SMauro Carvalho Chehab goto error; 35069a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 35079a0bf528SMauro Carvalho Chehab if (status < 0) 35089a0bf528SMauro Carvalho Chehab goto error; 35099a0bf528SMauro Carvalho Chehab 35109a0bf528SMauro Carvalho Chehab /* IQM setup */ 35119a0bf528SMauro Carvalho Chehab /* synchronize on ofdstate->m_festart */ 35129a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 1); 35139a0bf528SMauro Carvalho Chehab if (status < 0) 35149a0bf528SMauro Carvalho Chehab goto error; 35159a0bf528SMauro Carvalho Chehab /* window size for clipping ADC detection */ 35169a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0); 35179a0bf528SMauro Carvalho Chehab if (status < 0) 35189a0bf528SMauro Carvalho Chehab goto error; 351973854b86SJason Wang /* window size for sense pre-SAW detection */ 35209a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0); 35219a0bf528SMauro Carvalho Chehab if (status < 0) 35229a0bf528SMauro Carvalho Chehab goto error; 35239a0bf528SMauro Carvalho Chehab /* sense threshold for sense pre-SAW detection */ 35249a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 35259a0bf528SMauro Carvalho Chehab if (status < 0) 35269a0bf528SMauro Carvalho Chehab goto error; 3527cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true); 35289a0bf528SMauro Carvalho Chehab if (status < 0) 35299a0bf528SMauro Carvalho Chehab goto error; 35309a0bf528SMauro Carvalho Chehab 35319a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AGC_RF__A, 0); 35329a0bf528SMauro Carvalho Chehab if (status < 0) 35339a0bf528SMauro Carvalho Chehab goto error; 35349a0bf528SMauro Carvalho Chehab 35359a0bf528SMauro Carvalho Chehab /* Impulse noise cruncher setup */ 35369a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */ 35379a0bf528SMauro Carvalho Chehab if (status < 0) 35389a0bf528SMauro Carvalho Chehab goto error; 35399a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */ 35409a0bf528SMauro Carvalho Chehab if (status < 0) 35419a0bf528SMauro Carvalho Chehab goto error; 35429a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */ 35439a0bf528SMauro Carvalho Chehab if (status < 0) 35449a0bf528SMauro Carvalho Chehab goto error; 35459a0bf528SMauro Carvalho Chehab 35469a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 16); 35479a0bf528SMauro Carvalho Chehab if (status < 0) 35489a0bf528SMauro Carvalho Chehab goto error; 35499a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ 35509a0bf528SMauro Carvalho Chehab if (status < 0) 35519a0bf528SMauro Carvalho Chehab goto error; 35529a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */ 35539a0bf528SMauro Carvalho Chehab if (status < 0) 35549a0bf528SMauro Carvalho Chehab goto error; 35559a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE__A, 1600); 35569a0bf528SMauro Carvalho Chehab if (status < 0) 35579a0bf528SMauro Carvalho Chehab goto error; 35589a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, 0); 35599a0bf528SMauro Carvalho Chehab if (status < 0) 35609a0bf528SMauro Carvalho Chehab goto error; 35619a0bf528SMauro Carvalho Chehab 35629a0bf528SMauro Carvalho Chehab /* virtual clipping threshold for clipping ADC detection */ 35639a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448); 35649a0bf528SMauro Carvalho Chehab if (status < 0) 35659a0bf528SMauro Carvalho Chehab goto error; 35669a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */ 35679a0bf528SMauro Carvalho Chehab if (status < 0) 35689a0bf528SMauro Carvalho Chehab goto error; 35699a0bf528SMauro Carvalho Chehab 3570ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, 3571ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); 35729a0bf528SMauro Carvalho Chehab if (status < 0) 35739a0bf528SMauro Carvalho Chehab goto error; 35749a0bf528SMauro Carvalho Chehab 35759a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */ 35769a0bf528SMauro Carvalho Chehab if (status < 0) 35779a0bf528SMauro Carvalho Chehab goto error; 35789a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2); 35799a0bf528SMauro Carvalho Chehab if (status < 0) 35809a0bf528SMauro Carvalho Chehab goto error; 35819a0bf528SMauro Carvalho Chehab /* enable power measurement interrupt */ 35829a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_COMM_INT_MSK__A, 1); 35839a0bf528SMauro Carvalho Chehab if (status < 0) 35849a0bf528SMauro Carvalho Chehab goto error; 35859a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 35869a0bf528SMauro Carvalho Chehab if (status < 0) 35879a0bf528SMauro Carvalho Chehab goto error; 35889a0bf528SMauro Carvalho Chehab 35899a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */ 3590cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state); 35919a0bf528SMauro Carvalho Chehab if (status < 0) 35929a0bf528SMauro Carvalho Chehab goto error; 3593cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg); 35949a0bf528SMauro Carvalho Chehab if (status < 0) 35959a0bf528SMauro Carvalho Chehab goto error; 35969a0bf528SMauro Carvalho Chehab 35979a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 35989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 35999a0bf528SMauro Carvalho Chehab if (status < 0) 36009a0bf528SMauro Carvalho Chehab goto error; 36019a0bf528SMauro Carvalho Chehab 3602cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true); 36039a0bf528SMauro Carvalho Chehab if (status < 0) 36049a0bf528SMauro Carvalho Chehab goto error; 3605cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true); 36069a0bf528SMauro Carvalho Chehab if (status < 0) 36079a0bf528SMauro Carvalho Chehab goto error; 36089a0bf528SMauro Carvalho Chehab 36099a0bf528SMauro Carvalho Chehab /* Set Noise Estimation notch width and enable DC fix */ 36109a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data); 36119a0bf528SMauro Carvalho Chehab if (status < 0) 36129a0bf528SMauro Carvalho Chehab goto error; 36139a0bf528SMauro Carvalho Chehab data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M; 36149a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data); 36159a0bf528SMauro Carvalho Chehab if (status < 0) 36169a0bf528SMauro Carvalho Chehab goto error; 36179a0bf528SMauro Carvalho Chehab 36189a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 36199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 36209a0bf528SMauro Carvalho Chehab if (status < 0) 36219a0bf528SMauro Carvalho Chehab goto error; 36229a0bf528SMauro Carvalho Chehab 3623cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code) { 3624cd7a67a4SMauro Carvalho Chehab /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */ 3625ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 3626ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay); 36279a0bf528SMauro Carvalho Chehab if (status < 0) 36289a0bf528SMauro Carvalho Chehab goto error; 36299a0bf528SMauro Carvalho Chehab } 36309a0bf528SMauro Carvalho Chehab 36319a0bf528SMauro Carvalho Chehab /* OFDM_SC setup */ 36329a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT 36339a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1); 36349a0bf528SMauro Carvalho Chehab if (status < 0) 36359a0bf528SMauro Carvalho Chehab goto error; 36369a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2); 36379a0bf528SMauro Carvalho Chehab if (status < 0) 36389a0bf528SMauro Carvalho Chehab goto error; 36399a0bf528SMauro Carvalho Chehab #endif 36409a0bf528SMauro Carvalho Chehab 36419a0bf528SMauro Carvalho Chehab /* FEC setup */ 36429a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */ 36439a0bf528SMauro Carvalho Chehab if (status < 0) 36449a0bf528SMauro Carvalho Chehab goto error; 36459a0bf528SMauro Carvalho Chehab 36469a0bf528SMauro Carvalho Chehab 36479a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT 36489a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400); 36499a0bf528SMauro Carvalho Chehab if (status < 0) 36509a0bf528SMauro Carvalho Chehab goto error; 36519a0bf528SMauro Carvalho Chehab #else 36529a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000); 36539a0bf528SMauro Carvalho Chehab if (status < 0) 36549a0bf528SMauro Carvalho Chehab goto error; 36559a0bf528SMauro Carvalho Chehab #endif 36569a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001); 36579a0bf528SMauro Carvalho Chehab if (status < 0) 36589a0bf528SMauro Carvalho Chehab goto error; 36599a0bf528SMauro Carvalho Chehab 36609a0bf528SMauro Carvalho Chehab /* Setup MPEG bus */ 3661cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, OM_DVBT); 36629a0bf528SMauro Carvalho Chehab if (status < 0) 36639a0bf528SMauro Carvalho Chehab goto error; 36649a0bf528SMauro Carvalho Chehab /* Set DVBT Presets */ 3665cd7a67a4SMauro Carvalho Chehab status = dvbt_activate_presets(state); 36669a0bf528SMauro Carvalho Chehab if (status < 0) 36679a0bf528SMauro Carvalho Chehab goto error; 36689a0bf528SMauro Carvalho Chehab 36699a0bf528SMauro Carvalho Chehab error: 36709a0bf528SMauro Carvalho Chehab if (status < 0) 36713a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 36729a0bf528SMauro Carvalho Chehab return status; 36739a0bf528SMauro Carvalho Chehab } 36749a0bf528SMauro Carvalho Chehab 36759a0bf528SMauro Carvalho Chehab /*============================================================================*/ 367634eb9751SMauro Carvalho Chehab /* 3677cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel. 36789a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 36799a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 36809a0bf528SMauro Carvalho Chehab */ 3681cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state) 36829a0bf528SMauro Carvalho Chehab { 36839a0bf528SMauro Carvalho Chehab u16 param1; 36849a0bf528SMauro Carvalho Chehab int status; 3685cd7a67a4SMauro Carvalho Chehab /* drxk_ofdm_sc_cmd_t scCmd; */ 36869a0bf528SMauro Carvalho Chehab 36879a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 3688cd7a67a4SMauro Carvalho Chehab /* start correct processes to get in lock */ 36899a0bf528SMauro Carvalho Chehab /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */ 36909a0bf528SMauro Carvalho Chehab param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN; 3691ab5060cdSMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, 3692ab5060cdSMauro Carvalho Chehab OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 3693ab5060cdSMauro Carvalho Chehab 0, 0, 0); 36949a0bf528SMauro Carvalho Chehab if (status < 0) 36959a0bf528SMauro Carvalho Chehab goto error; 3696cd7a67a4SMauro Carvalho Chehab /* start FEC OC */ 3697cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state); 36989a0bf528SMauro Carvalho Chehab if (status < 0) 36999a0bf528SMauro Carvalho Chehab goto error; 37009a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 37019a0bf528SMauro Carvalho Chehab if (status < 0) 37029a0bf528SMauro Carvalho Chehab goto error; 37039a0bf528SMauro Carvalho Chehab error: 37049a0bf528SMauro Carvalho Chehab if (status < 0) 37053a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 37069a0bf528SMauro Carvalho Chehab return status; 37079a0bf528SMauro Carvalho Chehab } 37089a0bf528SMauro Carvalho Chehab 37099a0bf528SMauro Carvalho Chehab 37109a0bf528SMauro Carvalho Chehab /*============================================================================*/ 37119a0bf528SMauro Carvalho Chehab 371234eb9751SMauro Carvalho Chehab /* 37139a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel. 37149a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator. 37159a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 37169a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel() 37179a0bf528SMauro Carvalho Chehab */ 3718cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 3719cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset) 37209a0bf528SMauro Carvalho Chehab { 3721cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0; 3722cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0; 3723cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate_ofs = 0; 37249a0bf528SMauro Carvalho Chehab u32 bandwidth = 0; 37259a0bf528SMauro Carvalho Chehab u16 param1; 37269a0bf528SMauro Carvalho Chehab int status; 37279a0bf528SMauro Carvalho Chehab 3728ab5060cdSMauro Carvalho Chehab dprintk(1, "IF =%d, TFO = %d\n", 3729ab5060cdSMauro Carvalho Chehab intermediate_freqk_hz, tuner_freq_offset); 37309a0bf528SMauro Carvalho Chehab 3731ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 3732ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 3733ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 37349a0bf528SMauro Carvalho Chehab if (status < 0) 37359a0bf528SMauro Carvalho Chehab goto error; 37369a0bf528SMauro Carvalho Chehab 37379a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 37389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 37399a0bf528SMauro Carvalho Chehab if (status < 0) 37409a0bf528SMauro Carvalho Chehab goto error; 37419a0bf528SMauro Carvalho Chehab 37429a0bf528SMauro Carvalho Chehab /* Stop processors */ 37439a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 37449a0bf528SMauro Carvalho Chehab if (status < 0) 37459a0bf528SMauro Carvalho Chehab goto error; 37469a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 37479a0bf528SMauro Carvalho Chehab if (status < 0) 37489a0bf528SMauro Carvalho Chehab goto error; 37499a0bf528SMauro Carvalho Chehab 37509a0bf528SMauro Carvalho Chehab /* Mandatory fix, always stop CP, required to set spl offset back to 37519a0bf528SMauro Carvalho Chehab hardware default (is set to 0 by ucode during pilot detection */ 37529a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP); 37539a0bf528SMauro Carvalho Chehab if (status < 0) 37549a0bf528SMauro Carvalho Chehab goto error; 37559a0bf528SMauro Carvalho Chehab 3756ab5060cdSMauro Carvalho Chehab /*== Write channel settings to device ================================*/ 37579a0bf528SMauro Carvalho Chehab 37589a0bf528SMauro Carvalho Chehab /* mode */ 37599a0bf528SMauro Carvalho Chehab switch (state->props.transmission_mode) { 37609a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_AUTO: 37619a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_8K: 37621cef3942SMauro Carvalho Chehab default: 3763cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; 37649a0bf528SMauro Carvalho Chehab break; 37659a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_2K: 3766cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; 37679a0bf528SMauro Carvalho Chehab break; 37689a0bf528SMauro Carvalho Chehab } 37699a0bf528SMauro Carvalho Chehab 37709a0bf528SMauro Carvalho Chehab /* guard */ 37719a0bf528SMauro Carvalho Chehab switch (state->props.guard_interval) { 37729a0bf528SMauro Carvalho Chehab default: 37731cef3942SMauro Carvalho Chehab case GUARD_INTERVAL_AUTO: /* try first guess DRX_GUARD_1DIV4 */ 37749a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_4: 3775cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; 37769a0bf528SMauro Carvalho Chehab break; 37779a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_32: 3778cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; 37799a0bf528SMauro Carvalho Chehab break; 37809a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_16: 3781cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; 37829a0bf528SMauro Carvalho Chehab break; 37839a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_8: 3784cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; 37859a0bf528SMauro Carvalho Chehab break; 37869a0bf528SMauro Carvalho Chehab } 37879a0bf528SMauro Carvalho Chehab 37889a0bf528SMauro Carvalho Chehab /* hierarchy */ 37899a0bf528SMauro Carvalho Chehab switch (state->props.hierarchy) { 37909a0bf528SMauro Carvalho Chehab case HIERARCHY_AUTO: 37919a0bf528SMauro Carvalho Chehab case HIERARCHY_NONE: 37921cef3942SMauro Carvalho Chehab default: /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */ 37939a0bf528SMauro Carvalho Chehab case HIERARCHY_1: 3794cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; 37959a0bf528SMauro Carvalho Chehab break; 37969a0bf528SMauro Carvalho Chehab case HIERARCHY_2: 3797cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; 37989a0bf528SMauro Carvalho Chehab break; 37999a0bf528SMauro Carvalho Chehab case HIERARCHY_4: 3800cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; 38019a0bf528SMauro Carvalho Chehab break; 38029a0bf528SMauro Carvalho Chehab } 38039a0bf528SMauro Carvalho Chehab 38049a0bf528SMauro Carvalho Chehab 38059a0bf528SMauro Carvalho Chehab /* modulation */ 38069a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 38079a0bf528SMauro Carvalho Chehab case QAM_AUTO: 38081cef3942SMauro Carvalho Chehab default: /* try first guess DRX_CONSTELLATION_QAM64 */ 38099a0bf528SMauro Carvalho Chehab case QAM_64: 3810cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; 38119a0bf528SMauro Carvalho Chehab break; 38129a0bf528SMauro Carvalho Chehab case QPSK: 3813cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; 38149a0bf528SMauro Carvalho Chehab break; 38159a0bf528SMauro Carvalho Chehab case QAM_16: 3816cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; 38179a0bf528SMauro Carvalho Chehab break; 38189a0bf528SMauro Carvalho Chehab } 38199a0bf528SMauro Carvalho Chehab #if 0 382039c1cb2bSJonathan McCrohan /* No hierarchical channels support in BDA */ 38219a0bf528SMauro Carvalho Chehab /* Priority (only for hierarchical channels) */ 38229a0bf528SMauro Carvalho Chehab switch (channel->priority) { 38239a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_LOW: 3824cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; 3825cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38269a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_LO); 38279a0bf528SMauro Carvalho Chehab break; 38289a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_HIGH: 3829cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 3830cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38319a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_HI)); 38329a0bf528SMauro Carvalho Chehab break; 3833df561f66SGustavo A. R. Silva case DRX_PRIORITY_UNKNOWN: 38349a0bf528SMauro Carvalho Chehab default: 38359a0bf528SMauro Carvalho Chehab status = -EINVAL; 38369a0bf528SMauro Carvalho Chehab goto error; 38379a0bf528SMauro Carvalho Chehab } 38389a0bf528SMauro Carvalho Chehab #else 3839868c9a17SMauro Carvalho Chehab /* Set Priority high */ 3840cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 38419a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI); 38429a0bf528SMauro Carvalho Chehab if (status < 0) 38439a0bf528SMauro Carvalho Chehab goto error; 38449a0bf528SMauro Carvalho Chehab #endif 38459a0bf528SMauro Carvalho Chehab 38469a0bf528SMauro Carvalho Chehab /* coderate */ 38479a0bf528SMauro Carvalho Chehab switch (state->props.code_rate_HP) { 38489a0bf528SMauro Carvalho Chehab case FEC_AUTO: 38491cef3942SMauro Carvalho Chehab default: /* try first guess DRX_CODERATE_2DIV3 */ 38509a0bf528SMauro Carvalho Chehab case FEC_2_3: 3851cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; 38529a0bf528SMauro Carvalho Chehab break; 38539a0bf528SMauro Carvalho Chehab case FEC_1_2: 3854cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; 38559a0bf528SMauro Carvalho Chehab break; 38569a0bf528SMauro Carvalho Chehab case FEC_3_4: 3857cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; 38589a0bf528SMauro Carvalho Chehab break; 38599a0bf528SMauro Carvalho Chehab case FEC_5_6: 3860cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; 38619a0bf528SMauro Carvalho Chehab break; 38629a0bf528SMauro Carvalho Chehab case FEC_7_8: 3863cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; 38649a0bf528SMauro Carvalho Chehab break; 38659a0bf528SMauro Carvalho Chehab } 38669a0bf528SMauro Carvalho Chehab 3867ab5060cdSMauro Carvalho Chehab /* 3868868c9a17SMauro Carvalho Chehab * SAW filter selection: normally not necessary, but if wanted 3869ab5060cdSMauro Carvalho Chehab * the application can select a SAW filter via the driver by 3870ab5060cdSMauro Carvalho Chehab * using UIOs 3871ab5060cdSMauro Carvalho Chehab */ 3872ab5060cdSMauro Carvalho Chehab 38739a0bf528SMauro Carvalho Chehab /* First determine real bandwidth (Hz) */ 38749a0bf528SMauro Carvalho Chehab /* Also set delay for impulse noise cruncher */ 3875ab5060cdSMauro Carvalho Chehab /* 3876ab5060cdSMauro Carvalho Chehab * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is 3877ab5060cdSMauro Carvalho Chehab * changed by SC for fix for some 8K,1/8 guard but is restored by 3878ab5060cdSMauro Carvalho Chehab * InitEC and ResetEC functions 3879ab5060cdSMauro Carvalho Chehab */ 38809a0bf528SMauro Carvalho Chehab switch (state->props.bandwidth_hz) { 38819a0bf528SMauro Carvalho Chehab case 0: 38829a0bf528SMauro Carvalho Chehab state->props.bandwidth_hz = 8000000; 3883df561f66SGustavo A. R. Silva fallthrough; 38849a0bf528SMauro Carvalho Chehab case 8000000: 38859a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; 3886ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3887ab5060cdSMauro Carvalho Chehab 3052); 38889a0bf528SMauro Carvalho Chehab if (status < 0) 38899a0bf528SMauro Carvalho Chehab goto error; 38909a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 8 MHz */ 3891ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3892ab5060cdSMauro Carvalho Chehab 7); 38939a0bf528SMauro Carvalho Chehab if (status < 0) 38949a0bf528SMauro Carvalho Chehab goto error; 3895ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3896ab5060cdSMauro Carvalho Chehab 7); 38979a0bf528SMauro Carvalho Chehab if (status < 0) 38989a0bf528SMauro Carvalho Chehab goto error; 3899ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3900ab5060cdSMauro Carvalho Chehab 7); 39019a0bf528SMauro Carvalho Chehab if (status < 0) 39029a0bf528SMauro Carvalho Chehab goto error; 3903ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3904ab5060cdSMauro Carvalho Chehab 1); 39059a0bf528SMauro Carvalho Chehab if (status < 0) 39069a0bf528SMauro Carvalho Chehab goto error; 39079a0bf528SMauro Carvalho Chehab break; 39089a0bf528SMauro Carvalho Chehab case 7000000: 39099a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; 3910ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3911ab5060cdSMauro Carvalho Chehab 3491); 39129a0bf528SMauro Carvalho Chehab if (status < 0) 39139a0bf528SMauro Carvalho Chehab goto error; 39149a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 7 MHz */ 3915ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3916ab5060cdSMauro Carvalho Chehab 8); 39179a0bf528SMauro Carvalho Chehab if (status < 0) 39189a0bf528SMauro Carvalho Chehab goto error; 3919ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3920ab5060cdSMauro Carvalho Chehab 8); 39219a0bf528SMauro Carvalho Chehab if (status < 0) 39229a0bf528SMauro Carvalho Chehab goto error; 3923ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3924ab5060cdSMauro Carvalho Chehab 4); 39259a0bf528SMauro Carvalho Chehab if (status < 0) 39269a0bf528SMauro Carvalho Chehab goto error; 3927ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3928ab5060cdSMauro Carvalho Chehab 1); 39299a0bf528SMauro Carvalho Chehab if (status < 0) 39309a0bf528SMauro Carvalho Chehab goto error; 39319a0bf528SMauro Carvalho Chehab break; 39329a0bf528SMauro Carvalho Chehab case 6000000: 39339a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; 3934ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3935ab5060cdSMauro Carvalho Chehab 4073); 39369a0bf528SMauro Carvalho Chehab if (status < 0) 39379a0bf528SMauro Carvalho Chehab goto error; 39389a0bf528SMauro Carvalho Chehab /* cochannel protection for NTSC 6 MHz */ 3939ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 3940ab5060cdSMauro Carvalho Chehab 19); 39419a0bf528SMauro Carvalho Chehab if (status < 0) 39429a0bf528SMauro Carvalho Chehab goto error; 3943ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 3944ab5060cdSMauro Carvalho Chehab 19); 39459a0bf528SMauro Carvalho Chehab if (status < 0) 39469a0bf528SMauro Carvalho Chehab goto error; 3947ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 3948ab5060cdSMauro Carvalho Chehab 14); 39499a0bf528SMauro Carvalho Chehab if (status < 0) 39509a0bf528SMauro Carvalho Chehab goto error; 3951ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 3952ab5060cdSMauro Carvalho Chehab 1); 39539a0bf528SMauro Carvalho Chehab if (status < 0) 39549a0bf528SMauro Carvalho Chehab goto error; 39559a0bf528SMauro Carvalho Chehab break; 39569a0bf528SMauro Carvalho Chehab default: 39579a0bf528SMauro Carvalho Chehab status = -EINVAL; 39589a0bf528SMauro Carvalho Chehab goto error; 39599a0bf528SMauro Carvalho Chehab } 39609a0bf528SMauro Carvalho Chehab 3961cd7a67a4SMauro Carvalho Chehab if (iqm_rc_rate_ofs == 0) { 39629a0bf528SMauro Carvalho Chehab /* Now compute IQM_RC_RATE_OFS 39639a0bf528SMauro Carvalho Chehab (((SysFreq/BandWidth)/2)/2) -1) * 2^23) 39649a0bf528SMauro Carvalho Chehab => 39659a0bf528SMauro Carvalho Chehab ((SysFreq / BandWidth) * (2^21)) - (2^23) 39669a0bf528SMauro Carvalho Chehab */ 39679a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^28) */ 3968ab5060cdSMauro Carvalho Chehab /* 3969ab5060cdSMauro Carvalho Chehab * assert (MAX(sysClk)/MIN(bandwidth) < 16) 3970ab5060cdSMauro Carvalho Chehab * => assert(MAX(sysClk) < 16*MIN(bandwidth)) 3971ab5060cdSMauro Carvalho Chehab * => assert(109714272 > 48000000) = true 3972ab5060cdSMauro Carvalho Chehab * so Frac 28 can be used 3973ab5060cdSMauro Carvalho Chehab */ 3974cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = Frac28a((u32) 3975cd7a67a4SMauro Carvalho Chehab ((state->m_sys_clock_freq * 39769a0bf528SMauro Carvalho Chehab 1000) / 3), bandwidth); 39779a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ 3978cd7a67a4SMauro Carvalho Chehab if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40) 3979cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs += 0x80L; 3980cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7; 39819a0bf528SMauro Carvalho Chehab /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */ 3982cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23); 39839a0bf528SMauro Carvalho Chehab } 39849a0bf528SMauro Carvalho Chehab 3985cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs &= 39869a0bf528SMauro Carvalho Chehab ((((u32) IQM_RC_RATE_OFS_HI__M) << 39879a0bf528SMauro Carvalho Chehab IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M); 3988cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs); 39899a0bf528SMauro Carvalho Chehab if (status < 0) 39909a0bf528SMauro Carvalho Chehab goto error; 39919a0bf528SMauro Carvalho Chehab 39929a0bf528SMauro Carvalho Chehab /* Bandwidth setting done */ 39939a0bf528SMauro Carvalho Chehab 39949a0bf528SMauro Carvalho Chehab #if 0 3995cd7a67a4SMauro Carvalho Chehab status = dvbt_set_frequency_shift(demod, channel, tuner_offset); 39969a0bf528SMauro Carvalho Chehab if (status < 0) 39979a0bf528SMauro Carvalho Chehab goto error; 39989a0bf528SMauro Carvalho Chehab #endif 3999ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz, 4000ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true); 40019a0bf528SMauro Carvalho Chehab if (status < 0) 40029a0bf528SMauro Carvalho Chehab goto error; 40039a0bf528SMauro Carvalho Chehab 4004ab5060cdSMauro Carvalho Chehab /*== start SC, write channel settings to SC ==========================*/ 40059a0bf528SMauro Carvalho Chehab 40069a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 40079a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 40089a0bf528SMauro Carvalho Chehab if (status < 0) 40099a0bf528SMauro Carvalho Chehab goto error; 40109a0bf528SMauro Carvalho Chehab 40119a0bf528SMauro Carvalho Chehab /* Enable SC after setting all other parameters */ 40129a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_STATE__A, 0); 40139a0bf528SMauro Carvalho Chehab if (status < 0) 40149a0bf528SMauro Carvalho Chehab goto error; 40159a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, 1); 40169a0bf528SMauro Carvalho Chehab if (status < 0) 40179a0bf528SMauro Carvalho Chehab goto error; 40189a0bf528SMauro Carvalho Chehab 40199a0bf528SMauro Carvalho Chehab 4020ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 4021ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START, 4022ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 40239a0bf528SMauro Carvalho Chehab if (status < 0) 40249a0bf528SMauro Carvalho Chehab goto error; 40259a0bf528SMauro Carvalho Chehab 40269a0bf528SMauro Carvalho Chehab /* Write SC parameter registers, set all AUTO flags in operation mode */ 40279a0bf528SMauro Carvalho Chehab param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M | 40289a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_GUARD__M | 40299a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_CONST__M | 40309a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_HIER__M | 40319a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_RATE__M); 4032cd7a67a4SMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, 4033cd7a67a4SMauro Carvalho Chehab 0, transmission_params, param1, 0, 0, 0); 40349a0bf528SMauro Carvalho Chehab if (status < 0) 40359a0bf528SMauro Carvalho Chehab goto error; 40369a0bf528SMauro Carvalho Chehab 4037cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code) 4038cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed); 40399a0bf528SMauro Carvalho Chehab error: 40409a0bf528SMauro Carvalho Chehab if (status < 0) 40413a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 40429a0bf528SMauro Carvalho Chehab 40439a0bf528SMauro Carvalho Chehab return status; 40449a0bf528SMauro Carvalho Chehab } 40459a0bf528SMauro Carvalho Chehab 40469a0bf528SMauro Carvalho Chehab 40479a0bf528SMauro Carvalho Chehab /*============================================================================*/ 40489a0bf528SMauro Carvalho Chehab 404934eb9751SMauro Carvalho Chehab /* 405039c1cb2bSJonathan McCrohan * \brief Retrieve lock status . 40519a0bf528SMauro Carvalho Chehab * \param demod Pointer to demodulator instance. 40529a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure. 40539a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 40549a0bf528SMauro Carvalho Chehab * 40559a0bf528SMauro Carvalho Chehab */ 4056cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) 40579a0bf528SMauro Carvalho Chehab { 40589a0bf528SMauro Carvalho Chehab int status; 40599a0bf528SMauro Carvalho Chehab const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M | 40609a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_LOCK_FEC__M); 40619a0bf528SMauro Carvalho Chehab const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M); 40629a0bf528SMauro Carvalho Chehab const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M; 40639a0bf528SMauro Carvalho Chehab 4064cd7a67a4SMauro Carvalho Chehab u16 sc_ra_ram_lock = 0; 4065cd7a67a4SMauro Carvalho Chehab u16 sc_comm_exec = 0; 40669a0bf528SMauro Carvalho Chehab 40679a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 40689a0bf528SMauro Carvalho Chehab 4069cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 40709a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 40719a0bf528SMauro Carvalho Chehab /* Check if SC is running */ 4072cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec); 40739a0bf528SMauro Carvalho Chehab if (status < 0) 40749a0bf528SMauro Carvalho Chehab goto end; 4075cd7a67a4SMauro Carvalho Chehab if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP) 40769a0bf528SMauro Carvalho Chehab goto end; 40779a0bf528SMauro Carvalho Chehab 4078cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock); 40799a0bf528SMauro Carvalho Chehab if (status < 0) 40809a0bf528SMauro Carvalho Chehab goto end; 40819a0bf528SMauro Carvalho Chehab 4082cd7a67a4SMauro Carvalho Chehab if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask) 4083cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK; 4084cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask) 4085cd7a67a4SMauro Carvalho Chehab *p_lock_status = FEC_LOCK; 4086cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask) 4087cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK; 4088cd7a67a4SMauro Carvalho Chehab else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) 4089cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK; 40909a0bf528SMauro Carvalho Chehab end: 40919a0bf528SMauro Carvalho Chehab if (status < 0) 40923a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 40939a0bf528SMauro Carvalho Chehab 40949a0bf528SMauro Carvalho Chehab return status; 40959a0bf528SMauro Carvalho Chehab } 40969a0bf528SMauro Carvalho Chehab 4097cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state) 40989a0bf528SMauro Carvalho Chehab { 4099cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 41009a0bf528SMauro Carvalho Chehab int status; 41019a0bf528SMauro Carvalho Chehab 41029a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 4103cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 41049a0bf528SMauro Carvalho Chehab if (status < 0) 41053a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 41069a0bf528SMauro Carvalho Chehab 41079a0bf528SMauro Carvalho Chehab return status; 41089a0bf528SMauro Carvalho Chehab } 41099a0bf528SMauro Carvalho Chehab 41109a0bf528SMauro Carvalho Chehab 411134eb9751SMauro Carvalho Chehab /* Power Down QAM */ 4112cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state) 41139a0bf528SMauro Carvalho Chehab { 41149a0bf528SMauro Carvalho Chehab u16 data = 0; 4115cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 41169a0bf528SMauro Carvalho Chehab int status = 0; 41179a0bf528SMauro Carvalho Chehab 41189a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 41199a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data); 41209a0bf528SMauro Carvalho Chehab if (status < 0) 41219a0bf528SMauro Carvalho Chehab goto error; 41229a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) { 41239a0bf528SMauro Carvalho Chehab /* 41249a0bf528SMauro Carvalho Chehab STOP demodulator 41259a0bf528SMauro Carvalho Chehab QAM and HW blocks 41269a0bf528SMauro Carvalho Chehab */ 41279a0bf528SMauro Carvalho Chehab /* stop all comstate->m_exec */ 41289a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 41299a0bf528SMauro Carvalho Chehab if (status < 0) 41309a0bf528SMauro Carvalho Chehab goto error; 4131ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 4132ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 4133ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 41349a0bf528SMauro Carvalho Chehab if (status < 0) 41359a0bf528SMauro Carvalho Chehab goto error; 41369a0bf528SMauro Carvalho Chehab } 41379a0bf528SMauro Carvalho Chehab /* powerdown AFE */ 4138cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false); 41399a0bf528SMauro Carvalho Chehab 41409a0bf528SMauro Carvalho Chehab error: 41419a0bf528SMauro Carvalho Chehab if (status < 0) 41423a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 41439a0bf528SMauro Carvalho Chehab 41449a0bf528SMauro Carvalho Chehab return status; 41459a0bf528SMauro Carvalho Chehab } 41469a0bf528SMauro Carvalho Chehab 41479a0bf528SMauro Carvalho Chehab /*============================================================================*/ 41489a0bf528SMauro Carvalho Chehab 414934eb9751SMauro Carvalho Chehab /* 41509a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality 41519a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 41529a0bf528SMauro Carvalho Chehab * \param modulation current modulation. 41539a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 41549a0bf528SMauro Carvalho Chehab * 41559a0bf528SMauro Carvalho Chehab * NOTE: 41569a0bf528SMauro Carvalho Chehab * Take into account that for certain settings the errorcounters can overflow. 41579a0bf528SMauro Carvalho Chehab * The implementation does not check this. 41589a0bf528SMauro Carvalho Chehab * 41599a0bf528SMauro Carvalho Chehab */ 4160cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state, 4161cd7a67a4SMauro Carvalho Chehab enum e_drxk_constellation modulation, 4162cd7a67a4SMauro Carvalho Chehab u32 symbol_rate) 41639a0bf528SMauro Carvalho Chehab { 4164cd7a67a4SMauro Carvalho Chehab u32 fec_bits_desired = 0; /* BER accounting period */ 4165cd7a67a4SMauro Carvalho Chehab u32 fec_rs_period_total = 0; /* Total period */ 4166cd7a67a4SMauro Carvalho Chehab u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */ 4167cd7a67a4SMauro Carvalho Chehab u16 fec_rs_period = 0; /* Value for corresponding I2C register */ 41689a0bf528SMauro Carvalho Chehab int status = 0; 41699a0bf528SMauro Carvalho Chehab 41709a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 41719a0bf528SMauro Carvalho Chehab 4172cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1; 4173cd7a67a4SMauro Carvalho Chehab /* fec_bits_desired = symbol_rate [kHz] * 41749a0bf528SMauro Carvalho Chehab FrameLenght [ms] * 41759a0bf528SMauro Carvalho Chehab (modulation + 1) * 41769a0bf528SMauro Carvalho Chehab SyncLoss (== 1) * 41779a0bf528SMauro Carvalho Chehab ViterbiLoss (==1) 41789a0bf528SMauro Carvalho Chehab */ 41799a0bf528SMauro Carvalho Chehab switch (modulation) { 41809a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM16: 4181cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 4 * symbol_rate; 41829a0bf528SMauro Carvalho Chehab break; 41839a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM32: 4184cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 5 * symbol_rate; 41859a0bf528SMauro Carvalho Chehab break; 41869a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM64: 4187cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 6 * symbol_rate; 41889a0bf528SMauro Carvalho Chehab break; 41899a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM128: 4190cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 7 * symbol_rate; 41919a0bf528SMauro Carvalho Chehab break; 41929a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM256: 4193cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 8 * symbol_rate; 41949a0bf528SMauro Carvalho Chehab break; 41959a0bf528SMauro Carvalho Chehab default: 41969a0bf528SMauro Carvalho Chehab status = -EINVAL; 41979a0bf528SMauro Carvalho Chehab } 41989a0bf528SMauro Carvalho Chehab if (status < 0) 41999a0bf528SMauro Carvalho Chehab goto error; 42009a0bf528SMauro Carvalho Chehab 4201cd7a67a4SMauro Carvalho Chehab fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */ 4202cd7a67a4SMauro Carvalho Chehab fec_bits_desired *= 500; /* meas. period [ms] */ 42039a0bf528SMauro Carvalho Chehab 42049a0bf528SMauro Carvalho Chehab /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */ 4205cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_bits_desired / 1632 */ 4206cd7a67a4SMauro Carvalho Chehab fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */ 42079a0bf528SMauro Carvalho Chehab 4208cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */ 4209cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16); 4210cd7a67a4SMauro Carvalho Chehab if (fec_rs_prescale == 0) { 42119a0bf528SMauro Carvalho Chehab /* Divide by zero (though impossible) */ 42129a0bf528SMauro Carvalho Chehab status = -EINVAL; 42139a0bf528SMauro Carvalho Chehab if (status < 0) 42149a0bf528SMauro Carvalho Chehab goto error; 42159a0bf528SMauro Carvalho Chehab } 4216cd7a67a4SMauro Carvalho Chehab fec_rs_period = 4217cd7a67a4SMauro Carvalho Chehab ((u16) fec_rs_period_total + 4218cd7a67a4SMauro Carvalho Chehab (fec_rs_prescale >> 1)) / fec_rs_prescale; 42199a0bf528SMauro Carvalho Chehab 42209a0bf528SMauro Carvalho Chehab /* write corresponding registers */ 4221cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period); 42229a0bf528SMauro Carvalho Chehab if (status < 0) 42239a0bf528SMauro Carvalho Chehab goto error; 4224ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 4225ab5060cdSMauro Carvalho Chehab fec_rs_prescale); 42269a0bf528SMauro Carvalho Chehab if (status < 0) 42279a0bf528SMauro Carvalho Chehab goto error; 4228cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period); 42299a0bf528SMauro Carvalho Chehab error: 42309a0bf528SMauro Carvalho Chehab if (status < 0) 42313a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 42329a0bf528SMauro Carvalho Chehab return status; 42339a0bf528SMauro Carvalho Chehab } 42349a0bf528SMauro Carvalho Chehab 4235cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state) 42369a0bf528SMauro Carvalho Chehab { 42379a0bf528SMauro Carvalho Chehab int status = 0; 42389a0bf528SMauro Carvalho Chehab 42399a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 42409a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 42419a0bf528SMauro Carvalho Chehab /* Equalizer */ 42429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517); 42439a0bf528SMauro Carvalho Chehab if (status < 0) 42449a0bf528SMauro Carvalho Chehab goto error; 42459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517); 42469a0bf528SMauro Carvalho Chehab if (status < 0) 42479a0bf528SMauro Carvalho Chehab goto error; 42489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517); 42499a0bf528SMauro Carvalho Chehab if (status < 0) 42509a0bf528SMauro Carvalho Chehab goto error; 42519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517); 42529a0bf528SMauro Carvalho Chehab if (status < 0) 42539a0bf528SMauro Carvalho Chehab goto error; 42549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517); 42559a0bf528SMauro Carvalho Chehab if (status < 0) 42569a0bf528SMauro Carvalho Chehab goto error; 42579a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517); 42589a0bf528SMauro Carvalho Chehab if (status < 0) 42599a0bf528SMauro Carvalho Chehab goto error; 42609a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 42619a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 2); 42629a0bf528SMauro Carvalho Chehab if (status < 0) 42639a0bf528SMauro Carvalho Chehab goto error; 42649a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 2); 42659a0bf528SMauro Carvalho Chehab if (status < 0) 42669a0bf528SMauro Carvalho Chehab goto error; 42679a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 2); 42689a0bf528SMauro Carvalho Chehab if (status < 0) 42699a0bf528SMauro Carvalho Chehab goto error; 42709a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 2); 42719a0bf528SMauro Carvalho Chehab if (status < 0) 42729a0bf528SMauro Carvalho Chehab goto error; 42739a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 2); 42749a0bf528SMauro Carvalho Chehab if (status < 0) 42759a0bf528SMauro Carvalho Chehab goto error; 42769a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 42779a0bf528SMauro Carvalho Chehab if (status < 0) 42789a0bf528SMauro Carvalho Chehab goto error; 42799a0bf528SMauro Carvalho Chehab 42809a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 42819a0bf528SMauro Carvalho Chehab if (status < 0) 42829a0bf528SMauro Carvalho Chehab goto error; 42839a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 42849a0bf528SMauro Carvalho Chehab if (status < 0) 42859a0bf528SMauro Carvalho Chehab goto error; 42869a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 42879a0bf528SMauro Carvalho Chehab if (status < 0) 42889a0bf528SMauro Carvalho Chehab goto error; 42899a0bf528SMauro Carvalho Chehab 42909a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 4291ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4292ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM16); 42939a0bf528SMauro Carvalho Chehab if (status < 0) 42949a0bf528SMauro Carvalho Chehab goto error; 42959a0bf528SMauro Carvalho Chehab 42969a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 42979a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 42989a0bf528SMauro Carvalho Chehab if (status < 0) 42999a0bf528SMauro Carvalho Chehab goto error; 43009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 43019a0bf528SMauro Carvalho Chehab if (status < 0) 43029a0bf528SMauro Carvalho Chehab goto error; 43039a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 43049a0bf528SMauro Carvalho Chehab if (status < 0) 43059a0bf528SMauro Carvalho Chehab goto error; 43069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 43079a0bf528SMauro Carvalho Chehab if (status < 0) 43089a0bf528SMauro Carvalho Chehab goto error; 43099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 43109a0bf528SMauro Carvalho Chehab if (status < 0) 43119a0bf528SMauro Carvalho Chehab goto error; 43129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 43139a0bf528SMauro Carvalho Chehab if (status < 0) 43149a0bf528SMauro Carvalho Chehab goto error; 43159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 43169a0bf528SMauro Carvalho Chehab if (status < 0) 43179a0bf528SMauro Carvalho Chehab goto error; 43189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 43199a0bf528SMauro Carvalho Chehab if (status < 0) 43209a0bf528SMauro Carvalho Chehab goto error; 43219a0bf528SMauro Carvalho Chehab 43229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 43239a0bf528SMauro Carvalho Chehab if (status < 0) 43249a0bf528SMauro Carvalho Chehab goto error; 43259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 43269a0bf528SMauro Carvalho Chehab if (status < 0) 43279a0bf528SMauro Carvalho Chehab goto error; 43289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 43299a0bf528SMauro Carvalho Chehab if (status < 0) 43309a0bf528SMauro Carvalho Chehab goto error; 43319a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 43329a0bf528SMauro Carvalho Chehab if (status < 0) 43339a0bf528SMauro Carvalho Chehab goto error; 43349a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 43359a0bf528SMauro Carvalho Chehab if (status < 0) 43369a0bf528SMauro Carvalho Chehab goto error; 43379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 43389a0bf528SMauro Carvalho Chehab if (status < 0) 43399a0bf528SMauro Carvalho Chehab goto error; 43409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 43419a0bf528SMauro Carvalho Chehab if (status < 0) 43429a0bf528SMauro Carvalho Chehab goto error; 43439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 43449a0bf528SMauro Carvalho Chehab if (status < 0) 43459a0bf528SMauro Carvalho Chehab goto error; 43469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32); 43479a0bf528SMauro Carvalho Chehab if (status < 0) 43489a0bf528SMauro Carvalho Chehab goto error; 43499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 43509a0bf528SMauro Carvalho Chehab if (status < 0) 43519a0bf528SMauro Carvalho Chehab goto error; 43529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 43539a0bf528SMauro Carvalho Chehab if (status < 0) 43549a0bf528SMauro Carvalho Chehab goto error; 43559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 43569a0bf528SMauro Carvalho Chehab if (status < 0) 43579a0bf528SMauro Carvalho Chehab goto error; 43589a0bf528SMauro Carvalho Chehab 43599a0bf528SMauro Carvalho Chehab 43609a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 43619a0bf528SMauro Carvalho Chehab 43629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140); 43639a0bf528SMauro Carvalho Chehab if (status < 0) 43649a0bf528SMauro Carvalho Chehab goto error; 43659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 43669a0bf528SMauro Carvalho Chehab if (status < 0) 43679a0bf528SMauro Carvalho Chehab goto error; 43689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95); 43699a0bf528SMauro Carvalho Chehab if (status < 0) 43709a0bf528SMauro Carvalho Chehab goto error; 43719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120); 43729a0bf528SMauro Carvalho Chehab if (status < 0) 43739a0bf528SMauro Carvalho Chehab goto error; 43749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230); 43759a0bf528SMauro Carvalho Chehab if (status < 0) 43769a0bf528SMauro Carvalho Chehab goto error; 43779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105); 43789a0bf528SMauro Carvalho Chehab if (status < 0) 43799a0bf528SMauro Carvalho Chehab goto error; 43809a0bf528SMauro Carvalho Chehab 43819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 43829a0bf528SMauro Carvalho Chehab if (status < 0) 43839a0bf528SMauro Carvalho Chehab goto error; 43849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 43859a0bf528SMauro Carvalho Chehab if (status < 0) 43869a0bf528SMauro Carvalho Chehab goto error; 43879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24); 43889a0bf528SMauro Carvalho Chehab if (status < 0) 43899a0bf528SMauro Carvalho Chehab goto error; 43909a0bf528SMauro Carvalho Chehab 43919a0bf528SMauro Carvalho Chehab 43929a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 43939a0bf528SMauro Carvalho Chehab 43949a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16); 43959a0bf528SMauro Carvalho Chehab if (status < 0) 43969a0bf528SMauro Carvalho Chehab goto error; 43979a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220); 43989a0bf528SMauro Carvalho Chehab if (status < 0) 43999a0bf528SMauro Carvalho Chehab goto error; 44009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25); 44019a0bf528SMauro Carvalho Chehab if (status < 0) 44029a0bf528SMauro Carvalho Chehab goto error; 44039a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6); 44049a0bf528SMauro Carvalho Chehab if (status < 0) 44059a0bf528SMauro Carvalho Chehab goto error; 44069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24); 44079a0bf528SMauro Carvalho Chehab if (status < 0) 44089a0bf528SMauro Carvalho Chehab goto error; 44099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65); 44109a0bf528SMauro Carvalho Chehab if (status < 0) 44119a0bf528SMauro Carvalho Chehab goto error; 44129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127); 44139a0bf528SMauro Carvalho Chehab if (status < 0) 44149a0bf528SMauro Carvalho Chehab goto error; 44159a0bf528SMauro Carvalho Chehab 44169a0bf528SMauro Carvalho Chehab error: 44179a0bf528SMauro Carvalho Chehab if (status < 0) 44183a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 44199a0bf528SMauro Carvalho Chehab return status; 44209a0bf528SMauro Carvalho Chehab } 44219a0bf528SMauro Carvalho Chehab 44229a0bf528SMauro Carvalho Chehab /*============================================================================*/ 44239a0bf528SMauro Carvalho Chehab 442434eb9751SMauro Carvalho Chehab /* 44259a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup 44269a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 44279a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 44289a0bf528SMauro Carvalho Chehab */ 4429cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state) 44309a0bf528SMauro Carvalho Chehab { 44319a0bf528SMauro Carvalho Chehab int status = 0; 44329a0bf528SMauro Carvalho Chehab 44339a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 44349a0bf528SMauro Carvalho Chehab 44359a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 44369a0bf528SMauro Carvalho Chehab /* Equalizer */ 44379a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707); 44389a0bf528SMauro Carvalho Chehab if (status < 0) 44399a0bf528SMauro Carvalho Chehab goto error; 44409a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707); 44419a0bf528SMauro Carvalho Chehab if (status < 0) 44429a0bf528SMauro Carvalho Chehab goto error; 44439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707); 44449a0bf528SMauro Carvalho Chehab if (status < 0) 44459a0bf528SMauro Carvalho Chehab goto error; 44469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707); 44479a0bf528SMauro Carvalho Chehab if (status < 0) 44489a0bf528SMauro Carvalho Chehab goto error; 44499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707); 44509a0bf528SMauro Carvalho Chehab if (status < 0) 44519a0bf528SMauro Carvalho Chehab goto error; 44529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707); 44539a0bf528SMauro Carvalho Chehab if (status < 0) 44549a0bf528SMauro Carvalho Chehab goto error; 44559a0bf528SMauro Carvalho Chehab 44569a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 44579a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 3); 44589a0bf528SMauro Carvalho Chehab if (status < 0) 44599a0bf528SMauro Carvalho Chehab goto error; 44609a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 3); 44619a0bf528SMauro Carvalho Chehab if (status < 0) 44629a0bf528SMauro Carvalho Chehab goto error; 44639a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 3); 44649a0bf528SMauro Carvalho Chehab if (status < 0) 44659a0bf528SMauro Carvalho Chehab goto error; 44669a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 3); 44679a0bf528SMauro Carvalho Chehab if (status < 0) 44689a0bf528SMauro Carvalho Chehab goto error; 44699a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 44709a0bf528SMauro Carvalho Chehab if (status < 0) 44719a0bf528SMauro Carvalho Chehab goto error; 44729a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 44739a0bf528SMauro Carvalho Chehab if (status < 0) 44749a0bf528SMauro Carvalho Chehab goto error; 44759a0bf528SMauro Carvalho Chehab 44769a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6); 44779a0bf528SMauro Carvalho Chehab if (status < 0) 44789a0bf528SMauro Carvalho Chehab goto error; 44799a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5); 44809a0bf528SMauro Carvalho Chehab if (status < 0) 44819a0bf528SMauro Carvalho Chehab goto error; 44829a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 44839a0bf528SMauro Carvalho Chehab if (status < 0) 44849a0bf528SMauro Carvalho Chehab goto error; 44859a0bf528SMauro Carvalho Chehab 44869a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 44879a0bf528SMauro Carvalho Chehab 4488ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4489ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM32); 44909a0bf528SMauro Carvalho Chehab if (status < 0) 44919a0bf528SMauro Carvalho Chehab goto error; 44929a0bf528SMauro Carvalho Chehab 44939a0bf528SMauro Carvalho Chehab 44949a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 44959a0bf528SMauro Carvalho Chehab 44969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 44979a0bf528SMauro Carvalho Chehab if (status < 0) 44989a0bf528SMauro Carvalho Chehab goto error; 44999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 45009a0bf528SMauro Carvalho Chehab if (status < 0) 45019a0bf528SMauro Carvalho Chehab goto error; 45029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 45039a0bf528SMauro Carvalho Chehab if (status < 0) 45049a0bf528SMauro Carvalho Chehab goto error; 45059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 45069a0bf528SMauro Carvalho Chehab if (status < 0) 45079a0bf528SMauro Carvalho Chehab goto error; 45089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 45099a0bf528SMauro Carvalho Chehab if (status < 0) 45109a0bf528SMauro Carvalho Chehab goto error; 45119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 45129a0bf528SMauro Carvalho Chehab if (status < 0) 45139a0bf528SMauro Carvalho Chehab goto error; 45149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 45159a0bf528SMauro Carvalho Chehab if (status < 0) 45169a0bf528SMauro Carvalho Chehab goto error; 45179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 45189a0bf528SMauro Carvalho Chehab if (status < 0) 45199a0bf528SMauro Carvalho Chehab goto error; 45209a0bf528SMauro Carvalho Chehab 45219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 45229a0bf528SMauro Carvalho Chehab if (status < 0) 45239a0bf528SMauro Carvalho Chehab goto error; 45249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 45259a0bf528SMauro Carvalho Chehab if (status < 0) 45269a0bf528SMauro Carvalho Chehab goto error; 45279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 45289a0bf528SMauro Carvalho Chehab if (status < 0) 45299a0bf528SMauro Carvalho Chehab goto error; 45309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 45319a0bf528SMauro Carvalho Chehab if (status < 0) 45329a0bf528SMauro Carvalho Chehab goto error; 45339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 45349a0bf528SMauro Carvalho Chehab if (status < 0) 45359a0bf528SMauro Carvalho Chehab goto error; 45369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 45379a0bf528SMauro Carvalho Chehab if (status < 0) 45389a0bf528SMauro Carvalho Chehab goto error; 45399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 45409a0bf528SMauro Carvalho Chehab if (status < 0) 45419a0bf528SMauro Carvalho Chehab goto error; 45429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 45439a0bf528SMauro Carvalho Chehab if (status < 0) 45449a0bf528SMauro Carvalho Chehab goto error; 45459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16); 45469a0bf528SMauro Carvalho Chehab if (status < 0) 45479a0bf528SMauro Carvalho Chehab goto error; 45489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 45499a0bf528SMauro Carvalho Chehab if (status < 0) 45509a0bf528SMauro Carvalho Chehab goto error; 45519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 45529a0bf528SMauro Carvalho Chehab if (status < 0) 45539a0bf528SMauro Carvalho Chehab goto error; 45549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 45559a0bf528SMauro Carvalho Chehab if (status < 0) 45569a0bf528SMauro Carvalho Chehab goto error; 45579a0bf528SMauro Carvalho Chehab 45589a0bf528SMauro Carvalho Chehab 45599a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 45609a0bf528SMauro Carvalho Chehab 45619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90); 45629a0bf528SMauro Carvalho Chehab if (status < 0) 45639a0bf528SMauro Carvalho Chehab goto error; 45649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 45659a0bf528SMauro Carvalho Chehab if (status < 0) 45669a0bf528SMauro Carvalho Chehab goto error; 45679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 45689a0bf528SMauro Carvalho Chehab if (status < 0) 45699a0bf528SMauro Carvalho Chehab goto error; 45709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 45719a0bf528SMauro Carvalho Chehab if (status < 0) 45729a0bf528SMauro Carvalho Chehab goto error; 45739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170); 45749a0bf528SMauro Carvalho Chehab if (status < 0) 45759a0bf528SMauro Carvalho Chehab goto error; 45769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 45779a0bf528SMauro Carvalho Chehab if (status < 0) 45789a0bf528SMauro Carvalho Chehab goto error; 45799a0bf528SMauro Carvalho Chehab 45809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 45819a0bf528SMauro Carvalho Chehab if (status < 0) 45829a0bf528SMauro Carvalho Chehab goto error; 45839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 45849a0bf528SMauro Carvalho Chehab if (status < 0) 45859a0bf528SMauro Carvalho Chehab goto error; 45869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10); 45879a0bf528SMauro Carvalho Chehab if (status < 0) 45889a0bf528SMauro Carvalho Chehab goto error; 45899a0bf528SMauro Carvalho Chehab 45909a0bf528SMauro Carvalho Chehab 45919a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 45929a0bf528SMauro Carvalho Chehab 45939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 45949a0bf528SMauro Carvalho Chehab if (status < 0) 45959a0bf528SMauro Carvalho Chehab goto error; 45969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140); 45979a0bf528SMauro Carvalho Chehab if (status < 0) 45989a0bf528SMauro Carvalho Chehab goto error; 45999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8); 46009a0bf528SMauro Carvalho Chehab if (status < 0) 46019a0bf528SMauro Carvalho Chehab goto error; 46029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16); 46039a0bf528SMauro Carvalho Chehab if (status < 0) 46049a0bf528SMauro Carvalho Chehab goto error; 46059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26); 46069a0bf528SMauro Carvalho Chehab if (status < 0) 46079a0bf528SMauro Carvalho Chehab goto error; 46089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56); 46099a0bf528SMauro Carvalho Chehab if (status < 0) 46109a0bf528SMauro Carvalho Chehab goto error; 46119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86); 46129a0bf528SMauro Carvalho Chehab error: 46139a0bf528SMauro Carvalho Chehab if (status < 0) 46143a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 46159a0bf528SMauro Carvalho Chehab return status; 46169a0bf528SMauro Carvalho Chehab } 46179a0bf528SMauro Carvalho Chehab 46189a0bf528SMauro Carvalho Chehab /*============================================================================*/ 46199a0bf528SMauro Carvalho Chehab 462034eb9751SMauro Carvalho Chehab /* 46219a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup 46229a0bf528SMauro Carvalho Chehab * \param demod instance of demod. 46239a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 46249a0bf528SMauro Carvalho Chehab */ 4625cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state) 46269a0bf528SMauro Carvalho Chehab { 46279a0bf528SMauro Carvalho Chehab int status = 0; 46289a0bf528SMauro Carvalho Chehab 46299a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 46309a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 46319a0bf528SMauro Carvalho Chehab /* Equalizer */ 46329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336); 46339a0bf528SMauro Carvalho Chehab if (status < 0) 46349a0bf528SMauro Carvalho Chehab goto error; 46359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618); 46369a0bf528SMauro Carvalho Chehab if (status < 0) 46379a0bf528SMauro Carvalho Chehab goto error; 46389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988); 46399a0bf528SMauro Carvalho Chehab if (status < 0) 46409a0bf528SMauro Carvalho Chehab goto error; 46419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809); 46429a0bf528SMauro Carvalho Chehab if (status < 0) 46439a0bf528SMauro Carvalho Chehab goto error; 46449a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809); 46459a0bf528SMauro Carvalho Chehab if (status < 0) 46469a0bf528SMauro Carvalho Chehab goto error; 46479a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609); 46489a0bf528SMauro Carvalho Chehab if (status < 0) 46499a0bf528SMauro Carvalho Chehab goto error; 46509a0bf528SMauro Carvalho Chehab 46519a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 46529a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 4); 46539a0bf528SMauro Carvalho Chehab if (status < 0) 46549a0bf528SMauro Carvalho Chehab goto error; 46559a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 4); 46569a0bf528SMauro Carvalho Chehab if (status < 0) 46579a0bf528SMauro Carvalho Chehab goto error; 46589a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 4); 46599a0bf528SMauro Carvalho Chehab if (status < 0) 46609a0bf528SMauro Carvalho Chehab goto error; 46619a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 4); 46629a0bf528SMauro Carvalho Chehab if (status < 0) 46639a0bf528SMauro Carvalho Chehab goto error; 46649a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 46659a0bf528SMauro Carvalho Chehab if (status < 0) 46669a0bf528SMauro Carvalho Chehab goto error; 46679a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 46689a0bf528SMauro Carvalho Chehab if (status < 0) 46699a0bf528SMauro Carvalho Chehab goto error; 46709a0bf528SMauro Carvalho Chehab 46719a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 46729a0bf528SMauro Carvalho Chehab if (status < 0) 46739a0bf528SMauro Carvalho Chehab goto error; 46749a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 46759a0bf528SMauro Carvalho Chehab if (status < 0) 46769a0bf528SMauro Carvalho Chehab goto error; 46779a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 46789a0bf528SMauro Carvalho Chehab if (status < 0) 46799a0bf528SMauro Carvalho Chehab goto error; 46809a0bf528SMauro Carvalho Chehab 46819a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 4682ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4683ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM64); 46849a0bf528SMauro Carvalho Chehab if (status < 0) 46859a0bf528SMauro Carvalho Chehab goto error; 46869a0bf528SMauro Carvalho Chehab 46879a0bf528SMauro Carvalho Chehab 46889a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 46899a0bf528SMauro Carvalho Chehab 46909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 46919a0bf528SMauro Carvalho Chehab if (status < 0) 46929a0bf528SMauro Carvalho Chehab goto error; 46939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 46949a0bf528SMauro Carvalho Chehab if (status < 0) 46959a0bf528SMauro Carvalho Chehab goto error; 46969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 46979a0bf528SMauro Carvalho Chehab if (status < 0) 46989a0bf528SMauro Carvalho Chehab goto error; 46999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 47009a0bf528SMauro Carvalho Chehab if (status < 0) 47019a0bf528SMauro Carvalho Chehab goto error; 47029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 47039a0bf528SMauro Carvalho Chehab if (status < 0) 47049a0bf528SMauro Carvalho Chehab goto error; 47059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 47069a0bf528SMauro Carvalho Chehab if (status < 0) 47079a0bf528SMauro Carvalho Chehab goto error; 47089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 47099a0bf528SMauro Carvalho Chehab if (status < 0) 47109a0bf528SMauro Carvalho Chehab goto error; 47119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 47129a0bf528SMauro Carvalho Chehab if (status < 0) 47139a0bf528SMauro Carvalho Chehab goto error; 47149a0bf528SMauro Carvalho Chehab 47159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 47169a0bf528SMauro Carvalho Chehab if (status < 0) 47179a0bf528SMauro Carvalho Chehab goto error; 47189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30); 47199a0bf528SMauro Carvalho Chehab if (status < 0) 47209a0bf528SMauro Carvalho Chehab goto error; 47219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100); 47229a0bf528SMauro Carvalho Chehab if (status < 0) 47239a0bf528SMauro Carvalho Chehab goto error; 47249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 47259a0bf528SMauro Carvalho Chehab if (status < 0) 47269a0bf528SMauro Carvalho Chehab goto error; 47279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30); 47289a0bf528SMauro Carvalho Chehab if (status < 0) 47299a0bf528SMauro Carvalho Chehab goto error; 47309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 47319a0bf528SMauro Carvalho Chehab if (status < 0) 47329a0bf528SMauro Carvalho Chehab goto error; 47339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 47349a0bf528SMauro Carvalho Chehab if (status < 0) 47359a0bf528SMauro Carvalho Chehab goto error; 47369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 47379a0bf528SMauro Carvalho Chehab if (status < 0) 47389a0bf528SMauro Carvalho Chehab goto error; 47399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 47409a0bf528SMauro Carvalho Chehab if (status < 0) 47419a0bf528SMauro Carvalho Chehab goto error; 47429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 47439a0bf528SMauro Carvalho Chehab if (status < 0) 47449a0bf528SMauro Carvalho Chehab goto error; 47459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 47469a0bf528SMauro Carvalho Chehab if (status < 0) 47479a0bf528SMauro Carvalho Chehab goto error; 47489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 47499a0bf528SMauro Carvalho Chehab if (status < 0) 47509a0bf528SMauro Carvalho Chehab goto error; 47519a0bf528SMauro Carvalho Chehab 47529a0bf528SMauro Carvalho Chehab 47539a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 47549a0bf528SMauro Carvalho Chehab 47559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100); 47569a0bf528SMauro Carvalho Chehab if (status < 0) 47579a0bf528SMauro Carvalho Chehab goto error; 47589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 47599a0bf528SMauro Carvalho Chehab if (status < 0) 47609a0bf528SMauro Carvalho Chehab goto error; 47619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 47629a0bf528SMauro Carvalho Chehab if (status < 0) 47639a0bf528SMauro Carvalho Chehab goto error; 47649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110); 47659a0bf528SMauro Carvalho Chehab if (status < 0) 47669a0bf528SMauro Carvalho Chehab goto error; 47679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200); 47689a0bf528SMauro Carvalho Chehab if (status < 0) 47699a0bf528SMauro Carvalho Chehab goto error; 47709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95); 47719a0bf528SMauro Carvalho Chehab if (status < 0) 47729a0bf528SMauro Carvalho Chehab goto error; 47739a0bf528SMauro Carvalho Chehab 47749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 47759a0bf528SMauro Carvalho Chehab if (status < 0) 47769a0bf528SMauro Carvalho Chehab goto error; 47779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 47789a0bf528SMauro Carvalho Chehab if (status < 0) 47799a0bf528SMauro Carvalho Chehab goto error; 47809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15); 47819a0bf528SMauro Carvalho Chehab if (status < 0) 47829a0bf528SMauro Carvalho Chehab goto error; 47839a0bf528SMauro Carvalho Chehab 47849a0bf528SMauro Carvalho Chehab 47859a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 47869a0bf528SMauro Carvalho Chehab 47879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 47889a0bf528SMauro Carvalho Chehab if (status < 0) 47899a0bf528SMauro Carvalho Chehab goto error; 47909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141); 47919a0bf528SMauro Carvalho Chehab if (status < 0) 47929a0bf528SMauro Carvalho Chehab goto error; 47939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7); 47949a0bf528SMauro Carvalho Chehab if (status < 0) 47959a0bf528SMauro Carvalho Chehab goto error; 47969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0); 47979a0bf528SMauro Carvalho Chehab if (status < 0) 47989a0bf528SMauro Carvalho Chehab goto error; 47999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15); 48009a0bf528SMauro Carvalho Chehab if (status < 0) 48019a0bf528SMauro Carvalho Chehab goto error; 48029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45); 48039a0bf528SMauro Carvalho Chehab if (status < 0) 48049a0bf528SMauro Carvalho Chehab goto error; 48059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80); 48069a0bf528SMauro Carvalho Chehab error: 48079a0bf528SMauro Carvalho Chehab if (status < 0) 48083a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 48099a0bf528SMauro Carvalho Chehab 48109a0bf528SMauro Carvalho Chehab return status; 48119a0bf528SMauro Carvalho Chehab } 48129a0bf528SMauro Carvalho Chehab 48139a0bf528SMauro Carvalho Chehab /*============================================================================*/ 48149a0bf528SMauro Carvalho Chehab 481534eb9751SMauro Carvalho Chehab /* 48169a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup 48179a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 48189a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 48199a0bf528SMauro Carvalho Chehab */ 4820cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state) 48219a0bf528SMauro Carvalho Chehab { 48229a0bf528SMauro Carvalho Chehab int status = 0; 48239a0bf528SMauro Carvalho Chehab 48249a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 48259a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 48269a0bf528SMauro Carvalho Chehab /* Equalizer */ 48279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564); 48289a0bf528SMauro Carvalho Chehab if (status < 0) 48299a0bf528SMauro Carvalho Chehab goto error; 48309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598); 48319a0bf528SMauro Carvalho Chehab if (status < 0) 48329a0bf528SMauro Carvalho Chehab goto error; 48339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394); 48349a0bf528SMauro Carvalho Chehab if (status < 0) 48359a0bf528SMauro Carvalho Chehab goto error; 48369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409); 48379a0bf528SMauro Carvalho Chehab if (status < 0) 48389a0bf528SMauro Carvalho Chehab goto error; 48399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656); 48409a0bf528SMauro Carvalho Chehab if (status < 0) 48419a0bf528SMauro Carvalho Chehab goto error; 48429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238); 48439a0bf528SMauro Carvalho Chehab if (status < 0) 48449a0bf528SMauro Carvalho Chehab goto error; 48459a0bf528SMauro Carvalho Chehab 48469a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 48479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 6); 48489a0bf528SMauro Carvalho Chehab if (status < 0) 48499a0bf528SMauro Carvalho Chehab goto error; 48509a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 6); 48519a0bf528SMauro Carvalho Chehab if (status < 0) 48529a0bf528SMauro Carvalho Chehab goto error; 48539a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 6); 48549a0bf528SMauro Carvalho Chehab if (status < 0) 48559a0bf528SMauro Carvalho Chehab goto error; 48569a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 6); 48579a0bf528SMauro Carvalho Chehab if (status < 0) 48589a0bf528SMauro Carvalho Chehab goto error; 48599a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 5); 48609a0bf528SMauro Carvalho Chehab if (status < 0) 48619a0bf528SMauro Carvalho Chehab goto error; 48629a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 48639a0bf528SMauro Carvalho Chehab if (status < 0) 48649a0bf528SMauro Carvalho Chehab goto error; 48659a0bf528SMauro Carvalho Chehab 48669a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6); 48679a0bf528SMauro Carvalho Chehab if (status < 0) 48689a0bf528SMauro Carvalho Chehab goto error; 48699a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5); 48709a0bf528SMauro Carvalho Chehab if (status < 0) 48719a0bf528SMauro Carvalho Chehab goto error; 48729a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 48739a0bf528SMauro Carvalho Chehab if (status < 0) 48749a0bf528SMauro Carvalho Chehab goto error; 48759a0bf528SMauro Carvalho Chehab 48769a0bf528SMauro Carvalho Chehab 48779a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 48789a0bf528SMauro Carvalho Chehab 4879ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 4880ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM128); 48819a0bf528SMauro Carvalho Chehab if (status < 0) 48829a0bf528SMauro Carvalho Chehab goto error; 48839a0bf528SMauro Carvalho Chehab 48849a0bf528SMauro Carvalho Chehab 48859a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 48869a0bf528SMauro Carvalho Chehab 48879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 48889a0bf528SMauro Carvalho Chehab if (status < 0) 48899a0bf528SMauro Carvalho Chehab goto error; 48909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 48919a0bf528SMauro Carvalho Chehab if (status < 0) 48929a0bf528SMauro Carvalho Chehab goto error; 48939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 48949a0bf528SMauro Carvalho Chehab if (status < 0) 48959a0bf528SMauro Carvalho Chehab goto error; 48969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 48979a0bf528SMauro Carvalho Chehab if (status < 0) 48989a0bf528SMauro Carvalho Chehab goto error; 48999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 49009a0bf528SMauro Carvalho Chehab if (status < 0) 49019a0bf528SMauro Carvalho Chehab goto error; 49029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 49039a0bf528SMauro Carvalho Chehab if (status < 0) 49049a0bf528SMauro Carvalho Chehab goto error; 49059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 49069a0bf528SMauro Carvalho Chehab if (status < 0) 49079a0bf528SMauro Carvalho Chehab goto error; 49089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 49099a0bf528SMauro Carvalho Chehab if (status < 0) 49109a0bf528SMauro Carvalho Chehab goto error; 49119a0bf528SMauro Carvalho Chehab 49129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 49139a0bf528SMauro Carvalho Chehab if (status < 0) 49149a0bf528SMauro Carvalho Chehab goto error; 49159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40); 49169a0bf528SMauro Carvalho Chehab if (status < 0) 49179a0bf528SMauro Carvalho Chehab goto error; 49189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120); 49199a0bf528SMauro Carvalho Chehab if (status < 0) 49209a0bf528SMauro Carvalho Chehab goto error; 49219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 49229a0bf528SMauro Carvalho Chehab if (status < 0) 49239a0bf528SMauro Carvalho Chehab goto error; 49249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40); 49259a0bf528SMauro Carvalho Chehab if (status < 0) 49269a0bf528SMauro Carvalho Chehab goto error; 49279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60); 49289a0bf528SMauro Carvalho Chehab if (status < 0) 49299a0bf528SMauro Carvalho Chehab goto error; 49309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 49319a0bf528SMauro Carvalho Chehab if (status < 0) 49329a0bf528SMauro Carvalho Chehab goto error; 49339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 49349a0bf528SMauro Carvalho Chehab if (status < 0) 49359a0bf528SMauro Carvalho Chehab goto error; 49369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64); 49379a0bf528SMauro Carvalho Chehab if (status < 0) 49389a0bf528SMauro Carvalho Chehab goto error; 49399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 49409a0bf528SMauro Carvalho Chehab if (status < 0) 49419a0bf528SMauro Carvalho Chehab goto error; 49429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 49439a0bf528SMauro Carvalho Chehab if (status < 0) 49449a0bf528SMauro Carvalho Chehab goto error; 49459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 49469a0bf528SMauro Carvalho Chehab if (status < 0) 49479a0bf528SMauro Carvalho Chehab goto error; 49489a0bf528SMauro Carvalho Chehab 49499a0bf528SMauro Carvalho Chehab 49509a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 49519a0bf528SMauro Carvalho Chehab 49529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 49539a0bf528SMauro Carvalho Chehab if (status < 0) 49549a0bf528SMauro Carvalho Chehab goto error; 49559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 49569a0bf528SMauro Carvalho Chehab if (status < 0) 49579a0bf528SMauro Carvalho Chehab goto error; 49589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 49599a0bf528SMauro Carvalho Chehab if (status < 0) 49609a0bf528SMauro Carvalho Chehab goto error; 49619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 49629a0bf528SMauro Carvalho Chehab if (status < 0) 49639a0bf528SMauro Carvalho Chehab goto error; 49649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140); 49659a0bf528SMauro Carvalho Chehab if (status < 0) 49669a0bf528SMauro Carvalho Chehab goto error; 49679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 49689a0bf528SMauro Carvalho Chehab if (status < 0) 49699a0bf528SMauro Carvalho Chehab goto error; 49709a0bf528SMauro Carvalho Chehab 49719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 49729a0bf528SMauro Carvalho Chehab if (status < 0) 49739a0bf528SMauro Carvalho Chehab goto error; 49749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5); 49759a0bf528SMauro Carvalho Chehab if (status < 0) 49769a0bf528SMauro Carvalho Chehab goto error; 49779a0bf528SMauro Carvalho Chehab 49789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 49799a0bf528SMauro Carvalho Chehab if (status < 0) 49809a0bf528SMauro Carvalho Chehab goto error; 49819a0bf528SMauro Carvalho Chehab 49829a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 49839a0bf528SMauro Carvalho Chehab 49849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 49859a0bf528SMauro Carvalho Chehab if (status < 0) 49869a0bf528SMauro Carvalho Chehab goto error; 49879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65); 49889a0bf528SMauro Carvalho Chehab if (status < 0) 49899a0bf528SMauro Carvalho Chehab goto error; 49909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5); 49919a0bf528SMauro Carvalho Chehab if (status < 0) 49929a0bf528SMauro Carvalho Chehab goto error; 49939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3); 49949a0bf528SMauro Carvalho Chehab if (status < 0) 49959a0bf528SMauro Carvalho Chehab goto error; 49969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1); 49979a0bf528SMauro Carvalho Chehab if (status < 0) 49989a0bf528SMauro Carvalho Chehab goto error; 49999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12); 50009a0bf528SMauro Carvalho Chehab if (status < 0) 50019a0bf528SMauro Carvalho Chehab goto error; 50029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23); 50039a0bf528SMauro Carvalho Chehab error: 50049a0bf528SMauro Carvalho Chehab if (status < 0) 50053a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 50069a0bf528SMauro Carvalho Chehab 50079a0bf528SMauro Carvalho Chehab return status; 50089a0bf528SMauro Carvalho Chehab } 50099a0bf528SMauro Carvalho Chehab 50109a0bf528SMauro Carvalho Chehab /*============================================================================*/ 50119a0bf528SMauro Carvalho Chehab 501234eb9751SMauro Carvalho Chehab /* 50139a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup 50149a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 50159a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 50169a0bf528SMauro Carvalho Chehab */ 5017cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state) 50189a0bf528SMauro Carvalho Chehab { 50199a0bf528SMauro Carvalho Chehab int status = 0; 50209a0bf528SMauro Carvalho Chehab 50219a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 50229a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */ 50239a0bf528SMauro Carvalho Chehab /* Equalizer */ 50249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502); 50259a0bf528SMauro Carvalho Chehab if (status < 0) 50269a0bf528SMauro Carvalho Chehab goto error; 50279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084); 50289a0bf528SMauro Carvalho Chehab if (status < 0) 50299a0bf528SMauro Carvalho Chehab goto error; 50309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543); 50319a0bf528SMauro Carvalho Chehab if (status < 0) 50329a0bf528SMauro Carvalho Chehab goto error; 50339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931); 50349a0bf528SMauro Carvalho Chehab if (status < 0) 50359a0bf528SMauro Carvalho Chehab goto error; 50369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629); 50379a0bf528SMauro Carvalho Chehab if (status < 0) 50389a0bf528SMauro Carvalho Chehab goto error; 50399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385); 50409a0bf528SMauro Carvalho Chehab if (status < 0) 50419a0bf528SMauro Carvalho Chehab goto error; 50429a0bf528SMauro Carvalho Chehab 50439a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */ 50449a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 8); 50459a0bf528SMauro Carvalho Chehab if (status < 0) 50469a0bf528SMauro Carvalho Chehab goto error; 50479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 8); 50489a0bf528SMauro Carvalho Chehab if (status < 0) 50499a0bf528SMauro Carvalho Chehab goto error; 50509a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 8); 50519a0bf528SMauro Carvalho Chehab if (status < 0) 50529a0bf528SMauro Carvalho Chehab goto error; 50539a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 8); 50549a0bf528SMauro Carvalho Chehab if (status < 0) 50559a0bf528SMauro Carvalho Chehab goto error; 50569a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 6); 50579a0bf528SMauro Carvalho Chehab if (status < 0) 50589a0bf528SMauro Carvalho Chehab goto error; 50599a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 50609a0bf528SMauro Carvalho Chehab if (status < 0) 50619a0bf528SMauro Carvalho Chehab goto error; 50629a0bf528SMauro Carvalho Chehab 50639a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5); 50649a0bf528SMauro Carvalho Chehab if (status < 0) 50659a0bf528SMauro Carvalho Chehab goto error; 50669a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4); 50679a0bf528SMauro Carvalho Chehab if (status < 0) 50689a0bf528SMauro Carvalho Chehab goto error; 50699a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3); 50709a0bf528SMauro Carvalho Chehab if (status < 0) 50719a0bf528SMauro Carvalho Chehab goto error; 50729a0bf528SMauro Carvalho Chehab 50739a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */ 50749a0bf528SMauro Carvalho Chehab 5075ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 5076ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM256); 50779a0bf528SMauro Carvalho Chehab if (status < 0) 50789a0bf528SMauro Carvalho Chehab goto error; 50799a0bf528SMauro Carvalho Chehab 50809a0bf528SMauro Carvalho Chehab 50819a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */ 50829a0bf528SMauro Carvalho Chehab 50839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 50849a0bf528SMauro Carvalho Chehab if (status < 0) 50859a0bf528SMauro Carvalho Chehab goto error; 50869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 50879a0bf528SMauro Carvalho Chehab if (status < 0) 50889a0bf528SMauro Carvalho Chehab goto error; 50899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 50909a0bf528SMauro Carvalho Chehab if (status < 0) 50919a0bf528SMauro Carvalho Chehab goto error; 50929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 50939a0bf528SMauro Carvalho Chehab if (status < 0) 50949a0bf528SMauro Carvalho Chehab goto error; 50959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 50969a0bf528SMauro Carvalho Chehab if (status < 0) 50979a0bf528SMauro Carvalho Chehab goto error; 50989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 50999a0bf528SMauro Carvalho Chehab if (status < 0) 51009a0bf528SMauro Carvalho Chehab goto error; 51019a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 51029a0bf528SMauro Carvalho Chehab if (status < 0) 51039a0bf528SMauro Carvalho Chehab goto error; 51049a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 51059a0bf528SMauro Carvalho Chehab if (status < 0) 51069a0bf528SMauro Carvalho Chehab goto error; 51079a0bf528SMauro Carvalho Chehab 51089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 51099a0bf528SMauro Carvalho Chehab if (status < 0) 51109a0bf528SMauro Carvalho Chehab goto error; 51119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50); 51129a0bf528SMauro Carvalho Chehab if (status < 0) 51139a0bf528SMauro Carvalho Chehab goto error; 51149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250); 51159a0bf528SMauro Carvalho Chehab if (status < 0) 51169a0bf528SMauro Carvalho Chehab goto error; 51179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 51189a0bf528SMauro Carvalho Chehab if (status < 0) 51199a0bf528SMauro Carvalho Chehab goto error; 51209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50); 51219a0bf528SMauro Carvalho Chehab if (status < 0) 51229a0bf528SMauro Carvalho Chehab goto error; 51239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125); 51249a0bf528SMauro Carvalho Chehab if (status < 0) 51259a0bf528SMauro Carvalho Chehab goto error; 51269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 51279a0bf528SMauro Carvalho Chehab if (status < 0) 51289a0bf528SMauro Carvalho Chehab goto error; 51299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 51309a0bf528SMauro Carvalho Chehab if (status < 0) 51319a0bf528SMauro Carvalho Chehab goto error; 51329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 51339a0bf528SMauro Carvalho Chehab if (status < 0) 51349a0bf528SMauro Carvalho Chehab goto error; 51359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 51369a0bf528SMauro Carvalho Chehab if (status < 0) 51379a0bf528SMauro Carvalho Chehab goto error; 51389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 51399a0bf528SMauro Carvalho Chehab if (status < 0) 51409a0bf528SMauro Carvalho Chehab goto error; 51419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 51429a0bf528SMauro Carvalho Chehab if (status < 0) 51439a0bf528SMauro Carvalho Chehab goto error; 51449a0bf528SMauro Carvalho Chehab 51459a0bf528SMauro Carvalho Chehab 51469a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */ 51479a0bf528SMauro Carvalho Chehab 51489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 51499a0bf528SMauro Carvalho Chehab if (status < 0) 51509a0bf528SMauro Carvalho Chehab goto error; 51519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 51529a0bf528SMauro Carvalho Chehab if (status < 0) 51539a0bf528SMauro Carvalho Chehab goto error; 51549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 51559a0bf528SMauro Carvalho Chehab if (status < 0) 51569a0bf528SMauro Carvalho Chehab goto error; 51579a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 51589a0bf528SMauro Carvalho Chehab if (status < 0) 51599a0bf528SMauro Carvalho Chehab goto error; 51609a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150); 51619a0bf528SMauro Carvalho Chehab if (status < 0) 51629a0bf528SMauro Carvalho Chehab goto error; 51639a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110); 51649a0bf528SMauro Carvalho Chehab if (status < 0) 51659a0bf528SMauro Carvalho Chehab goto error; 51669a0bf528SMauro Carvalho Chehab 51679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 51689a0bf528SMauro Carvalho Chehab if (status < 0) 51699a0bf528SMauro Carvalho Chehab goto error; 51709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 51719a0bf528SMauro Carvalho Chehab if (status < 0) 51729a0bf528SMauro Carvalho Chehab goto error; 51739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 51749a0bf528SMauro Carvalho Chehab if (status < 0) 51759a0bf528SMauro Carvalho Chehab goto error; 51769a0bf528SMauro Carvalho Chehab 51779a0bf528SMauro Carvalho Chehab 51789a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */ 51799a0bf528SMauro Carvalho Chehab 51809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 51819a0bf528SMauro Carvalho Chehab if (status < 0) 51829a0bf528SMauro Carvalho Chehab goto error; 51839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74); 51849a0bf528SMauro Carvalho Chehab if (status < 0) 51859a0bf528SMauro Carvalho Chehab goto error; 51869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18); 51879a0bf528SMauro Carvalho Chehab if (status < 0) 51889a0bf528SMauro Carvalho Chehab goto error; 51899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13); 51909a0bf528SMauro Carvalho Chehab if (status < 0) 51919a0bf528SMauro Carvalho Chehab goto error; 51929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7); 51939a0bf528SMauro Carvalho Chehab if (status < 0) 51949a0bf528SMauro Carvalho Chehab goto error; 51959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0); 51969a0bf528SMauro Carvalho Chehab if (status < 0) 51979a0bf528SMauro Carvalho Chehab goto error; 51989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8); 51999a0bf528SMauro Carvalho Chehab error: 52009a0bf528SMauro Carvalho Chehab if (status < 0) 52013a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 52029a0bf528SMauro Carvalho Chehab return status; 52039a0bf528SMauro Carvalho Chehab } 52049a0bf528SMauro Carvalho Chehab 52059a0bf528SMauro Carvalho Chehab 52069a0bf528SMauro Carvalho Chehab /*============================================================================*/ 520734eb9751SMauro Carvalho Chehab /* 52089a0bf528SMauro Carvalho Chehab * \brief Reset QAM block. 52099a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 52109a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 52119a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 52129a0bf528SMauro Carvalho Chehab */ 5213cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state) 52149a0bf528SMauro Carvalho Chehab { 52159a0bf528SMauro Carvalho Chehab int status; 5216cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 52179a0bf528SMauro Carvalho Chehab 52189a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 52199a0bf528SMauro Carvalho Chehab /* Stop QAM comstate->m_exec */ 52209a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 52219a0bf528SMauro Carvalho Chehab if (status < 0) 52229a0bf528SMauro Carvalho Chehab goto error; 52239a0bf528SMauro Carvalho Chehab 5224ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 5225ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 5226ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 52279a0bf528SMauro Carvalho Chehab error: 52289a0bf528SMauro Carvalho Chehab if (status < 0) 52293a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 52309a0bf528SMauro Carvalho Chehab return status; 52319a0bf528SMauro Carvalho Chehab } 52329a0bf528SMauro Carvalho Chehab 52339a0bf528SMauro Carvalho Chehab /*============================================================================*/ 52349a0bf528SMauro Carvalho Chehab 523534eb9751SMauro Carvalho Chehab /* 52369a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate. 52379a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 52389a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 52399a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 52409a0bf528SMauro Carvalho Chehab */ 5241cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state) 52429a0bf528SMauro Carvalho Chehab { 5243cd7a67a4SMauro Carvalho Chehab u32 adc_frequency = 0; 5244cd7a67a4SMauro Carvalho Chehab u32 symb_freq = 0; 5245cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate = 0; 52469a0bf528SMauro Carvalho Chehab u16 ratesel = 0; 5247cd7a67a4SMauro Carvalho Chehab u32 lc_symb_rate = 0; 52489a0bf528SMauro Carvalho Chehab int status; 52499a0bf528SMauro Carvalho Chehab 52509a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 52519a0bf528SMauro Carvalho Chehab /* Select & calculate correct IQM rate */ 5252cd7a67a4SMauro Carvalho Chehab adc_frequency = (state->m_sys_clock_freq * 1000) / 3; 52539a0bf528SMauro Carvalho Chehab ratesel = 0; 52549a0bf528SMauro Carvalho Chehab if (state->props.symbol_rate <= 1188750) 52559a0bf528SMauro Carvalho Chehab ratesel = 3; 52569a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 2377500) 52579a0bf528SMauro Carvalho Chehab ratesel = 2; 52589a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 4755000) 52599a0bf528SMauro Carvalho Chehab ratesel = 1; 52609a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FD_RATESEL__A, ratesel); 52619a0bf528SMauro Carvalho Chehab if (status < 0) 52629a0bf528SMauro Carvalho Chehab goto error; 52639a0bf528SMauro Carvalho Chehab 52649a0bf528SMauro Carvalho Chehab /* 52659a0bf528SMauro Carvalho Chehab IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23) 52669a0bf528SMauro Carvalho Chehab */ 5267cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate * (1 << ratesel); 5268cd7a67a4SMauro Carvalho Chehab if (symb_freq == 0) { 52699a0bf528SMauro Carvalho Chehab /* Divide by zero */ 52709a0bf528SMauro Carvalho Chehab status = -EINVAL; 52719a0bf528SMauro Carvalho Chehab goto error; 52729a0bf528SMauro Carvalho Chehab } 5273cd7a67a4SMauro Carvalho Chehab iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) + 5274cd7a67a4SMauro Carvalho Chehab (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) - 52759a0bf528SMauro Carvalho Chehab (1 << 23); 5276cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate); 52779a0bf528SMauro Carvalho Chehab if (status < 0) 52789a0bf528SMauro Carvalho Chehab goto error; 5279cd7a67a4SMauro Carvalho Chehab state->m_iqm_rc_rate = iqm_rc_rate; 52809a0bf528SMauro Carvalho Chehab /* 5281cd7a67a4SMauro Carvalho Chehab LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15)) 52829a0bf528SMauro Carvalho Chehab */ 5283cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate; 5284cd7a67a4SMauro Carvalho Chehab if (adc_frequency == 0) { 52859a0bf528SMauro Carvalho Chehab /* Divide by zero */ 52869a0bf528SMauro Carvalho Chehab status = -EINVAL; 52879a0bf528SMauro Carvalho Chehab goto error; 52889a0bf528SMauro Carvalho Chehab } 5289cd7a67a4SMauro Carvalho Chehab lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) + 5290cd7a67a4SMauro Carvalho Chehab (Frac28a((symb_freq % adc_frequency), adc_frequency) >> 52919a0bf528SMauro Carvalho Chehab 16); 5292cd7a67a4SMauro Carvalho Chehab if (lc_symb_rate > 511) 5293cd7a67a4SMauro Carvalho Chehab lc_symb_rate = 511; 5294cd7a67a4SMauro Carvalho Chehab status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate); 52959a0bf528SMauro Carvalho Chehab 52969a0bf528SMauro Carvalho Chehab error: 52979a0bf528SMauro Carvalho Chehab if (status < 0) 52983a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 52999a0bf528SMauro Carvalho Chehab return status; 53009a0bf528SMauro Carvalho Chehab } 53019a0bf528SMauro Carvalho Chehab 53029a0bf528SMauro Carvalho Chehab /*============================================================================*/ 53039a0bf528SMauro Carvalho Chehab 530434eb9751SMauro Carvalho Chehab /* 53059a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status. 53069a0bf528SMauro Carvalho Chehab * \param demod: instance of demod. 53079a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data. 53089a0bf528SMauro Carvalho Chehab * \return DRXStatus_t. 53099a0bf528SMauro Carvalho Chehab */ 53109a0bf528SMauro Carvalho Chehab 5311cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) 53129a0bf528SMauro Carvalho Chehab { 53139a0bf528SMauro Carvalho Chehab int status; 5314cd7a67a4SMauro Carvalho Chehab u16 result[2] = { 0, 0 }; 53159a0bf528SMauro Carvalho Chehab 53169a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5317cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED; 53189a0bf528SMauro Carvalho Chehab status = scu_command(state, 53199a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM | 53209a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, 5321cd7a67a4SMauro Carvalho Chehab result); 53229a0bf528SMauro Carvalho Chehab if (status < 0) 53233a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 53249a0bf528SMauro Carvalho Chehab 5325cd7a67a4SMauro Carvalho Chehab if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { 53269a0bf528SMauro Carvalho Chehab /* 0x0000 NOT LOCKED */ 5327cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { 53289a0bf528SMauro Carvalho Chehab /* 0x4000 DEMOD LOCKED */ 5329cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK; 5330cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { 53319a0bf528SMauro Carvalho Chehab /* 0x8000 DEMOD + FEC LOCKED (system lock) */ 5332cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK; 53339a0bf528SMauro Carvalho Chehab } else { 53349a0bf528SMauro Carvalho Chehab /* 0xC000 NEVER LOCKED */ 53359a0bf528SMauro Carvalho Chehab /* (system will never be able to lock to the signal) */ 5336ab5060cdSMauro Carvalho Chehab /* 5337ab5060cdSMauro Carvalho Chehab * TODO: check this, intermediate & standard specific lock 5338ab5060cdSMauro Carvalho Chehab * states are not taken into account here 5339ab5060cdSMauro Carvalho Chehab */ 5340cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK; 53419a0bf528SMauro Carvalho Chehab } 53429a0bf528SMauro Carvalho Chehab return status; 53439a0bf528SMauro Carvalho Chehab } 53449a0bf528SMauro Carvalho Chehab 53459a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M 0x03 53469a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL 0x00 53479a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED 0x01 53489a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON 0x02 53499a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M 0x10 53509a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL 0x10 53519a0bf528SMauro Carvalho Chehab 5352cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state, 5353cd7a67a4SMauro Carvalho Chehab int number_of_parameters) 53549a0bf528SMauro Carvalho Chehab { 53559a0bf528SMauro Carvalho Chehab int status; 5356cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 5357cd7a67a4SMauro Carvalho Chehab u16 set_param_parameters[4] = { 0, 0, 0, 0 }; 53589a0bf528SMauro Carvalho Chehab 5359cd7a67a4SMauro Carvalho Chehab set_param_parameters[0] = state->m_constellation; /* modulation */ 5360cd7a67a4SMauro Carvalho Chehab set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ 53619a0bf528SMauro Carvalho Chehab 5362cd7a67a4SMauro Carvalho Chehab if (number_of_parameters == 2) { 5363cd7a67a4SMauro Carvalho Chehab u16 set_env_parameters[1] = { 0 }; 53649a0bf528SMauro Carvalho Chehab 5365cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C) 5366cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_C; 53679a0bf528SMauro Carvalho Chehab else 5368cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_A; 53699a0bf528SMauro Carvalho Chehab 53709a0bf528SMauro Carvalho Chehab status = scu_command(state, 5371ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5372ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 5373cd7a67a4SMauro Carvalho Chehab 1, set_env_parameters, 1, &cmd_result); 53749a0bf528SMauro Carvalho Chehab if (status < 0) 53759a0bf528SMauro Carvalho Chehab goto error; 53769a0bf528SMauro Carvalho Chehab 53779a0bf528SMauro Carvalho Chehab status = scu_command(state, 5378ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5379ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 5380cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters, 5381cd7a67a4SMauro Carvalho Chehab 1, &cmd_result); 5382cd7a67a4SMauro Carvalho Chehab } else if (number_of_parameters == 4) { 5383cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C) 5384cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_C; 53859a0bf528SMauro Carvalho Chehab else 5386cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_A; 53879a0bf528SMauro Carvalho Chehab 5388cd7a67a4SMauro Carvalho Chehab set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON); 53899a0bf528SMauro Carvalho Chehab /* Env parameters */ 5390868c9a17SMauro Carvalho Chehab /* check for LOCKRANGE Extended */ 5391cd7a67a4SMauro Carvalho Chehab /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */ 53929a0bf528SMauro Carvalho Chehab 53939a0bf528SMauro Carvalho Chehab status = scu_command(state, 5394ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM 5395ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 5396cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters, 5397cd7a67a4SMauro Carvalho Chehab 1, &cmd_result); 53989a0bf528SMauro Carvalho Chehab } else { 53993a4398f5SMauro Carvalho Chehab pr_warn("Unknown QAM demodulator parameter count %d\n", 54003a4398f5SMauro Carvalho Chehab number_of_parameters); 540194af1b63SMauro Carvalho Chehab status = -EINVAL; 54029a0bf528SMauro Carvalho Chehab } 54039a0bf528SMauro Carvalho Chehab 54049a0bf528SMauro Carvalho Chehab error: 54059a0bf528SMauro Carvalho Chehab if (status < 0) 54063a4398f5SMauro Carvalho Chehab pr_warn("Warning %d on %s\n", status, __func__); 54079a0bf528SMauro Carvalho Chehab return status; 54089a0bf528SMauro Carvalho Chehab } 54099a0bf528SMauro Carvalho Chehab 5410cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 5411cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset) 54129a0bf528SMauro Carvalho Chehab { 54139a0bf528SMauro Carvalho Chehab int status; 5414cd7a67a4SMauro Carvalho Chehab u16 cmd_result; 5415cd7a67a4SMauro Carvalho Chehab int qam_demod_param_count = state->qam_demod_parameter_count; 54169a0bf528SMauro Carvalho Chehab 54179a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 54189a0bf528SMauro Carvalho Chehab /* 54199a0bf528SMauro Carvalho Chehab * STEP 1: reset demodulator 54209a0bf528SMauro Carvalho Chehab * resets FEC DI and FEC RS 54219a0bf528SMauro Carvalho Chehab * resets QAM block 54229a0bf528SMauro Carvalho Chehab * resets SCU variables 54239a0bf528SMauro Carvalho Chehab */ 54249a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP); 54259a0bf528SMauro Carvalho Chehab if (status < 0) 54269a0bf528SMauro Carvalho Chehab goto error; 54279a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP); 54289a0bf528SMauro Carvalho Chehab if (status < 0) 54299a0bf528SMauro Carvalho Chehab goto error; 5430cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state); 54319a0bf528SMauro Carvalho Chehab if (status < 0) 54329a0bf528SMauro Carvalho Chehab goto error; 54339a0bf528SMauro Carvalho Chehab 54349a0bf528SMauro Carvalho Chehab /* 54359a0bf528SMauro Carvalho Chehab * STEP 2: configure demodulator 54369a0bf528SMauro Carvalho Chehab * -set params; resets IQM,QAM,FEC HW; initializes some 54379a0bf528SMauro Carvalho Chehab * SCU variables 54389a0bf528SMauro Carvalho Chehab */ 5439cd7a67a4SMauro Carvalho Chehab status = qam_set_symbolrate(state); 54409a0bf528SMauro Carvalho Chehab if (status < 0) 54419a0bf528SMauro Carvalho Chehab goto error; 54429a0bf528SMauro Carvalho Chehab 54439a0bf528SMauro Carvalho Chehab /* Set params */ 54449a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 54459a0bf528SMauro Carvalho Chehab case QAM_256: 5446cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM256; 54479a0bf528SMauro Carvalho Chehab break; 54489a0bf528SMauro Carvalho Chehab case QAM_AUTO: 54499a0bf528SMauro Carvalho Chehab case QAM_64: 5450cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM64; 54519a0bf528SMauro Carvalho Chehab break; 54529a0bf528SMauro Carvalho Chehab case QAM_16: 5453cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM16; 54549a0bf528SMauro Carvalho Chehab break; 54559a0bf528SMauro Carvalho Chehab case QAM_32: 5456cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM32; 54579a0bf528SMauro Carvalho Chehab break; 54589a0bf528SMauro Carvalho Chehab case QAM_128: 5459cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM128; 54609a0bf528SMauro Carvalho Chehab break; 54619a0bf528SMauro Carvalho Chehab default: 54629a0bf528SMauro Carvalho Chehab status = -EINVAL; 54639a0bf528SMauro Carvalho Chehab break; 54649a0bf528SMauro Carvalho Chehab } 54659a0bf528SMauro Carvalho Chehab if (status < 0) 54669a0bf528SMauro Carvalho Chehab goto error; 54679a0bf528SMauro Carvalho Chehab 54689a0bf528SMauro Carvalho Chehab /* Use the 4-parameter if it's requested or we're probing for 54699a0bf528SMauro Carvalho Chehab * the correct command. */ 54709a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 4 54719a0bf528SMauro Carvalho Chehab || !state->qam_demod_parameter_count) { 5472cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 4; 5473cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count); 54749a0bf528SMauro Carvalho Chehab } 54759a0bf528SMauro Carvalho Chehab 54769a0bf528SMauro Carvalho Chehab /* Use the 2-parameter command if it was requested or if we're 54779a0bf528SMauro Carvalho Chehab * probing for the correct command and the 4-parameter command 54789a0bf528SMauro Carvalho Chehab * failed. */ 54799a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 2 54809a0bf528SMauro Carvalho Chehab || (!state->qam_demod_parameter_count && status < 0)) { 5481cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 2; 5482cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count); 54839a0bf528SMauro Carvalho Chehab } 54849a0bf528SMauro Carvalho Chehab 54859a0bf528SMauro Carvalho Chehab if (status < 0) { 54860fb220f2SMauro Carvalho Chehab dprintk(1, "Could not set demodulator parameters.\n"); 54870fb220f2SMauro Carvalho Chehab dprintk(1, 54880fb220f2SMauro Carvalho Chehab "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n", 54899a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count, 54909a0bf528SMauro Carvalho Chehab state->microcode_name); 54919a0bf528SMauro Carvalho Chehab goto error; 54929a0bf528SMauro Carvalho Chehab } else if (!state->qam_demod_parameter_count) { 54930fb220f2SMauro Carvalho Chehab dprintk(1, 54940fb220f2SMauro Carvalho Chehab "Auto-probing the QAM command parameters was successful - using %d parameters.\n", 5495cd7a67a4SMauro Carvalho Chehab qam_demod_param_count); 54969a0bf528SMauro Carvalho Chehab 54979a0bf528SMauro Carvalho Chehab /* 54989a0bf528SMauro Carvalho Chehab * One of our commands was successful. We don't need to 54999a0bf528SMauro Carvalho Chehab * auto-probe anymore, now that we got the correct command. 55009a0bf528SMauro Carvalho Chehab */ 5501cd7a67a4SMauro Carvalho Chehab state->qam_demod_parameter_count = qam_demod_param_count; 55029a0bf528SMauro Carvalho Chehab } 55039a0bf528SMauro Carvalho Chehab 55049a0bf528SMauro Carvalho Chehab /* 55059a0bf528SMauro Carvalho Chehab * STEP 3: enable the system in a mode where the ADC provides valid 55069a0bf528SMauro Carvalho Chehab * signal setup modulation independent registers 55079a0bf528SMauro Carvalho Chehab */ 55089a0bf528SMauro Carvalho Chehab #if 0 5509cd7a67a4SMauro Carvalho Chehab status = set_frequency(channel, tuner_freq_offset)); 55109a0bf528SMauro Carvalho Chehab if (status < 0) 55119a0bf528SMauro Carvalho Chehab goto error; 55129a0bf528SMauro Carvalho Chehab #endif 5513ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz, 5514ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true); 55159a0bf528SMauro Carvalho Chehab if (status < 0) 55169a0bf528SMauro Carvalho Chehab goto error; 55179a0bf528SMauro Carvalho Chehab 55189a0bf528SMauro Carvalho Chehab /* Setup BER measurement */ 5519ab5060cdSMauro Carvalho Chehab status = set_qam_measurement(state, state->m_constellation, 5520ab5060cdSMauro Carvalho Chehab state->props.symbol_rate); 55219a0bf528SMauro Carvalho Chehab if (status < 0) 55229a0bf528SMauro Carvalho Chehab goto error; 55239a0bf528SMauro Carvalho Chehab 55249a0bf528SMauro Carvalho Chehab /* Reset default values */ 55259a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); 55269a0bf528SMauro Carvalho Chehab if (status < 0) 55279a0bf528SMauro Carvalho Chehab goto error; 55289a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); 55299a0bf528SMauro Carvalho Chehab if (status < 0) 55309a0bf528SMauro Carvalho Chehab goto error; 55319a0bf528SMauro Carvalho Chehab 55329a0bf528SMauro Carvalho Chehab /* Reset default LC values */ 55339a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_RATE_LIMIT__A, 3); 55349a0bf528SMauro Carvalho Chehab if (status < 0) 55359a0bf528SMauro Carvalho Chehab goto error; 55369a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORP__A, 4); 55379a0bf528SMauro Carvalho Chehab if (status < 0) 55389a0bf528SMauro Carvalho Chehab goto error; 55399a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORI__A, 4); 55409a0bf528SMauro Carvalho Chehab if (status < 0) 55419a0bf528SMauro Carvalho Chehab goto error; 55429a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_MODE__A, 7); 55439a0bf528SMauro Carvalho Chehab if (status < 0) 55449a0bf528SMauro Carvalho Chehab goto error; 55459a0bf528SMauro Carvalho Chehab 55469a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB0__A, 1); 55479a0bf528SMauro Carvalho Chehab if (status < 0) 55489a0bf528SMauro Carvalho Chehab goto error; 55499a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB1__A, 1); 55509a0bf528SMauro Carvalho Chehab if (status < 0) 55519a0bf528SMauro Carvalho Chehab goto error; 55529a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB2__A, 1); 55539a0bf528SMauro Carvalho Chehab if (status < 0) 55549a0bf528SMauro Carvalho Chehab goto error; 55559a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB3__A, 1); 55569a0bf528SMauro Carvalho Chehab if (status < 0) 55579a0bf528SMauro Carvalho Chehab goto error; 55589a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB4__A, 2); 55599a0bf528SMauro Carvalho Chehab if (status < 0) 55609a0bf528SMauro Carvalho Chehab goto error; 55619a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB5__A, 2); 55629a0bf528SMauro Carvalho Chehab if (status < 0) 55639a0bf528SMauro Carvalho Chehab goto error; 55649a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB6__A, 2); 55659a0bf528SMauro Carvalho Chehab if (status < 0) 55669a0bf528SMauro Carvalho Chehab goto error; 55679a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB8__A, 2); 55689a0bf528SMauro Carvalho Chehab if (status < 0) 55699a0bf528SMauro Carvalho Chehab goto error; 55709a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB9__A, 2); 55719a0bf528SMauro Carvalho Chehab if (status < 0) 55729a0bf528SMauro Carvalho Chehab goto error; 55739a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB10__A, 2); 55749a0bf528SMauro Carvalho Chehab if (status < 0) 55759a0bf528SMauro Carvalho Chehab goto error; 55769a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB12__A, 2); 55779a0bf528SMauro Carvalho Chehab if (status < 0) 55789a0bf528SMauro Carvalho Chehab goto error; 55799a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB15__A, 3); 55809a0bf528SMauro Carvalho Chehab if (status < 0) 55819a0bf528SMauro Carvalho Chehab goto error; 55829a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB16__A, 3); 55839a0bf528SMauro Carvalho Chehab if (status < 0) 55849a0bf528SMauro Carvalho Chehab goto error; 55859a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB20__A, 4); 55869a0bf528SMauro Carvalho Chehab if (status < 0) 55879a0bf528SMauro Carvalho Chehab goto error; 55889a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB25__A, 4); 55899a0bf528SMauro Carvalho Chehab if (status < 0) 55909a0bf528SMauro Carvalho Chehab goto error; 55919a0bf528SMauro Carvalho Chehab 55929a0bf528SMauro Carvalho Chehab /* Mirroring, QAM-block starting point not inverted */ 5593ab5060cdSMauro Carvalho Chehab status = write16(state, QAM_SY_SP_INV__A, 5594ab5060cdSMauro Carvalho Chehab QAM_SY_SP_INV_SPECTRUM_INV_DIS); 55959a0bf528SMauro Carvalho Chehab if (status < 0) 55969a0bf528SMauro Carvalho Chehab goto error; 55979a0bf528SMauro Carvalho Chehab 55989a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 55999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 56009a0bf528SMauro Carvalho Chehab if (status < 0) 56019a0bf528SMauro Carvalho Chehab goto error; 56029a0bf528SMauro Carvalho Chehab 56039a0bf528SMauro Carvalho Chehab /* STEP 4: modulation specific setup */ 56049a0bf528SMauro Carvalho Chehab switch (state->props.modulation) { 56059a0bf528SMauro Carvalho Chehab case QAM_16: 5606cd7a67a4SMauro Carvalho Chehab status = set_qam16(state); 56079a0bf528SMauro Carvalho Chehab break; 56089a0bf528SMauro Carvalho Chehab case QAM_32: 5609cd7a67a4SMauro Carvalho Chehab status = set_qam32(state); 56109a0bf528SMauro Carvalho Chehab break; 56119a0bf528SMauro Carvalho Chehab case QAM_AUTO: 56129a0bf528SMauro Carvalho Chehab case QAM_64: 5613cd7a67a4SMauro Carvalho Chehab status = set_qam64(state); 56149a0bf528SMauro Carvalho Chehab break; 56159a0bf528SMauro Carvalho Chehab case QAM_128: 5616cd7a67a4SMauro Carvalho Chehab status = set_qam128(state); 56179a0bf528SMauro Carvalho Chehab break; 56189a0bf528SMauro Carvalho Chehab case QAM_256: 5619cd7a67a4SMauro Carvalho Chehab status = set_qam256(state); 56209a0bf528SMauro Carvalho Chehab break; 56219a0bf528SMauro Carvalho Chehab default: 56229a0bf528SMauro Carvalho Chehab status = -EINVAL; 56239a0bf528SMauro Carvalho Chehab break; 56249a0bf528SMauro Carvalho Chehab } 56259a0bf528SMauro Carvalho Chehab if (status < 0) 56269a0bf528SMauro Carvalho Chehab goto error; 56279a0bf528SMauro Carvalho Chehab 56289a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 56299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 56309a0bf528SMauro Carvalho Chehab if (status < 0) 56319a0bf528SMauro Carvalho Chehab goto error; 56329a0bf528SMauro Carvalho Chehab 56339a0bf528SMauro Carvalho Chehab /* Re-configure MPEG output, requires knowledge of channel bitrate */ 56349a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.modulation = channel->modulation; */ 56359a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ 5636cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, state->m_operation_mode); 56379a0bf528SMauro Carvalho Chehab if (status < 0) 56389a0bf528SMauro Carvalho Chehab goto error; 56399a0bf528SMauro Carvalho Chehab 5640cd7a67a4SMauro Carvalho Chehab /* start processes */ 5641cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state); 56429a0bf528SMauro Carvalho Chehab if (status < 0) 56439a0bf528SMauro Carvalho Chehab goto error; 56449a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 56459a0bf528SMauro Carvalho Chehab if (status < 0) 56469a0bf528SMauro Carvalho Chehab goto error; 56479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE); 56489a0bf528SMauro Carvalho Chehab if (status < 0) 56499a0bf528SMauro Carvalho Chehab goto error; 56509a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 56519a0bf528SMauro Carvalho Chehab if (status < 0) 56529a0bf528SMauro Carvalho Chehab goto error; 56539a0bf528SMauro Carvalho Chehab 56549a0bf528SMauro Carvalho Chehab /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */ 5655ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 5656ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START, 5657ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result); 56589a0bf528SMauro Carvalho Chehab if (status < 0) 56599a0bf528SMauro Carvalho Chehab goto error; 56609a0bf528SMauro Carvalho Chehab 56619a0bf528SMauro Carvalho Chehab /* update global DRXK data container */ 56629a0bf528SMauro Carvalho Chehab /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */ 56639a0bf528SMauro Carvalho Chehab 56649a0bf528SMauro Carvalho Chehab error: 56659a0bf528SMauro Carvalho Chehab if (status < 0) 56663a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 56679a0bf528SMauro Carvalho Chehab return status; 56689a0bf528SMauro Carvalho Chehab } 56699a0bf528SMauro Carvalho Chehab 5670cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state, 5671cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode) 56729a0bf528SMauro Carvalho Chehab { 56739a0bf528SMauro Carvalho Chehab int status; 56749a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS 56759a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT 56769a0bf528SMauro Carvalho Chehab #include "drxk_filters.h" 56779a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT 56789a0bf528SMauro Carvalho Chehab #endif 56799a0bf528SMauro Carvalho Chehab 56809a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 56819a0bf528SMauro Carvalho Chehab 56829a0bf528SMauro Carvalho Chehab /* added antenna switch */ 5683cd7a67a4SMauro Carvalho Chehab switch_antenna_to_qam(state); 56849a0bf528SMauro Carvalho Chehab 56859a0bf528SMauro Carvalho Chehab /* Ensure correct power-up mode */ 5686cd7a67a4SMauro Carvalho Chehab status = power_up_qam(state); 56879a0bf528SMauro Carvalho Chehab if (status < 0) 56889a0bf528SMauro Carvalho Chehab goto error; 56899a0bf528SMauro Carvalho Chehab /* Reset QAM block */ 5690cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state); 56919a0bf528SMauro Carvalho Chehab if (status < 0) 56929a0bf528SMauro Carvalho Chehab goto error; 56939a0bf528SMauro Carvalho Chehab 56949a0bf528SMauro Carvalho Chehab /* Setup IQM */ 56959a0bf528SMauro Carvalho Chehab 56969a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 56979a0bf528SMauro Carvalho Chehab if (status < 0) 56989a0bf528SMauro Carvalho Chehab goto error; 56999a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 57009a0bf528SMauro Carvalho Chehab if (status < 0) 57019a0bf528SMauro Carvalho Chehab goto error; 57029a0bf528SMauro Carvalho Chehab 57039a0bf528SMauro Carvalho Chehab /* Upload IQM Channel Filter settings by 57049a0bf528SMauro Carvalho Chehab boot loader from ROM table */ 5705cd7a67a4SMauro Carvalho Chehab switch (o_mode) { 57069a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A: 5707ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, 5708ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS, 5709ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57109a0bf528SMauro Carvalho Chehab break; 57119a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C: 5712ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, 5713ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 5714ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS, 5715ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57169a0bf528SMauro Carvalho Chehab if (status < 0) 57179a0bf528SMauro Carvalho Chehab goto error; 5718ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state, 5719ab5060cdSMauro Carvalho Chehab IQM_CF_TAP_IM0__A, 5720ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 5721ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS, 5722ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT); 57239a0bf528SMauro Carvalho Chehab break; 57249a0bf528SMauro Carvalho Chehab default: 57259a0bf528SMauro Carvalho Chehab status = -EINVAL; 57269a0bf528SMauro Carvalho Chehab } 57279a0bf528SMauro Carvalho Chehab if (status < 0) 57289a0bf528SMauro Carvalho Chehab goto error; 57299a0bf528SMauro Carvalho Chehab 5730ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B); 57319a0bf528SMauro Carvalho Chehab if (status < 0) 57329a0bf528SMauro Carvalho Chehab goto error; 57339a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SYMMETRIC__A, 0); 57349a0bf528SMauro Carvalho Chehab if (status < 0) 57359a0bf528SMauro Carvalho Chehab goto error; 5736ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_MIDTAP__A, 5737ab5060cdSMauro Carvalho Chehab ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); 57389a0bf528SMauro Carvalho Chehab if (status < 0) 57399a0bf528SMauro Carvalho Chehab goto error; 57409a0bf528SMauro Carvalho Chehab 57419a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 21); 57429a0bf528SMauro Carvalho Chehab if (status < 0) 57439a0bf528SMauro Carvalho Chehab goto error; 57449a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0); 57459a0bf528SMauro Carvalho Chehab if (status < 0) 57469a0bf528SMauro Carvalho Chehab goto error; 57479a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448); 57489a0bf528SMauro Carvalho Chehab if (status < 0) 57499a0bf528SMauro Carvalho Chehab goto error; 57509a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0); 57519a0bf528SMauro Carvalho Chehab if (status < 0) 57529a0bf528SMauro Carvalho Chehab goto error; 57539a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0); 57549a0bf528SMauro Carvalho Chehab if (status < 0) 57559a0bf528SMauro Carvalho Chehab goto error; 57569a0bf528SMauro Carvalho Chehab 57579a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FS_ADJ_SEL__A, 1); 57589a0bf528SMauro Carvalho Chehab if (status < 0) 57599a0bf528SMauro Carvalho Chehab goto error; 57609a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_ADJ_SEL__A, 1); 57619a0bf528SMauro Carvalho Chehab if (status < 0) 57629a0bf528SMauro Carvalho Chehab goto error; 57639a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_ADJ_SEL__A, 1); 57649a0bf528SMauro Carvalho Chehab if (status < 0) 57659a0bf528SMauro Carvalho Chehab goto error; 57669a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 0); 57679a0bf528SMauro Carvalho Chehab if (status < 0) 57689a0bf528SMauro Carvalho Chehab goto error; 57699a0bf528SMauro Carvalho Chehab 57709a0bf528SMauro Carvalho Chehab /* IQM Impulse Noise Processing Unit */ 57719a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_CLP_VAL__A, 500); 57729a0bf528SMauro Carvalho Chehab if (status < 0) 57739a0bf528SMauro Carvalho Chehab goto error; 57749a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 1000); 57759a0bf528SMauro Carvalho Chehab if (status < 0) 57769a0bf528SMauro Carvalho Chehab goto error; 57779a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1); 57789a0bf528SMauro Carvalho Chehab if (status < 0) 57799a0bf528SMauro Carvalho Chehab goto error; 57809a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0); 57819a0bf528SMauro Carvalho Chehab if (status < 0) 57829a0bf528SMauro Carvalho Chehab goto error; 57839a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 1); 57849a0bf528SMauro Carvalho Chehab if (status < 0) 57859a0bf528SMauro Carvalho Chehab goto error; 57869a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 1); 57879a0bf528SMauro Carvalho Chehab if (status < 0) 57889a0bf528SMauro Carvalho Chehab goto error; 57899a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_BYPASS__A, 1); 57909a0bf528SMauro Carvalho Chehab if (status < 0) 57919a0bf528SMauro Carvalho Chehab goto error; 57929a0bf528SMauro Carvalho Chehab 57939a0bf528SMauro Carvalho Chehab /* turn on IQMAF. Must be done before setAgc**() */ 5794cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true); 57959a0bf528SMauro Carvalho Chehab if (status < 0) 57969a0bf528SMauro Carvalho Chehab goto error; 57979a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 0x01); 57989a0bf528SMauro Carvalho Chehab if (status < 0) 57999a0bf528SMauro Carvalho Chehab goto error; 58009a0bf528SMauro Carvalho Chehab 58019a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */ 5802cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state); 58039a0bf528SMauro Carvalho Chehab if (status < 0) 58049a0bf528SMauro Carvalho Chehab goto error; 58059a0bf528SMauro Carvalho Chehab 58069a0bf528SMauro Carvalho Chehab /* Set the FSM step period */ 58079a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000); 58089a0bf528SMauro Carvalho Chehab if (status < 0) 58099a0bf528SMauro Carvalho Chehab goto error; 58109a0bf528SMauro Carvalho Chehab 58119a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */ 58129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 58139a0bf528SMauro Carvalho Chehab if (status < 0) 58149a0bf528SMauro Carvalho Chehab goto error; 58159a0bf528SMauro Carvalho Chehab 58169a0bf528SMauro Carvalho Chehab /* No more resets of the IQM, current standard correctly set => 58179a0bf528SMauro Carvalho Chehab now AGCs can be configured. */ 58189a0bf528SMauro Carvalho Chehab 5819cd7a67a4SMauro Carvalho Chehab status = init_agc(state, true); 58209a0bf528SMauro Carvalho Chehab if (status < 0) 58219a0bf528SMauro Carvalho Chehab goto error; 5822cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg)); 58239a0bf528SMauro Carvalho Chehab if (status < 0) 58249a0bf528SMauro Carvalho Chehab goto error; 58259a0bf528SMauro Carvalho Chehab 58269a0bf528SMauro Carvalho Chehab /* Configure AGC's */ 5827cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true); 58289a0bf528SMauro Carvalho Chehab if (status < 0) 58299a0bf528SMauro Carvalho Chehab goto error; 5830cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true); 58319a0bf528SMauro Carvalho Chehab if (status < 0) 58329a0bf528SMauro Carvalho Chehab goto error; 58339a0bf528SMauro Carvalho Chehab 58349a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */ 58359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 58369a0bf528SMauro Carvalho Chehab error: 58379a0bf528SMauro Carvalho Chehab if (status < 0) 58383a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 58399a0bf528SMauro Carvalho Chehab return status; 58409a0bf528SMauro Carvalho Chehab } 58419a0bf528SMauro Carvalho Chehab 5842cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state) 58439a0bf528SMauro Carvalho Chehab { 58449a0bf528SMauro Carvalho Chehab int status; 58459a0bf528SMauro Carvalho Chehab u16 value = 0; 58469a0bf528SMauro Carvalho Chehab 58479a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 58489a0bf528SMauro Carvalho Chehab /* stop lock indicator process */ 5849ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 5850ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 58519a0bf528SMauro Carvalho Chehab if (status < 0) 58529a0bf528SMauro Carvalho Chehab goto error; 58539a0bf528SMauro Carvalho Chehab 58549a0bf528SMauro Carvalho Chehab /* Write magic word to enable pdr reg write */ 58559a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 58569a0bf528SMauro Carvalho Chehab if (status < 0) 58579a0bf528SMauro Carvalho Chehab goto error; 58589a0bf528SMauro Carvalho Chehab 5859cd7a67a4SMauro Carvalho Chehab if (state->m_has_sawsw) { 5860cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0001) { /* UIO-1 */ 58619a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5862ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_TX_CFG__A, 5863ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 58649a0bf528SMauro Carvalho Chehab if (status < 0) 58659a0bf528SMauro Carvalho Chehab goto error; 58669a0bf528SMauro Carvalho Chehab 58679a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 58689a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 58699a0bf528SMauro Carvalho Chehab if (status < 0) 58709a0bf528SMauro Carvalho Chehab goto error; 5871cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0001) == 0) 58729a0bf528SMauro Carvalho Chehab value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ 58739a0bf528SMauro Carvalho Chehab else 58749a0bf528SMauro Carvalho Chehab value |= 0x8000; /* write one to 15th bit - 1st UIO */ 58759a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 58769a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 58779a0bf528SMauro Carvalho Chehab if (status < 0) 58789a0bf528SMauro Carvalho Chehab goto error; 58799a0bf528SMauro Carvalho Chehab } 5880cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0002) { /* UIO-2 */ 58819a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5882ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_RX_CFG__A, 5883ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 58849a0bf528SMauro Carvalho Chehab if (status < 0) 58859a0bf528SMauro Carvalho Chehab goto error; 58869a0bf528SMauro Carvalho Chehab 58879a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 58889a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 58899a0bf528SMauro Carvalho Chehab if (status < 0) 58909a0bf528SMauro Carvalho Chehab goto error; 5891cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0002) == 0) 58929a0bf528SMauro Carvalho Chehab value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ 58939a0bf528SMauro Carvalho Chehab else 58949a0bf528SMauro Carvalho Chehab value |= 0x4000; /* write one to 14th bit - 2st UIO */ 58959a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 58969a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 58979a0bf528SMauro Carvalho Chehab if (status < 0) 58989a0bf528SMauro Carvalho Chehab goto error; 58999a0bf528SMauro Carvalho Chehab } 5900cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0004) { /* UIO-3 */ 59019a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */ 5902ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_GPIO_CFG__A, 5903ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg); 59049a0bf528SMauro Carvalho Chehab if (status < 0) 59059a0bf528SMauro Carvalho Chehab goto error; 59069a0bf528SMauro Carvalho Chehab 59079a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */ 59089a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59099a0bf528SMauro Carvalho Chehab if (status < 0) 59109a0bf528SMauro Carvalho Chehab goto error; 5911cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0004) == 0) 59129a0bf528SMauro Carvalho Chehab value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ 59139a0bf528SMauro Carvalho Chehab else 59149a0bf528SMauro Carvalho Chehab value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ 59159a0bf528SMauro Carvalho Chehab /* write back to io data output register */ 59169a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59179a0bf528SMauro Carvalho Chehab if (status < 0) 59189a0bf528SMauro Carvalho Chehab goto error; 59199a0bf528SMauro Carvalho Chehab } 59209a0bf528SMauro Carvalho Chehab } 59219a0bf528SMauro Carvalho Chehab /* Write magic word to disable pdr reg write */ 59229a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 59239a0bf528SMauro Carvalho Chehab error: 59249a0bf528SMauro Carvalho Chehab if (status < 0) 59253a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 59269a0bf528SMauro Carvalho Chehab return status; 59279a0bf528SMauro Carvalho Chehab } 59289a0bf528SMauro Carvalho Chehab 5929cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state) 59309a0bf528SMauro Carvalho Chehab { 59319a0bf528SMauro Carvalho Chehab int status = 0; 59329a0bf528SMauro Carvalho Chehab bool gpio_state; 59339a0bf528SMauro Carvalho Chehab 59349a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 59359a0bf528SMauro Carvalho Chehab 59369a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio) 59379a0bf528SMauro Carvalho Chehab return 0; 59389a0bf528SMauro Carvalho Chehab 5939cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio; 59409a0bf528SMauro Carvalho Chehab 59419a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt ^ gpio_state) { 59429a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-T mode. Switch */ 59439a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt) 5944cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 59459a0bf528SMauro Carvalho Chehab else 5946cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 5947cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 59489a0bf528SMauro Carvalho Chehab } 59499a0bf528SMauro Carvalho Chehab if (status < 0) 59503a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 59519a0bf528SMauro Carvalho Chehab return status; 59529a0bf528SMauro Carvalho Chehab } 59539a0bf528SMauro Carvalho Chehab 5954cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state) 59559a0bf528SMauro Carvalho Chehab { 59569a0bf528SMauro Carvalho Chehab int status = 0; 59579a0bf528SMauro Carvalho Chehab bool gpio_state; 59589a0bf528SMauro Carvalho Chehab 59599a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 59609a0bf528SMauro Carvalho Chehab 59619a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio) 59629a0bf528SMauro Carvalho Chehab return 0; 59639a0bf528SMauro Carvalho Chehab 5964cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio; 59659a0bf528SMauro Carvalho Chehab 59669a0bf528SMauro Carvalho Chehab if (!(state->antenna_dvbt ^ gpio_state)) { 59679a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-C mode. Switch */ 59689a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt) 5969cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 59709a0bf528SMauro Carvalho Chehab else 5971cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 5972cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 59739a0bf528SMauro Carvalho Chehab } 59749a0bf528SMauro Carvalho Chehab if (status < 0) 59753a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 59769a0bf528SMauro Carvalho Chehab return status; 59779a0bf528SMauro Carvalho Chehab } 59789a0bf528SMauro Carvalho Chehab 59799a0bf528SMauro Carvalho Chehab 5980cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state) 59819a0bf528SMauro Carvalho Chehab { 59829a0bf528SMauro Carvalho Chehab /* Power down to requested mode */ 59839a0bf528SMauro Carvalho Chehab /* Backup some register settings */ 59849a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected to them in input mode */ 59859a0bf528SMauro Carvalho Chehab /* Analog power down */ 59869a0bf528SMauro Carvalho Chehab /* ADC power down */ 59879a0bf528SMauro Carvalho Chehab /* Power down device */ 59889a0bf528SMauro Carvalho Chehab int status; 59899a0bf528SMauro Carvalho Chehab 59909a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 5991cd7a67a4SMauro Carvalho Chehab if (state->m_b_p_down_open_bridge) { 59929a0bf528SMauro Carvalho Chehab /* Open I2C bridge before power down of DRXK */ 59939a0bf528SMauro Carvalho Chehab status = ConfigureI2CBridge(state, true); 59949a0bf528SMauro Carvalho Chehab if (status < 0) 59959a0bf528SMauro Carvalho Chehab goto error; 59969a0bf528SMauro Carvalho Chehab } 59979a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 5998cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false); 59999a0bf528SMauro Carvalho Chehab if (status < 0) 60009a0bf528SMauro Carvalho Chehab goto error; 60019a0bf528SMauro Carvalho Chehab 6002ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, 6003ab5060cdSMauro Carvalho Chehab SIO_CC_PWD_MODE_LEVEL_CLOCK); 60049a0bf528SMauro Carvalho Chehab if (status < 0) 60059a0bf528SMauro Carvalho Chehab goto error; 60069a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60079a0bf528SMauro Carvalho Chehab if (status < 0) 60089a0bf528SMauro Carvalho Chehab goto error; 6009cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 6010cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state); 60119a0bf528SMauro Carvalho Chehab error: 60129a0bf528SMauro Carvalho Chehab if (status < 0) 60133a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 60149a0bf528SMauro Carvalho Chehab 60159a0bf528SMauro Carvalho Chehab return status; 60169a0bf528SMauro Carvalho Chehab } 60179a0bf528SMauro Carvalho Chehab 60189a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state) 60199a0bf528SMauro Carvalho Chehab { 60209a0bf528SMauro Carvalho Chehab int status = 0, n = 0; 6021cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 6022cd7a67a4SMauro Carvalho Chehab u16 driver_version; 60239a0bf528SMauro Carvalho Chehab 60249a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 60257369bbf2SNick Desaulniers if (state->m_drxk_state == DRXK_UNINITIALIZED) { 60269a0bf528SMauro Carvalho Chehab drxk_i2c_lock(state); 6027cd7a67a4SMauro Carvalho Chehab status = power_up_device(state); 60289a0bf528SMauro Carvalho Chehab if (status < 0) 60299a0bf528SMauro Carvalho Chehab goto error; 6030cd7a67a4SMauro Carvalho Chehab status = drxx_open(state); 60319a0bf528SMauro Carvalho Chehab if (status < 0) 60329a0bf528SMauro Carvalho Chehab goto error; 60339a0bf528SMauro Carvalho Chehab /* Soft reset of OFDM-, sys- and osc-clockdomain */ 6034ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_SOFT_RST__A, 6035ab5060cdSMauro Carvalho Chehab SIO_CC_SOFT_RST_OFDM__M 6036ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_SYS__M 6037ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_OSC__M); 60389a0bf528SMauro Carvalho Chehab if (status < 0) 60399a0bf528SMauro Carvalho Chehab goto error; 60409a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60419a0bf528SMauro Carvalho Chehab if (status < 0) 60429a0bf528SMauro Carvalho Chehab goto error; 6043ab5060cdSMauro Carvalho Chehab /* 6044ab5060cdSMauro Carvalho Chehab * TODO is this needed? If yes, how much delay in 6045ab5060cdSMauro Carvalho Chehab * worst case scenario 6046ab5060cdSMauro Carvalho Chehab */ 6047b72852baSMauro Carvalho Chehab usleep_range(1000, 2000); 6048cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = true; 6049cd7a67a4SMauro Carvalho Chehab status = get_device_capabilities(state); 60509a0bf528SMauro Carvalho Chehab if (status < 0) 60519a0bf528SMauro Carvalho Chehab goto error; 60529a0bf528SMauro Carvalho Chehab 60539a0bf528SMauro Carvalho Chehab /* Bridge delay, uses oscilator clock */ 60549a0bf528SMauro Carvalho Chehab /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */ 60559a0bf528SMauro Carvalho Chehab /* SDA brdige delay */ 6056cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay = 6057cd7a67a4SMauro Carvalho Chehab (u16) ((state->m_osc_clock_freq / 1000) * 60589a0bf528SMauro Carvalho Chehab HI_I2C_BRIDGE_DELAY) / 1000; 60599a0bf528SMauro Carvalho Chehab /* Clipping */ 6060cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_bridge_delay > 60619a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) { 6062cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay = 60639a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M; 60649a0bf528SMauro Carvalho Chehab } 60659a0bf528SMauro Carvalho Chehab /* SCL bridge delay, same as SDA for now */ 6066cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay += 6067cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay << 60689a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B; 60699a0bf528SMauro Carvalho Chehab 6070cd7a67a4SMauro Carvalho Chehab status = init_hi(state); 60719a0bf528SMauro Carvalho Chehab if (status < 0) 60729a0bf528SMauro Carvalho Chehab goto error; 60739a0bf528SMauro Carvalho Chehab /* disable various processes */ 60749a0bf528SMauro Carvalho Chehab #if NOA1ROM 60759a0bf528SMauro Carvalho Chehab if (!(state->m_DRXK_A1_ROM_CODE) 60769a0bf528SMauro Carvalho Chehab && !(state->m_DRXK_A2_ROM_CODE)) 60779a0bf528SMauro Carvalho Chehab #endif 60789a0bf528SMauro Carvalho Chehab { 6079ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A, 6080ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 60819a0bf528SMauro Carvalho Chehab if (status < 0) 60829a0bf528SMauro Carvalho Chehab goto error; 60839a0bf528SMauro Carvalho Chehab } 60849a0bf528SMauro Carvalho Chehab 60859a0bf528SMauro Carvalho Chehab /* disable MPEG port */ 6086cd7a67a4SMauro Carvalho Chehab status = mpegts_disable(state); 60879a0bf528SMauro Carvalho Chehab if (status < 0) 60889a0bf528SMauro Carvalho Chehab goto error; 60899a0bf528SMauro Carvalho Chehab 60909a0bf528SMauro Carvalho Chehab /* Stop AUD and SCU */ 60919a0bf528SMauro Carvalho Chehab status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP); 60929a0bf528SMauro Carvalho Chehab if (status < 0) 60939a0bf528SMauro Carvalho Chehab goto error; 60949a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP); 60959a0bf528SMauro Carvalho Chehab if (status < 0) 60969a0bf528SMauro Carvalho Chehab goto error; 60979a0bf528SMauro Carvalho Chehab 60989a0bf528SMauro Carvalho Chehab /* enable token-ring bus through OFDM block for possible ucode upload */ 6099ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 6100ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_ON); 61019a0bf528SMauro Carvalho Chehab if (status < 0) 61029a0bf528SMauro Carvalho Chehab goto error; 61039a0bf528SMauro Carvalho Chehab 61049a0bf528SMauro Carvalho Chehab /* include boot loader section */ 6105ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_BL_COMM_EXEC__A, 6106ab5060cdSMauro Carvalho Chehab SIO_BL_COMM_EXEC_ACTIVE); 61079a0bf528SMauro Carvalho Chehab if (status < 0) 61089a0bf528SMauro Carvalho Chehab goto error; 6109cd7a67a4SMauro Carvalho Chehab status = bl_chain_cmd(state, 0, 6, 100); 61109a0bf528SMauro Carvalho Chehab if (status < 0) 61119a0bf528SMauro Carvalho Chehab goto error; 61129a0bf528SMauro Carvalho Chehab 61139a0bf528SMauro Carvalho Chehab if (state->fw) { 6114cd7a67a4SMauro Carvalho Chehab status = download_microcode(state, state->fw->data, 61159a0bf528SMauro Carvalho Chehab state->fw->size); 61169a0bf528SMauro Carvalho Chehab if (status < 0) 61179a0bf528SMauro Carvalho Chehab goto error; 61189a0bf528SMauro Carvalho Chehab } 61199a0bf528SMauro Carvalho Chehab 61209a0bf528SMauro Carvalho Chehab /* disable token-ring bus through OFDM block for possible ucode upload */ 6121ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 6122ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); 61239a0bf528SMauro Carvalho Chehab if (status < 0) 61249a0bf528SMauro Carvalho Chehab goto error; 61259a0bf528SMauro Carvalho Chehab 61269a0bf528SMauro Carvalho Chehab /* Run SCU for a little while to initialize microcode version numbers */ 61279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 61289a0bf528SMauro Carvalho Chehab if (status < 0) 61299a0bf528SMauro Carvalho Chehab goto error; 6130cd7a67a4SMauro Carvalho Chehab status = drxx_open(state); 61319a0bf528SMauro Carvalho Chehab if (status < 0) 61329a0bf528SMauro Carvalho Chehab goto error; 61339a0bf528SMauro Carvalho Chehab /* added for test */ 61349a0bf528SMauro Carvalho Chehab msleep(30); 61359a0bf528SMauro Carvalho Chehab 6136cd7a67a4SMauro Carvalho Chehab power_mode = DRXK_POWER_DOWN_OFDM; 6137cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode); 61389a0bf528SMauro Carvalho Chehab if (status < 0) 61399a0bf528SMauro Carvalho Chehab goto error; 61409a0bf528SMauro Carvalho Chehab 61419a0bf528SMauro Carvalho Chehab /* Stamp driver version number in SCU data RAM in BCD code 614239c1cb2bSJonathan McCrohan Done to enable field application engineers to retrieve drxdriver version 61439a0bf528SMauro Carvalho Chehab via I2C from SCU RAM. 61449a0bf528SMauro Carvalho Chehab Not using SCU command interface for SCU register access since no 61459a0bf528SMauro Carvalho Chehab microcode may be present. 61469a0bf528SMauro Carvalho Chehab */ 6147cd7a67a4SMauro Carvalho Chehab driver_version = 61489a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 100) % 10) << 12) + 61499a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 10) % 10) << 8) + 61509a0bf528SMauro Carvalho Chehab ((DRXK_VERSION_MAJOR % 10) << 4) + 61519a0bf528SMauro Carvalho Chehab (DRXK_VERSION_MINOR % 10); 6152ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_HI__A, 6153ab5060cdSMauro Carvalho Chehab driver_version); 61549a0bf528SMauro Carvalho Chehab if (status < 0) 61559a0bf528SMauro Carvalho Chehab goto error; 6156cd7a67a4SMauro Carvalho Chehab driver_version = 61579a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 1000) % 10) << 12) + 61589a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 100) % 10) << 8) + 61599a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 10) % 10) << 4) + 61609a0bf528SMauro Carvalho Chehab (DRXK_VERSION_PATCH % 10); 6161ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_LO__A, 6162ab5060cdSMauro Carvalho Chehab driver_version); 61639a0bf528SMauro Carvalho Chehab if (status < 0) 61649a0bf528SMauro Carvalho Chehab goto error; 61659a0bf528SMauro Carvalho Chehab 61663a4398f5SMauro Carvalho Chehab pr_info("DRXK driver version %d.%d.%d\n", 61679a0bf528SMauro Carvalho Chehab DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR, 61689a0bf528SMauro Carvalho Chehab DRXK_VERSION_PATCH); 61699a0bf528SMauro Carvalho Chehab 6170ab5060cdSMauro Carvalho Chehab /* 6171ab5060cdSMauro Carvalho Chehab * Dirty fix of default values for ROM/PATCH microcode 6172ab5060cdSMauro Carvalho Chehab * Dirty because this fix makes it impossible to setup 6173ab5060cdSMauro Carvalho Chehab * suitable values before calling DRX_Open. This solution 6174ab5060cdSMauro Carvalho Chehab * requires changes to RF AGC speed to be done via the CTRL 6175ab5060cdSMauro Carvalho Chehab * function after calling DRX_Open 6176ab5060cdSMauro Carvalho Chehab */ 61779a0bf528SMauro Carvalho Chehab 6178cd7a67a4SMauro Carvalho Chehab /* m_dvbt_rf_agc_cfg.speed = 3; */ 61799a0bf528SMauro Carvalho Chehab 61809a0bf528SMauro Carvalho Chehab /* Reset driver debug flags to 0 */ 61819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0); 61829a0bf528SMauro Carvalho Chehab if (status < 0) 61839a0bf528SMauro Carvalho Chehab goto error; 61849a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */ 61859a0bf528SMauro Carvalho Chehab /* Setup FEC OC: 61869a0bf528SMauro Carvalho Chehab NOTE: No more full FEC resets allowed afterwards!! */ 61879a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP); 61889a0bf528SMauro Carvalho Chehab if (status < 0) 61899a0bf528SMauro Carvalho Chehab goto error; 61909a0bf528SMauro Carvalho Chehab /* MPEGTS functions are still the same */ 6191cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_init(state); 61929a0bf528SMauro Carvalho Chehab if (status < 0) 61939a0bf528SMauro Carvalho Chehab goto error; 6194cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state); 61959a0bf528SMauro Carvalho Chehab if (status < 0) 61969a0bf528SMauro Carvalho Chehab goto error; 6197cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_polarity(state); 61989a0bf528SMauro Carvalho Chehab if (status < 0) 61999a0bf528SMauro Carvalho Chehab goto error; 6200cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_pins(state, state->m_enable_mpeg_output); 62019a0bf528SMauro Carvalho Chehab if (status < 0) 62029a0bf528SMauro Carvalho Chehab goto error; 62039a0bf528SMauro Carvalho Chehab /* added: configure GPIO */ 6204cd7a67a4SMauro Carvalho Chehab status = write_gpio(state); 62059a0bf528SMauro Carvalho Chehab if (status < 0) 62069a0bf528SMauro Carvalho Chehab goto error; 62079a0bf528SMauro Carvalho Chehab 6208cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED; 62099a0bf528SMauro Carvalho Chehab 6210cd7a67a4SMauro Carvalho Chehab if (state->m_b_power_down) { 6211cd7a67a4SMauro Carvalho Chehab status = power_down_device(state); 62129a0bf528SMauro Carvalho Chehab if (status < 0) 62139a0bf528SMauro Carvalho Chehab goto error; 6214cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_POWERED_DOWN; 62159a0bf528SMauro Carvalho Chehab } else 6216cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED; 62179a0bf528SMauro Carvalho Chehab 62189a0bf528SMauro Carvalho Chehab /* Initialize the supported delivery systems */ 62199a0bf528SMauro Carvalho Chehab n = 0; 6220cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbc) { 62219a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; 62229a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; 62239a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-C", 62249a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name)); 62259a0bf528SMauro Carvalho Chehab } 6226cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbt) { 62279a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBT; 62289a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-T", 62299a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name)); 62309a0bf528SMauro Carvalho Chehab } 62319a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state); 62329a0bf528SMauro Carvalho Chehab } 62339a0bf528SMauro Carvalho Chehab error: 62349a0bf528SMauro Carvalho Chehab if (status < 0) { 6235cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_NO_DEV; 62369a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state); 62373a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__); 62389a0bf528SMauro Carvalho Chehab } 62399a0bf528SMauro Carvalho Chehab 62409a0bf528SMauro Carvalho Chehab return status; 62419a0bf528SMauro Carvalho Chehab } 62429a0bf528SMauro Carvalho Chehab 62439a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw, 62449a0bf528SMauro Carvalho Chehab void *context) 62459a0bf528SMauro Carvalho Chehab { 62469a0bf528SMauro Carvalho Chehab struct drxk_state *state = context; 62479a0bf528SMauro Carvalho Chehab 62489a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); 62499a0bf528SMauro Carvalho Chehab if (!fw) { 62503a4398f5SMauro Carvalho Chehab pr_err("Could not load firmware file %s.\n", 62519a0bf528SMauro Carvalho Chehab state->microcode_name); 62523a4398f5SMauro Carvalho Chehab pr_info("Copy %s to your hotplug directory!\n", 62539a0bf528SMauro Carvalho Chehab state->microcode_name); 62549a0bf528SMauro Carvalho Chehab state->microcode_name = NULL; 62559a0bf528SMauro Carvalho Chehab 62569a0bf528SMauro Carvalho Chehab /* 62579a0bf528SMauro Carvalho Chehab * As firmware is now load asynchronous, it is not possible 62589a0bf528SMauro Carvalho Chehab * anymore to fail at frontend attach. We might silently 62599a0bf528SMauro Carvalho Chehab * return here, and hope that the driver won't crash. 62609a0bf528SMauro Carvalho Chehab * We might also change all DVB callbacks to return -ENODEV 62619a0bf528SMauro Carvalho Chehab * if the device is not initialized. 62629a0bf528SMauro Carvalho Chehab * As the DRX-K devices have their own internal firmware, 62639a0bf528SMauro Carvalho Chehab * let's just hope that it will match a firmware revision 62649a0bf528SMauro Carvalho Chehab * compatible with this driver and proceed. 62659a0bf528SMauro Carvalho Chehab */ 62669a0bf528SMauro Carvalho Chehab } 62679a0bf528SMauro Carvalho Chehab state->fw = fw; 62689a0bf528SMauro Carvalho Chehab 62699a0bf528SMauro Carvalho Chehab init_drxk(state); 62709a0bf528SMauro Carvalho Chehab } 62719a0bf528SMauro Carvalho Chehab 62729a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe) 62739a0bf528SMauro Carvalho Chehab { 62749a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 62759a0bf528SMauro Carvalho Chehab 62769a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 62779a0bf528SMauro Carvalho Chehab release_firmware(state->fw); 62789a0bf528SMauro Carvalho Chehab 62799a0bf528SMauro Carvalho Chehab kfree(state); 62809a0bf528SMauro Carvalho Chehab } 62819a0bf528SMauro Carvalho Chehab 62829a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe) 62839a0bf528SMauro Carvalho Chehab { 62849a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 62859a0bf528SMauro Carvalho Chehab 62869a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 62879a0bf528SMauro Carvalho Chehab 6288cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 62899a0bf528SMauro Carvalho Chehab return -ENODEV; 6290cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 62919a0bf528SMauro Carvalho Chehab return 0; 62929a0bf528SMauro Carvalho Chehab 6293cd7a67a4SMauro Carvalho Chehab shut_down(state); 62949a0bf528SMauro Carvalho Chehab return 0; 62959a0bf528SMauro Carvalho Chehab } 62969a0bf528SMauro Carvalho Chehab 62979a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 62989a0bf528SMauro Carvalho Chehab { 62999a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63009a0bf528SMauro Carvalho Chehab 63019a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", enable ? "enable" : "disable"); 63029a0bf528SMauro Carvalho Chehab 6303cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 63049a0bf528SMauro Carvalho Chehab return -ENODEV; 63059a0bf528SMauro Carvalho Chehab 63069a0bf528SMauro Carvalho Chehab return ConfigureI2CBridge(state, enable ? true : false); 63079a0bf528SMauro Carvalho Chehab } 63089a0bf528SMauro Carvalho Chehab 63099a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe) 63109a0bf528SMauro Carvalho Chehab { 63119a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 63129a0bf528SMauro Carvalho Chehab u32 delsys = p->delivery_system, old_delsys; 63139a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 63149a0bf528SMauro Carvalho Chehab u32 IF; 63159a0bf528SMauro Carvalho Chehab 63169a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 63179a0bf528SMauro Carvalho Chehab 6318cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 63199a0bf528SMauro Carvalho Chehab return -ENODEV; 63209a0bf528SMauro Carvalho Chehab 6321cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 63229a0bf528SMauro Carvalho Chehab return -EAGAIN; 63239a0bf528SMauro Carvalho Chehab 63249a0bf528SMauro Carvalho Chehab if (!fe->ops.tuner_ops.get_if_frequency) { 63253a4398f5SMauro Carvalho Chehab pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); 63269a0bf528SMauro Carvalho Chehab return -EINVAL; 63279a0bf528SMauro Carvalho Chehab } 63289a0bf528SMauro Carvalho Chehab 63299a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl) 63309a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1); 63319a0bf528SMauro Carvalho Chehab if (fe->ops.tuner_ops.set_params) 63329a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 63339a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl) 63349a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 0); 63359a0bf528SMauro Carvalho Chehab 63369a0bf528SMauro Carvalho Chehab old_delsys = state->props.delivery_system; 63379a0bf528SMauro Carvalho Chehab state->props = *p; 63389a0bf528SMauro Carvalho Chehab 63399a0bf528SMauro Carvalho Chehab if (old_delsys != delsys) { 6340cd7a67a4SMauro Carvalho Chehab shut_down(state); 63419a0bf528SMauro Carvalho Chehab switch (delsys) { 63429a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A: 63439a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C: 6344cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbc) 63459a0bf528SMauro Carvalho Chehab return -EINVAL; 6346ab5060cdSMauro Carvalho Chehab state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? 6347ab5060cdSMauro Carvalho Chehab true : false; 63489a0bf528SMauro Carvalho Chehab if (state->m_itut_annex_c) 6349cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_C); 63509a0bf528SMauro Carvalho Chehab else 6351cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_A); 63529a0bf528SMauro Carvalho Chehab break; 63539a0bf528SMauro Carvalho Chehab case SYS_DVBT: 6354cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbt) 63559a0bf528SMauro Carvalho Chehab return -EINVAL; 6356cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_DVBT); 63579a0bf528SMauro Carvalho Chehab break; 63589a0bf528SMauro Carvalho Chehab default: 63599a0bf528SMauro Carvalho Chehab return -EINVAL; 63609a0bf528SMauro Carvalho Chehab } 63619a0bf528SMauro Carvalho Chehab } 63629a0bf528SMauro Carvalho Chehab 63639a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.get_if_frequency(fe, &IF); 6364cd7a67a4SMauro Carvalho Chehab start(state, 0, IF); 63659a0bf528SMauro Carvalho Chehab 636639c1cb2bSJonathan McCrohan /* After set_frontend, stats aren't available */ 63678f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 63688f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63698f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63708f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63718f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63728f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63738f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63748f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63758f3741e0SMauro Carvalho Chehab 63769a0bf528SMauro Carvalho Chehab /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */ 63779a0bf528SMauro Carvalho Chehab 63789a0bf528SMauro Carvalho Chehab return 0; 63799a0bf528SMauro Carvalho Chehab } 63809a0bf528SMauro Carvalho Chehab 638159a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength) 638259a7a23cSMauro Carvalho Chehab { 638359a7a23cSMauro Carvalho Chehab int status; 6384cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc rf_agc, if_agc; 6385cd7a67a4SMauro Carvalho Chehab u32 total_gain = 0; 638659a7a23cSMauro Carvalho Chehab u32 atten = 0; 6387cd7a67a4SMauro Carvalho Chehab u32 agc_range = 0; 638859a7a23cSMauro Carvalho Chehab u16 scu_lvl = 0; 638959a7a23cSMauro Carvalho Chehab u16 scu_coc = 0; 639059a7a23cSMauro Carvalho Chehab /* FIXME: those are part of the tuner presets */ 6391cd7a67a4SMauro Carvalho Chehab u16 tuner_rf_gain = 50; /* Default value on az6007 driver */ 6392cd7a67a4SMauro Carvalho Chehab u16 tuner_if_gain = 40; /* Default value on az6007 driver */ 639359a7a23cSMauro Carvalho Chehab 639459a7a23cSMauro Carvalho Chehab *strength = 0; 639559a7a23cSMauro Carvalho Chehab 6396cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state)) { 6397cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_dvbt_rf_agc_cfg; 6398cd7a67a4SMauro Carvalho Chehab if_agc = state->m_dvbt_if_agc_cfg; 6399cd7a67a4SMauro Carvalho Chehab } else if (is_qam(state)) { 6400cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_qam_rf_agc_cfg; 6401cd7a67a4SMauro Carvalho Chehab if_agc = state->m_qam_if_agc_cfg; 640259a7a23cSMauro Carvalho Chehab } else { 6403cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_atv_rf_agc_cfg; 6404cd7a67a4SMauro Carvalho Chehab if_agc = state->m_atv_if_agc_cfg; 640559a7a23cSMauro Carvalho Chehab } 640659a7a23cSMauro Carvalho Chehab 6407cd7a67a4SMauro Carvalho Chehab if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 6408cd7a67a4SMauro Carvalho Chehab /* SCU output_level */ 640959a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl); 641059a7a23cSMauro Carvalho Chehab if (status < 0) 641159a7a23cSMauro Carvalho Chehab return status; 641259a7a23cSMauro Carvalho Chehab 641359a7a23cSMauro Carvalho Chehab /* SCU c.o.c. */ 6414d259a5eeSChristophe JAILLET status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); 641559a7a23cSMauro Carvalho Chehab if (status < 0) 641659a7a23cSMauro Carvalho Chehab return status; 641759a7a23cSMauro Carvalho Chehab 641859a7a23cSMauro Carvalho Chehab if (((u32) scu_lvl + (u32) scu_coc) < 0xffff) 6419cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = scu_lvl + scu_coc; 642059a7a23cSMauro Carvalho Chehab else 6421cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = 0xffff; 642259a7a23cSMauro Carvalho Chehab 642359a7a23cSMauro Carvalho Chehab /* Take RF gain into account */ 6424cd7a67a4SMauro Carvalho Chehab total_gain += tuner_rf_gain; 642559a7a23cSMauro Carvalho Chehab 642659a7a23cSMauro Carvalho Chehab /* clip output value */ 6427cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level < rf_agc.min_output_level) 6428cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.min_output_level; 6429cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level > rf_agc.max_output_level) 6430cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.max_output_level; 643159a7a23cSMauro Carvalho Chehab 6432cd7a67a4SMauro Carvalho Chehab agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level); 6433cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) { 643459a7a23cSMauro Carvalho Chehab atten += 100UL * 6435cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_rf_gain)) * 6436cd7a67a4SMauro Carvalho Chehab ((u32)(rf_agc.output_level - rf_agc.min_output_level)) 6437cd7a67a4SMauro Carvalho Chehab / agc_range; 643859a7a23cSMauro Carvalho Chehab } 643959a7a23cSMauro Carvalho Chehab } 644059a7a23cSMauro Carvalho Chehab 6441cd7a67a4SMauro Carvalho Chehab if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 644259a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 6443cd7a67a4SMauro Carvalho Chehab &if_agc.output_level); 644459a7a23cSMauro Carvalho Chehab if (status < 0) 644559a7a23cSMauro Carvalho Chehab return status; 644659a7a23cSMauro Carvalho Chehab 644759a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, 6448cd7a67a4SMauro Carvalho Chehab &if_agc.top); 644959a7a23cSMauro Carvalho Chehab if (status < 0) 645059a7a23cSMauro Carvalho Chehab return status; 645159a7a23cSMauro Carvalho Chehab 645259a7a23cSMauro Carvalho Chehab /* Take IF gain into account */ 6453cd7a67a4SMauro Carvalho Chehab total_gain += (u32) tuner_if_gain; 645459a7a23cSMauro Carvalho Chehab 645559a7a23cSMauro Carvalho Chehab /* clip output value */ 6456cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level < if_agc.min_output_level) 6457cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.min_output_level; 6458cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level > if_agc.max_output_level) 6459cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.max_output_level; 646059a7a23cSMauro Carvalho Chehab 6461cd7a67a4SMauro Carvalho Chehab agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level); 6462cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) { 646359a7a23cSMauro Carvalho Chehab atten += 100UL * 6464cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_if_gain)) * 6465cd7a67a4SMauro Carvalho Chehab ((u32)(if_agc.output_level - if_agc.min_output_level)) 6466cd7a67a4SMauro Carvalho Chehab / agc_range; 646759a7a23cSMauro Carvalho Chehab } 646859a7a23cSMauro Carvalho Chehab } 646959a7a23cSMauro Carvalho Chehab 647059a7a23cSMauro Carvalho Chehab /* 647159a7a23cSMauro Carvalho Chehab * Convert to 0..65535 scale. 647259a7a23cSMauro Carvalho Chehab * If it can't be measured (AGC is disabled), just show 100%. 647359a7a23cSMauro Carvalho Chehab */ 6474cd7a67a4SMauro Carvalho Chehab if (total_gain > 0) 6475cd7a67a4SMauro Carvalho Chehab *strength = (65535UL * atten / total_gain / 100); 647659a7a23cSMauro Carvalho Chehab else 647759a7a23cSMauro Carvalho Chehab *strength = 65535; 647859a7a23cSMauro Carvalho Chehab 647959a7a23cSMauro Carvalho Chehab return 0; 648059a7a23cSMauro Carvalho Chehab } 648159a7a23cSMauro Carvalho Chehab 64828f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe) 64839a0bf528SMauro Carvalho Chehab { 64848f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 64859a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 64868f3741e0SMauro Carvalho Chehab int status; 64879a0bf528SMauro Carvalho Chehab u32 stat; 64888f3741e0SMauro Carvalho Chehab u16 reg16; 64898f3741e0SMauro Carvalho Chehab u32 post_bit_count; 64908f3741e0SMauro Carvalho Chehab u32 post_bit_err_count; 64918f3741e0SMauro Carvalho Chehab u32 post_bit_error_scale; 64928f3741e0SMauro Carvalho Chehab u32 pre_bit_err_count; 64938f3741e0SMauro Carvalho Chehab u32 pre_bit_count; 64948f3741e0SMauro Carvalho Chehab u32 pkt_count; 64958f3741e0SMauro Carvalho Chehab u32 pkt_error_count; 649659a7a23cSMauro Carvalho Chehab s32 cnr; 64979a0bf528SMauro Carvalho Chehab 6498cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 64999a0bf528SMauro Carvalho Chehab return -ENODEV; 6500cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 65019a0bf528SMauro Carvalho Chehab return -EAGAIN; 65029a0bf528SMauro Carvalho Chehab 65038f3741e0SMauro Carvalho Chehab /* get status */ 65048f3741e0SMauro Carvalho Chehab state->fe_status = 0; 6505cd7a67a4SMauro Carvalho Chehab get_lock_status(state, &stat); 65069a0bf528SMauro Carvalho Chehab if (stat == MPEG_LOCK) 65078f3741e0SMauro Carvalho Chehab state->fe_status |= 0x1f; 65089a0bf528SMauro Carvalho Chehab if (stat == FEC_LOCK) 65098f3741e0SMauro Carvalho Chehab state->fe_status |= 0x0f; 65109a0bf528SMauro Carvalho Chehab if (stat == DEMOD_LOCK) 65118f3741e0SMauro Carvalho Chehab state->fe_status |= 0x07; 65128f3741e0SMauro Carvalho Chehab 651359a7a23cSMauro Carvalho Chehab /* 651459a7a23cSMauro Carvalho Chehab * Estimate signal strength from AGC 651559a7a23cSMauro Carvalho Chehab */ 651659a7a23cSMauro Carvalho Chehab get_strength(state, &c->strength.stat[0].uvalue); 651759a7a23cSMauro Carvalho Chehab c->strength.stat[0].scale = FE_SCALE_RELATIVE; 651859a7a23cSMauro Carvalho Chehab 651959a7a23cSMauro Carvalho Chehab 65208f3741e0SMauro Carvalho Chehab if (stat >= DEMOD_LOCK) { 6521cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &cnr); 65228f3741e0SMauro Carvalho Chehab c->cnr.stat[0].svalue = cnr * 100; 65238f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 65248f3741e0SMauro Carvalho Chehab } else { 65258f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65268f3741e0SMauro Carvalho Chehab } 65278f3741e0SMauro Carvalho Chehab 65288f3741e0SMauro Carvalho Chehab if (stat < FEC_LOCK) { 65298f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65308f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65318f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65328f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65338f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65348f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65358f3741e0SMauro Carvalho Chehab return 0; 65368f3741e0SMauro Carvalho Chehab } 65378f3741e0SMauro Carvalho Chehab 65388f3741e0SMauro Carvalho Chehab /* Get post BER */ 65398f3741e0SMauro Carvalho Chehab 65408f3741e0SMauro Carvalho Chehab /* BER measurement is valid if at least FEC lock is achieved */ 65418f3741e0SMauro Carvalho Chehab 6542ab5060cdSMauro Carvalho Chehab /* 6543ab5060cdSMauro Carvalho Chehab * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be 6544ab5060cdSMauro Carvalho Chehab * written to set nr of symbols or bits over which to measure 6545ab5060cdSMauro Carvalho Chehab * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). 6546ab5060cdSMauro Carvalho Chehab */ 65478f3741e0SMauro Carvalho Chehab 65488f3741e0SMauro Carvalho Chehab /* Read registers for post/preViterbi BER calculation */ 65498f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16); 65508f3741e0SMauro Carvalho Chehab if (status < 0) 65518f3741e0SMauro Carvalho Chehab goto error; 65528f3741e0SMauro Carvalho Chehab pre_bit_err_count = reg16; 65538f3741e0SMauro Carvalho Chehab 65548f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16); 65558f3741e0SMauro Carvalho Chehab if (status < 0) 65568f3741e0SMauro Carvalho Chehab goto error; 65578f3741e0SMauro Carvalho Chehab pre_bit_count = reg16; 65588f3741e0SMauro Carvalho Chehab 65598f3741e0SMauro Carvalho Chehab /* Number of bit-errors */ 65608f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16); 65618f3741e0SMauro Carvalho Chehab if (status < 0) 65628f3741e0SMauro Carvalho Chehab goto error; 65638f3741e0SMauro Carvalho Chehab post_bit_err_count = reg16; 65648f3741e0SMauro Carvalho Chehab 65658f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16); 65668f3741e0SMauro Carvalho Chehab if (status < 0) 65678f3741e0SMauro Carvalho Chehab goto error; 65688f3741e0SMauro Carvalho Chehab post_bit_error_scale = reg16; 65698f3741e0SMauro Carvalho Chehab 65708f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16); 65718f3741e0SMauro Carvalho Chehab if (status < 0) 65728f3741e0SMauro Carvalho Chehab goto error; 65738f3741e0SMauro Carvalho Chehab pkt_count = reg16; 65748f3741e0SMauro Carvalho Chehab 65758f3741e0SMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16); 65768f3741e0SMauro Carvalho Chehab if (status < 0) 65778f3741e0SMauro Carvalho Chehab goto error; 65788f3741e0SMauro Carvalho Chehab pkt_error_count = reg16; 65798f3741e0SMauro Carvalho Chehab write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 65808f3741e0SMauro Carvalho Chehab 65818f3741e0SMauro Carvalho Chehab post_bit_err_count *= post_bit_error_scale; 65828f3741e0SMauro Carvalho Chehab 65838f3741e0SMauro Carvalho Chehab post_bit_count = pkt_count * 204 * 8; 65848f3741e0SMauro Carvalho Chehab 65858f3741e0SMauro Carvalho Chehab /* Store the results */ 65868f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_COUNTER; 65878f3741e0SMauro Carvalho Chehab c->block_error.stat[0].uvalue += pkt_error_count; 65888f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_COUNTER; 65898f3741e0SMauro Carvalho Chehab c->block_count.stat[0].uvalue += pkt_count; 65908f3741e0SMauro Carvalho Chehab 65918f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; 65928f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].uvalue += pre_bit_err_count; 65938f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; 65948f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].uvalue += pre_bit_count; 65958f3741e0SMauro Carvalho Chehab 65968f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 65978f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].uvalue += post_bit_err_count; 65988f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 65998f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].uvalue += post_bit_count; 66008f3741e0SMauro Carvalho Chehab 66018f3741e0SMauro Carvalho Chehab error: 66028f3741e0SMauro Carvalho Chehab return status; 66038f3741e0SMauro Carvalho Chehab } 66048f3741e0SMauro Carvalho Chehab 66058f3741e0SMauro Carvalho Chehab 66060df289a2SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status) 66078f3741e0SMauro Carvalho Chehab { 66088f3741e0SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 66098f3741e0SMauro Carvalho Chehab int rc; 66108f3741e0SMauro Carvalho Chehab 66118f3741e0SMauro Carvalho Chehab dprintk(1, "\n"); 66128f3741e0SMauro Carvalho Chehab 66138f3741e0SMauro Carvalho Chehab rc = drxk_get_stats(fe); 66148f3741e0SMauro Carvalho Chehab if (rc < 0) 66158f3741e0SMauro Carvalho Chehab return rc; 66168f3741e0SMauro Carvalho Chehab 66178f3741e0SMauro Carvalho Chehab *status = state->fe_status; 66188f3741e0SMauro Carvalho Chehab 66199a0bf528SMauro Carvalho Chehab return 0; 66209a0bf528SMauro Carvalho Chehab } 66219a0bf528SMauro Carvalho Chehab 66229a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe, 66239a0bf528SMauro Carvalho Chehab u16 *strength) 66249a0bf528SMauro Carvalho Chehab { 66259a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 6626340e7696SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 66279a0bf528SMauro Carvalho Chehab 66289a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 66299a0bf528SMauro Carvalho Chehab 6630cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 66319a0bf528SMauro Carvalho Chehab return -ENODEV; 6632cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 66339a0bf528SMauro Carvalho Chehab return -EAGAIN; 66349a0bf528SMauro Carvalho Chehab 6635340e7696SMauro Carvalho Chehab *strength = c->strength.stat[0].uvalue; 66369a0bf528SMauro Carvalho Chehab return 0; 66379a0bf528SMauro Carvalho Chehab } 66389a0bf528SMauro Carvalho Chehab 66399a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) 66409a0bf528SMauro Carvalho Chehab { 66419a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 66429a0bf528SMauro Carvalho Chehab s32 snr2; 66439a0bf528SMauro Carvalho Chehab 66449a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 66459a0bf528SMauro Carvalho Chehab 6646cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 66479a0bf528SMauro Carvalho Chehab return -ENODEV; 6648cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 66499a0bf528SMauro Carvalho Chehab return -EAGAIN; 66509a0bf528SMauro Carvalho Chehab 6651cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &snr2); 66528f3741e0SMauro Carvalho Chehab 66538f3741e0SMauro Carvalho Chehab /* No negative SNR, clip to zero */ 66548f3741e0SMauro Carvalho Chehab if (snr2 < 0) 66558f3741e0SMauro Carvalho Chehab snr2 = 0; 66569a0bf528SMauro Carvalho Chehab *snr = snr2 & 0xffff; 66579a0bf528SMauro Carvalho Chehab return 0; 66589a0bf528SMauro Carvalho Chehab } 66599a0bf528SMauro Carvalho Chehab 66609a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 66619a0bf528SMauro Carvalho Chehab { 66629a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 6663*20694e96SHans Verkuil u16 err = 0; 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 6672cd7a67a4SMauro Carvalho Chehab dvbtqam_get_acc_pkt_err(state, &err); 66739a0bf528SMauro Carvalho Chehab *ucblocks = (u32) err; 66749a0bf528SMauro Carvalho Chehab return 0; 66759a0bf528SMauro Carvalho Chehab } 66769a0bf528SMauro Carvalho Chehab 6677ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe, 6678ab5060cdSMauro Carvalho Chehab struct dvb_frontend_tune_settings *sets) 66799a0bf528SMauro Carvalho Chehab { 66809a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv; 66819a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 66829a0bf528SMauro Carvalho Chehab 66839a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 66849a0bf528SMauro Carvalho Chehab 6685cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV) 66869a0bf528SMauro Carvalho Chehab return -ENODEV; 6687cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED) 66889a0bf528SMauro Carvalho Chehab return -EAGAIN; 66899a0bf528SMauro Carvalho Chehab 66909a0bf528SMauro Carvalho Chehab switch (p->delivery_system) { 66919a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A: 66929a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C: 66939a0bf528SMauro Carvalho Chehab case SYS_DVBT: 66949a0bf528SMauro Carvalho Chehab sets->min_delay_ms = 3000; 66959a0bf528SMauro Carvalho Chehab sets->max_drift = 0; 66969a0bf528SMauro Carvalho Chehab sets->step_size = 0; 66979a0bf528SMauro Carvalho Chehab return 0; 66989a0bf528SMauro Carvalho Chehab default: 66999a0bf528SMauro Carvalho Chehab return -EINVAL; 67009a0bf528SMauro Carvalho Chehab } 67019a0bf528SMauro Carvalho Chehab } 67029a0bf528SMauro Carvalho Chehab 6703bd336e63SMax Kellermann static const struct dvb_frontend_ops drxk_ops = { 67049a0bf528SMauro Carvalho Chehab /* .delsys will be filled dynamically */ 67059a0bf528SMauro Carvalho Chehab .info = { 67069a0bf528SMauro Carvalho Chehab .name = "DRXK", 6707f1b1eabfSMauro Carvalho Chehab .frequency_min_hz = 47 * MHz, 6708f1b1eabfSMauro Carvalho Chehab .frequency_max_hz = 865 * MHz, 67099a0bf528SMauro Carvalho Chehab /* For DVB-C */ 67109a0bf528SMauro Carvalho Chehab .symbol_rate_min = 870000, 67119a0bf528SMauro Carvalho Chehab .symbol_rate_max = 11700000, 67129a0bf528SMauro Carvalho Chehab /* For DVB-T */ 6713f1b1eabfSMauro Carvalho Chehab .frequency_stepsize_hz = 166667, 67149a0bf528SMauro Carvalho Chehab 67159a0bf528SMauro Carvalho Chehab .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | 67169a0bf528SMauro Carvalho Chehab FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO | 67179a0bf528SMauro Carvalho Chehab FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 67189a0bf528SMauro Carvalho Chehab FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS | 67199a0bf528SMauro Carvalho Chehab FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER | 67209a0bf528SMauro Carvalho Chehab FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO 67219a0bf528SMauro Carvalho Chehab }, 67229a0bf528SMauro Carvalho Chehab 67239a0bf528SMauro Carvalho Chehab .release = drxk_release, 67249a0bf528SMauro Carvalho Chehab .sleep = drxk_sleep, 67259a0bf528SMauro Carvalho Chehab .i2c_gate_ctrl = drxk_gate_ctrl, 67269a0bf528SMauro Carvalho Chehab 67279a0bf528SMauro Carvalho Chehab .set_frontend = drxk_set_parameters, 67289a0bf528SMauro Carvalho Chehab .get_tune_settings = drxk_get_tune_settings, 67299a0bf528SMauro Carvalho Chehab 67309a0bf528SMauro Carvalho Chehab .read_status = drxk_read_status, 67319a0bf528SMauro Carvalho Chehab .read_signal_strength = drxk_read_signal_strength, 67329a0bf528SMauro Carvalho Chehab .read_snr = drxk_read_snr, 67339a0bf528SMauro Carvalho Chehab .read_ucblocks = drxk_read_ucblocks, 67349a0bf528SMauro Carvalho Chehab }; 67359a0bf528SMauro Carvalho Chehab 67369a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config, 67379a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c) 67389a0bf528SMauro Carvalho Chehab { 67398f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *p; 67409a0bf528SMauro Carvalho Chehab struct drxk_state *state = NULL; 67419a0bf528SMauro Carvalho Chehab u8 adr = config->adr; 67429a0bf528SMauro Carvalho Chehab int status; 67439a0bf528SMauro Carvalho Chehab 67449a0bf528SMauro Carvalho Chehab dprintk(1, "\n"); 67459a0bf528SMauro Carvalho Chehab state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); 67469a0bf528SMauro Carvalho Chehab if (!state) 67479a0bf528SMauro Carvalho Chehab return NULL; 67489a0bf528SMauro Carvalho Chehab 67499a0bf528SMauro Carvalho Chehab state->i2c = i2c; 67509a0bf528SMauro Carvalho Chehab state->demod_address = adr; 67519a0bf528SMauro Carvalho Chehab state->single_master = config->single_master; 67529a0bf528SMauro Carvalho Chehab state->microcode_name = config->microcode_name; 67539a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count = config->qam_demod_parameter_count; 67549a0bf528SMauro Carvalho Chehab state->no_i2c_bridge = config->no_i2c_bridge; 67559a0bf528SMauro Carvalho Chehab state->antenna_gpio = config->antenna_gpio; 67569a0bf528SMauro Carvalho Chehab state->antenna_dvbt = config->antenna_dvbt; 6757cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = config->chunk_size; 67589a0bf528SMauro Carvalho Chehab state->enable_merr_cfg = config->enable_merr_cfg; 67599a0bf528SMauro Carvalho Chehab 67609a0bf528SMauro Carvalho Chehab if (config->dynamic_clk) { 67615a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = false; 67625a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = false; 67639a0bf528SMauro Carvalho Chehab } else { 67645a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = true; 67655a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = true; 67669a0bf528SMauro Carvalho Chehab } 67679a0bf528SMauro Carvalho Chehab 67689a0bf528SMauro Carvalho Chehab 67699a0bf528SMauro Carvalho Chehab if (config->mpeg_out_clk_strength) 6770cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; 67719a0bf528SMauro Carvalho Chehab else 6772cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = 0x06; 67739a0bf528SMauro Carvalho Chehab 67749a0bf528SMauro Carvalho Chehab if (config->parallel_ts) 6775cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = true; 67769a0bf528SMauro Carvalho Chehab else 6777cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = false; 67789a0bf528SMauro Carvalho Chehab 67799a0bf528SMauro Carvalho Chehab /* NOTE: as more UIO bits will be used, add them to the mask */ 6780cd7a67a4SMauro Carvalho Chehab state->uio_mask = config->antenna_gpio; 67819a0bf528SMauro Carvalho Chehab 67829a0bf528SMauro Carvalho Chehab /* Default gpio to DVB-C */ 67839a0bf528SMauro Carvalho Chehab if (!state->antenna_dvbt && state->antenna_gpio) 6784cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio; 67859a0bf528SMauro Carvalho Chehab else 6786cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio; 67879a0bf528SMauro Carvalho Chehab 67889a0bf528SMauro Carvalho Chehab mutex_init(&state->mutex); 67899a0bf528SMauro Carvalho Chehab 67909a0bf528SMauro Carvalho Chehab memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops)); 67919a0bf528SMauro Carvalho Chehab state->frontend.demodulator_priv = state; 67929a0bf528SMauro Carvalho Chehab 67939a0bf528SMauro Carvalho Chehab init_state(state); 67949a0bf528SMauro Carvalho Chehab 67959a0bf528SMauro Carvalho Chehab /* Load firmware and initialize DRX-K */ 67969a0bf528SMauro Carvalho Chehab if (state->microcode_name) { 67978e30783bSMauro Carvalho Chehab const struct firmware *fw = NULL; 67988e30783bSMauro Carvalho Chehab 67998e30783bSMauro Carvalho Chehab status = request_firmware(&fw, state->microcode_name, 68008e30783bSMauro Carvalho Chehab state->i2c->dev.parent); 68018e30783bSMauro Carvalho Chehab if (status < 0) 68028e30783bSMauro Carvalho Chehab fw = NULL; 68038e30783bSMauro Carvalho Chehab load_firmware_cb(fw, state); 68049a0bf528SMauro Carvalho Chehab } else if (init_drxk(state) < 0) 68059a0bf528SMauro Carvalho Chehab goto error; 68069a0bf528SMauro Carvalho Chehab 68078f3741e0SMauro Carvalho Chehab 68088f3741e0SMauro Carvalho Chehab /* Initialize stats */ 68098f3741e0SMauro Carvalho Chehab p = &state->frontend.dtv_property_cache; 68108f3741e0SMauro Carvalho Chehab p->strength.len = 1; 68118f3741e0SMauro Carvalho Chehab p->cnr.len = 1; 68128f3741e0SMauro Carvalho Chehab p->block_error.len = 1; 68138f3741e0SMauro Carvalho Chehab p->block_count.len = 1; 68148f3741e0SMauro Carvalho Chehab p->pre_bit_error.len = 1; 68158f3741e0SMauro Carvalho Chehab p->pre_bit_count.len = 1; 68168f3741e0SMauro Carvalho Chehab p->post_bit_error.len = 1; 68178f3741e0SMauro Carvalho Chehab p->post_bit_count.len = 1; 68188f3741e0SMauro Carvalho Chehab 68198f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 68208f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68218f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68228f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68238f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68248f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68258f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68268f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68278f3741e0SMauro Carvalho Chehab 68283a4398f5SMauro Carvalho Chehab pr_info("frontend initialized.\n"); 68299a0bf528SMauro Carvalho Chehab return &state->frontend; 68309a0bf528SMauro Carvalho Chehab 68319a0bf528SMauro Carvalho Chehab error: 68323a4398f5SMauro Carvalho Chehab pr_err("not found\n"); 68339a0bf528SMauro Carvalho Chehab kfree(state); 68349a0bf528SMauro Carvalho Chehab return NULL; 68359a0bf528SMauro Carvalho Chehab } 68369a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(drxk_attach); 68379a0bf528SMauro Carvalho Chehab 68389a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver"); 68399a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler"); 68409a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL"); 6841