18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * drxk_hard: DRX-K DVB-C/T demodulator driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2010-2011 Digital Devices GmbH 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/kernel.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/delay.h> 158c2ecf20Sopenharmony_ci#include <linux/firmware.h> 168c2ecf20Sopenharmony_ci#include <linux/i2c.h> 178c2ecf20Sopenharmony_ci#include <linux/hardirq.h> 188c2ecf20Sopenharmony_ci#include <asm/div64.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <media/dvb_frontend.h> 218c2ecf20Sopenharmony_ci#include "drxk.h" 228c2ecf20Sopenharmony_ci#include "drxk_hard.h" 238c2ecf20Sopenharmony_ci#include <media/dvb_math.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic int power_down_dvbt(struct drxk_state *state, bool set_power_mode); 268c2ecf20Sopenharmony_cistatic int power_down_qam(struct drxk_state *state); 278c2ecf20Sopenharmony_cistatic int set_dvbt_standard(struct drxk_state *state, 288c2ecf20Sopenharmony_ci enum operation_mode o_mode); 298c2ecf20Sopenharmony_cistatic int set_qam_standard(struct drxk_state *state, 308c2ecf20Sopenharmony_ci enum operation_mode o_mode); 318c2ecf20Sopenharmony_cistatic int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 328c2ecf20Sopenharmony_ci s32 tuner_freq_offset); 338c2ecf20Sopenharmony_cistatic int set_dvbt_standard(struct drxk_state *state, 348c2ecf20Sopenharmony_ci enum operation_mode o_mode); 358c2ecf20Sopenharmony_cistatic int dvbt_start(struct drxk_state *state); 368c2ecf20Sopenharmony_cistatic int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 378c2ecf20Sopenharmony_ci s32 tuner_freq_offset); 388c2ecf20Sopenharmony_cistatic int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status); 398c2ecf20Sopenharmony_cistatic int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status); 408c2ecf20Sopenharmony_cistatic int switch_antenna_to_qam(struct drxk_state *state); 418c2ecf20Sopenharmony_cistatic int switch_antenna_to_dvbt(struct drxk_state *state); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic bool is_dvbt(struct drxk_state *state) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci return state->m_operation_mode == OM_DVBT; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic bool is_qam(struct drxk_state *state) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci return state->m_operation_mode == OM_QAM_ITU_A || 518c2ecf20Sopenharmony_ci state->m_operation_mode == OM_QAM_ITU_B || 528c2ecf20Sopenharmony_ci state->m_operation_mode == OM_QAM_ITU_C; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define NOA1ROM 0 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0) 588c2ecf20Sopenharmony_ci#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define DEFAULT_MER_83 165 618c2ecf20Sopenharmony_ci#define DEFAULT_MER_93 250 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 648c2ecf20Sopenharmony_ci#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02) 658c2ecf20Sopenharmony_ci#endif 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 688c2ecf20Sopenharmony_ci#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) 698c2ecf20Sopenharmony_ci#endif 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 728c2ecf20Sopenharmony_ci#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#ifndef DRXK_KI_RAGC_ATV 758c2ecf20Sopenharmony_ci#define DRXK_KI_RAGC_ATV 4 768c2ecf20Sopenharmony_ci#endif 778c2ecf20Sopenharmony_ci#ifndef DRXK_KI_IAGC_ATV 788c2ecf20Sopenharmony_ci#define DRXK_KI_IAGC_ATV 6 798c2ecf20Sopenharmony_ci#endif 808c2ecf20Sopenharmony_ci#ifndef DRXK_KI_DAGC_ATV 818c2ecf20Sopenharmony_ci#define DRXK_KI_DAGC_ATV 7 828c2ecf20Sopenharmony_ci#endif 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#ifndef DRXK_KI_RAGC_QAM 858c2ecf20Sopenharmony_ci#define DRXK_KI_RAGC_QAM 3 868c2ecf20Sopenharmony_ci#endif 878c2ecf20Sopenharmony_ci#ifndef DRXK_KI_IAGC_QAM 888c2ecf20Sopenharmony_ci#define DRXK_KI_IAGC_QAM 4 898c2ecf20Sopenharmony_ci#endif 908c2ecf20Sopenharmony_ci#ifndef DRXK_KI_DAGC_QAM 918c2ecf20Sopenharmony_ci#define DRXK_KI_DAGC_QAM 7 928c2ecf20Sopenharmony_ci#endif 938c2ecf20Sopenharmony_ci#ifndef DRXK_KI_RAGC_DVBT 948c2ecf20Sopenharmony_ci#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2) 958c2ecf20Sopenharmony_ci#endif 968c2ecf20Sopenharmony_ci#ifndef DRXK_KI_IAGC_DVBT 978c2ecf20Sopenharmony_ci#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2) 988c2ecf20Sopenharmony_ci#endif 998c2ecf20Sopenharmony_ci#ifndef DRXK_KI_DAGC_DVBT 1008c2ecf20Sopenharmony_ci#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7) 1018c2ecf20Sopenharmony_ci#endif 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#ifndef DRXK_AGC_DAC_OFFSET 1048c2ecf20Sopenharmony_ci#define DRXK_AGC_DAC_OFFSET (0x800) 1058c2ecf20Sopenharmony_ci#endif 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ 1088c2ecf20Sopenharmony_ci#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L) 1098c2ecf20Sopenharmony_ci#endif 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ 1128c2ecf20Sopenharmony_ci#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L) 1138c2ecf20Sopenharmony_ci#endif 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ 1168c2ecf20Sopenharmony_ci#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L) 1178c2ecf20Sopenharmony_ci#endif 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#ifndef DRXK_QAM_SYMBOLRATE_MAX 1208c2ecf20Sopenharmony_ci#define DRXK_QAM_SYMBOLRATE_MAX (7233000) 1218c2ecf20Sopenharmony_ci#endif 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56 1248c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64 1258c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0 1268c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_BG 24 1278c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32 1288c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40 1298c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_TAPS_FM 48 1308c2ecf20Sopenharmony_ci#define DRXK_BL_ROM_OFFSET_UCODE 0 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#define DRXK_BLC_TIMEOUT 100 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define DRXK_BLCC_NR_ELEMENTS_TAPS 2 1358c2ecf20Sopenharmony_ci#define DRXK_BLCC_NR_ELEMENTS_UCODE 6 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci#define DRXK_BLDC_NR_ELEMENTS_TAPS 28 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#ifndef DRXK_OFDM_NE_NOTCH_WIDTH 1408c2ecf20Sopenharmony_ci#define DRXK_OFDM_NE_NOTCH_WIDTH (4) 1418c2ecf20Sopenharmony_ci#endif 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960) 1448c2ecf20Sopenharmony_ci#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480) 1458c2ecf20Sopenharmony_ci#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008) 1468c2ecf20Sopenharmony_ci#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992) 1478c2ecf20Sopenharmony_ci#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520) 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic unsigned int debug; 1508c2ecf20Sopenharmony_cimodule_param(debug, int, 0644); 1518c2ecf20Sopenharmony_ciMODULE_PARM_DESC(debug, "enable debug messages"); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#define dprintk(level, fmt, arg...) do { \ 1548c2ecf20Sopenharmony_ciif (debug >= level) \ 1558c2ecf20Sopenharmony_ci printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ 1568c2ecf20Sopenharmony_ci} while (0) 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic inline u32 Frac28a(u32 a, u32 c) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci int i = 0; 1618c2ecf20Sopenharmony_ci u32 Q1 = 0; 1628c2ecf20Sopenharmony_ci u32 R0 = 0; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ 1658c2ecf20Sopenharmony_ci Q1 = a / c; /* 1668c2ecf20Sopenharmony_ci * integer part, only the 4 least significant 1678c2ecf20Sopenharmony_ci * bits will be visible in the result 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* division using radix 16, 7 nibbles in the result */ 1718c2ecf20Sopenharmony_ci for (i = 0; i < 7; i++) { 1728c2ecf20Sopenharmony_ci Q1 = (Q1 << 4) | (R0 / c); 1738c2ecf20Sopenharmony_ci R0 = (R0 % c) << 4; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci /* rounding */ 1768c2ecf20Sopenharmony_ci if ((R0 >> 3) >= c) 1778c2ecf20Sopenharmony_ci Q1++; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return Q1; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic inline u32 log10times100(u32 value) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci return (100L * intlog10(value)) >> 24; 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/***************************************************************************/ 1888c2ecf20Sopenharmony_ci/* I2C **********************************************************************/ 1898c2ecf20Sopenharmony_ci/***************************************************************************/ 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic int drxk_i2c_lock(struct drxk_state *state) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT); 1948c2ecf20Sopenharmony_ci state->drxk_i2c_exclusive_lock = true; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci return 0; 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void drxk_i2c_unlock(struct drxk_state *state) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci if (!state->drxk_i2c_exclusive_lock) 2028c2ecf20Sopenharmony_ci return; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT); 2058c2ecf20Sopenharmony_ci state->drxk_i2c_exclusive_lock = false; 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, 2098c2ecf20Sopenharmony_ci unsigned len) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci if (state->drxk_i2c_exclusive_lock) 2128c2ecf20Sopenharmony_ci return __i2c_transfer(state->i2c, msgs, len); 2138c2ecf20Sopenharmony_ci else 2148c2ecf20Sopenharmony_ci return i2c_transfer(state->i2c, msgs, len); 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, 2208c2ecf20Sopenharmony_ci .buf = val, .len = 1} 2218c2ecf20Sopenharmony_ci }; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci return drxk_i2c_transfer(state, msgs, 1); 2248c2ecf20Sopenharmony_ci} 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_cistatic int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci int status; 2298c2ecf20Sopenharmony_ci struct i2c_msg msg = { 2308c2ecf20Sopenharmony_ci .addr = adr, .flags = 0, .buf = data, .len = len }; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci dprintk(3, ":"); 2338c2ecf20Sopenharmony_ci if (debug > 2) { 2348c2ecf20Sopenharmony_ci int i; 2358c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 2368c2ecf20Sopenharmony_ci pr_cont(" %02x", data[i]); 2378c2ecf20Sopenharmony_ci pr_cont("\n"); 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci status = drxk_i2c_transfer(state, &msg, 1); 2408c2ecf20Sopenharmony_ci if (status >= 0 && status != 1) 2418c2ecf20Sopenharmony_ci status = -EIO; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci if (status < 0) 2448c2ecf20Sopenharmony_ci pr_err("i2c write error at addr 0x%02x\n", adr); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci return status; 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic int i2c_read(struct drxk_state *state, 2508c2ecf20Sopenharmony_ci u8 adr, u8 *msg, int len, u8 *answ, int alen) 2518c2ecf20Sopenharmony_ci{ 2528c2ecf20Sopenharmony_ci int status; 2538c2ecf20Sopenharmony_ci struct i2c_msg msgs[2] = { 2548c2ecf20Sopenharmony_ci {.addr = adr, .flags = 0, 2558c2ecf20Sopenharmony_ci .buf = msg, .len = len}, 2568c2ecf20Sopenharmony_ci {.addr = adr, .flags = I2C_M_RD, 2578c2ecf20Sopenharmony_ci .buf = answ, .len = alen} 2588c2ecf20Sopenharmony_ci }; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci status = drxk_i2c_transfer(state, msgs, 2); 2618c2ecf20Sopenharmony_ci if (status != 2) { 2628c2ecf20Sopenharmony_ci if (debug > 2) 2638c2ecf20Sopenharmony_ci pr_cont(": ERROR!\n"); 2648c2ecf20Sopenharmony_ci if (status >= 0) 2658c2ecf20Sopenharmony_ci status = -EIO; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci pr_err("i2c read error at addr 0x%02x\n", adr); 2688c2ecf20Sopenharmony_ci return status; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci if (debug > 2) { 2718c2ecf20Sopenharmony_ci int i; 2728c2ecf20Sopenharmony_ci dprintk(2, ": read from"); 2738c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 2748c2ecf20Sopenharmony_ci pr_cont(" %02x", msg[i]); 2758c2ecf20Sopenharmony_ci pr_cont(", value = "); 2768c2ecf20Sopenharmony_ci for (i = 0; i < alen; i++) 2778c2ecf20Sopenharmony_ci pr_cont(" %02x", answ[i]); 2788c2ecf20Sopenharmony_ci pr_cont("\n"); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci return 0; 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci int status; 2868c2ecf20Sopenharmony_ci u8 adr = state->demod_address, mm1[4], mm2[2], len; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if (state->single_master) 2898c2ecf20Sopenharmony_ci flags |= 0xC0; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 2928c2ecf20Sopenharmony_ci mm1[0] = (((reg << 1) & 0xFF) | 0x01); 2938c2ecf20Sopenharmony_ci mm1[1] = ((reg >> 16) & 0xFF); 2948c2ecf20Sopenharmony_ci mm1[2] = ((reg >> 24) & 0xFF) | flags; 2958c2ecf20Sopenharmony_ci mm1[3] = ((reg >> 7) & 0xFF); 2968c2ecf20Sopenharmony_ci len = 4; 2978c2ecf20Sopenharmony_ci } else { 2988c2ecf20Sopenharmony_ci mm1[0] = ((reg << 1) & 0xFF); 2998c2ecf20Sopenharmony_ci mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3008c2ecf20Sopenharmony_ci len = 2; 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3038c2ecf20Sopenharmony_ci status = i2c_read(state, adr, mm1, len, mm2, 2); 3048c2ecf20Sopenharmony_ci if (status < 0) 3058c2ecf20Sopenharmony_ci return status; 3068c2ecf20Sopenharmony_ci if (data) 3078c2ecf20Sopenharmony_ci *data = mm2[0] | (mm2[1] << 8); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci return 0; 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic int read16(struct drxk_state *state, u32 reg, u16 *data) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return read16_flags(state, reg, data, 0); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci int status; 3208c2ecf20Sopenharmony_ci u8 adr = state->demod_address, mm1[4], mm2[4], len; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci if (state->single_master) 3238c2ecf20Sopenharmony_ci flags |= 0xC0; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3268c2ecf20Sopenharmony_ci mm1[0] = (((reg << 1) & 0xFF) | 0x01); 3278c2ecf20Sopenharmony_ci mm1[1] = ((reg >> 16) & 0xFF); 3288c2ecf20Sopenharmony_ci mm1[2] = ((reg >> 24) & 0xFF) | flags; 3298c2ecf20Sopenharmony_ci mm1[3] = ((reg >> 7) & 0xFF); 3308c2ecf20Sopenharmony_ci len = 4; 3318c2ecf20Sopenharmony_ci } else { 3328c2ecf20Sopenharmony_ci mm1[0] = ((reg << 1) & 0xFF); 3338c2ecf20Sopenharmony_ci mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3348c2ecf20Sopenharmony_ci len = 2; 3358c2ecf20Sopenharmony_ci } 3368c2ecf20Sopenharmony_ci dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); 3378c2ecf20Sopenharmony_ci status = i2c_read(state, adr, mm1, len, mm2, 4); 3388c2ecf20Sopenharmony_ci if (status < 0) 3398c2ecf20Sopenharmony_ci return status; 3408c2ecf20Sopenharmony_ci if (data) 3418c2ecf20Sopenharmony_ci *data = mm2[0] | (mm2[1] << 8) | 3428c2ecf20Sopenharmony_ci (mm2[2] << 16) | (mm2[3] << 24); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci return 0; 3458c2ecf20Sopenharmony_ci} 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic int read32(struct drxk_state *state, u32 reg, u32 *data) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci return read32_flags(state, reg, data, 0); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci u8 adr = state->demod_address, mm[6], len; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci if (state->single_master) 3578c2ecf20Sopenharmony_ci flags |= 0xC0; 3588c2ecf20Sopenharmony_ci if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3598c2ecf20Sopenharmony_ci mm[0] = (((reg << 1) & 0xFF) | 0x01); 3608c2ecf20Sopenharmony_ci mm[1] = ((reg >> 16) & 0xFF); 3618c2ecf20Sopenharmony_ci mm[2] = ((reg >> 24) & 0xFF) | flags; 3628c2ecf20Sopenharmony_ci mm[3] = ((reg >> 7) & 0xFF); 3638c2ecf20Sopenharmony_ci len = 4; 3648c2ecf20Sopenharmony_ci } else { 3658c2ecf20Sopenharmony_ci mm[0] = ((reg << 1) & 0xFF); 3668c2ecf20Sopenharmony_ci mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3678c2ecf20Sopenharmony_ci len = 2; 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci mm[len] = data & 0xff; 3708c2ecf20Sopenharmony_ci mm[len + 1] = (data >> 8) & 0xff; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); 3738c2ecf20Sopenharmony_ci return i2c_write(state, adr, mm, len + 2); 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic int write16(struct drxk_state *state, u32 reg, u16 data) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci return write16_flags(state, reg, data, 0); 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_cistatic int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) 3828c2ecf20Sopenharmony_ci{ 3838c2ecf20Sopenharmony_ci u8 adr = state->demod_address, mm[8], len; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci if (state->single_master) 3868c2ecf20Sopenharmony_ci flags |= 0xC0; 3878c2ecf20Sopenharmony_ci if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { 3888c2ecf20Sopenharmony_ci mm[0] = (((reg << 1) & 0xFF) | 0x01); 3898c2ecf20Sopenharmony_ci mm[1] = ((reg >> 16) & 0xFF); 3908c2ecf20Sopenharmony_ci mm[2] = ((reg >> 24) & 0xFF) | flags; 3918c2ecf20Sopenharmony_ci mm[3] = ((reg >> 7) & 0xFF); 3928c2ecf20Sopenharmony_ci len = 4; 3938c2ecf20Sopenharmony_ci } else { 3948c2ecf20Sopenharmony_ci mm[0] = ((reg << 1) & 0xFF); 3958c2ecf20Sopenharmony_ci mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); 3968c2ecf20Sopenharmony_ci len = 2; 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci mm[len] = data & 0xff; 3998c2ecf20Sopenharmony_ci mm[len + 1] = (data >> 8) & 0xff; 4008c2ecf20Sopenharmony_ci mm[len + 2] = (data >> 16) & 0xff; 4018c2ecf20Sopenharmony_ci mm[len + 3] = (data >> 24) & 0xff; 4028c2ecf20Sopenharmony_ci dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci return i2c_write(state, adr, mm, len + 4); 4058c2ecf20Sopenharmony_ci} 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic int write32(struct drxk_state *state, u32 reg, u32 data) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci return write32_flags(state, reg, data, 0); 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_cistatic int write_block(struct drxk_state *state, u32 address, 4138c2ecf20Sopenharmony_ci const int block_size, const u8 p_block[]) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci int status = 0, blk_size = block_size; 4168c2ecf20Sopenharmony_ci u8 flags = 0; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci if (state->single_master) 4198c2ecf20Sopenharmony_ci flags |= 0xC0; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci while (blk_size > 0) { 4228c2ecf20Sopenharmony_ci int chunk = blk_size > state->m_chunk_size ? 4238c2ecf20Sopenharmony_ci state->m_chunk_size : blk_size; 4248c2ecf20Sopenharmony_ci u8 *adr_buf = &state->chunk[0]; 4258c2ecf20Sopenharmony_ci u32 adr_length = 0; 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) { 4288c2ecf20Sopenharmony_ci adr_buf[0] = (((address << 1) & 0xFF) | 0x01); 4298c2ecf20Sopenharmony_ci adr_buf[1] = ((address >> 16) & 0xFF); 4308c2ecf20Sopenharmony_ci adr_buf[2] = ((address >> 24) & 0xFF); 4318c2ecf20Sopenharmony_ci adr_buf[3] = ((address >> 7) & 0xFF); 4328c2ecf20Sopenharmony_ci adr_buf[2] |= flags; 4338c2ecf20Sopenharmony_ci adr_length = 4; 4348c2ecf20Sopenharmony_ci if (chunk == state->m_chunk_size) 4358c2ecf20Sopenharmony_ci chunk -= 2; 4368c2ecf20Sopenharmony_ci } else { 4378c2ecf20Sopenharmony_ci adr_buf[0] = ((address << 1) & 0xFF); 4388c2ecf20Sopenharmony_ci adr_buf[1] = (((address >> 16) & 0x0F) | 4398c2ecf20Sopenharmony_ci ((address >> 18) & 0xF0)); 4408c2ecf20Sopenharmony_ci adr_length = 2; 4418c2ecf20Sopenharmony_ci } 4428c2ecf20Sopenharmony_ci memcpy(&state->chunk[adr_length], p_block, chunk); 4438c2ecf20Sopenharmony_ci dprintk(2, "(0x%08x, 0x%02x)\n", address, flags); 4448c2ecf20Sopenharmony_ci if (debug > 1) { 4458c2ecf20Sopenharmony_ci int i; 4468c2ecf20Sopenharmony_ci if (p_block) 4478c2ecf20Sopenharmony_ci for (i = 0; i < chunk; i++) 4488c2ecf20Sopenharmony_ci pr_cont(" %02x", p_block[i]); 4498c2ecf20Sopenharmony_ci pr_cont("\n"); 4508c2ecf20Sopenharmony_ci } 4518c2ecf20Sopenharmony_ci status = i2c_write(state, state->demod_address, 4528c2ecf20Sopenharmony_ci &state->chunk[0], chunk + adr_length); 4538c2ecf20Sopenharmony_ci if (status < 0) { 4548c2ecf20Sopenharmony_ci pr_err("%s: i2c write error at addr 0x%02x\n", 4558c2ecf20Sopenharmony_ci __func__, address); 4568c2ecf20Sopenharmony_ci break; 4578c2ecf20Sopenharmony_ci } 4588c2ecf20Sopenharmony_ci p_block += chunk; 4598c2ecf20Sopenharmony_ci address += (chunk >> 1); 4608c2ecf20Sopenharmony_ci blk_size -= chunk; 4618c2ecf20Sopenharmony_ci } 4628c2ecf20Sopenharmony_ci return status; 4638c2ecf20Sopenharmony_ci} 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci#ifndef DRXK_MAX_RETRIES_POWERUP 4668c2ecf20Sopenharmony_ci#define DRXK_MAX_RETRIES_POWERUP 20 4678c2ecf20Sopenharmony_ci#endif 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic int power_up_device(struct drxk_state *state) 4708c2ecf20Sopenharmony_ci{ 4718c2ecf20Sopenharmony_ci int status; 4728c2ecf20Sopenharmony_ci u8 data = 0; 4738c2ecf20Sopenharmony_ci u16 retry_count = 0; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci dprintk(1, "\n"); 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci status = i2c_read1(state, state->demod_address, &data); 4788c2ecf20Sopenharmony_ci if (status < 0) { 4798c2ecf20Sopenharmony_ci do { 4808c2ecf20Sopenharmony_ci data = 0; 4818c2ecf20Sopenharmony_ci status = i2c_write(state, state->demod_address, 4828c2ecf20Sopenharmony_ci &data, 1); 4838c2ecf20Sopenharmony_ci usleep_range(10000, 11000); 4848c2ecf20Sopenharmony_ci retry_count++; 4858c2ecf20Sopenharmony_ci if (status < 0) 4868c2ecf20Sopenharmony_ci continue; 4878c2ecf20Sopenharmony_ci status = i2c_read1(state, state->demod_address, 4888c2ecf20Sopenharmony_ci &data); 4898c2ecf20Sopenharmony_ci } while (status < 0 && 4908c2ecf20Sopenharmony_ci (retry_count < DRXK_MAX_RETRIES_POWERUP)); 4918c2ecf20Sopenharmony_ci if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP) 4928c2ecf20Sopenharmony_ci goto error; 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci /* Make sure all clk domains are active */ 4968c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE); 4978c2ecf20Sopenharmony_ci if (status < 0) 4988c2ecf20Sopenharmony_ci goto error; 4998c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 5008c2ecf20Sopenharmony_ci if (status < 0) 5018c2ecf20Sopenharmony_ci goto error; 5028c2ecf20Sopenharmony_ci /* Enable pll lock tests */ 5038c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_PLL_LOCK__A, 1); 5048c2ecf20Sopenharmony_ci if (status < 0) 5058c2ecf20Sopenharmony_ci goto error; 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci state->m_current_power_mode = DRX_POWER_UP; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cierror: 5108c2ecf20Sopenharmony_ci if (status < 0) 5118c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci return status; 5148c2ecf20Sopenharmony_ci} 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_cistatic int init_state(struct drxk_state *state) 5188c2ecf20Sopenharmony_ci{ 5198c2ecf20Sopenharmony_ci /* 5208c2ecf20Sopenharmony_ci * FIXME: most (all?) of the values below should be moved into 5218c2ecf20Sopenharmony_ci * struct drxk_config, as they are probably board-specific 5228c2ecf20Sopenharmony_ci */ 5238c2ecf20Sopenharmony_ci u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; 5248c2ecf20Sopenharmony_ci u32 ul_vsb_if_agc_output_level = 0; 5258c2ecf20Sopenharmony_ci u32 ul_vsb_if_agc_min_level = 0; 5268c2ecf20Sopenharmony_ci u32 ul_vsb_if_agc_max_level = 0x7FFF; 5278c2ecf20Sopenharmony_ci u32 ul_vsb_if_agc_speed = 3; 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO; 5308c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_output_level = 0; 5318c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_min_level = 0; 5328c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_max_level = 0x7FFF; 5338c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_speed = 3; 5348c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_top = 9500; 5358c2ecf20Sopenharmony_ci u32 ul_vsb_rf_agc_cut_off_current = 4000; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO; 5388c2ecf20Sopenharmony_ci u32 ul_atv_if_agc_output_level = 0; 5398c2ecf20Sopenharmony_ci u32 ul_atv_if_agc_min_level = 0; 5408c2ecf20Sopenharmony_ci u32 ul_atv_if_agc_max_level = 0; 5418c2ecf20Sopenharmony_ci u32 ul_atv_if_agc_speed = 3; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF; 5448c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_output_level = 0; 5458c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_min_level = 0; 5468c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_max_level = 0; 5478c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_top = 9500; 5488c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_cut_off_current = 4000; 5498c2ecf20Sopenharmony_ci u32 ul_atv_rf_agc_speed = 3; 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci u32 ulQual83 = DEFAULT_MER_83; 5528c2ecf20Sopenharmony_ci u32 ulQual93 = DEFAULT_MER_93; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 5558c2ecf20Sopenharmony_ci u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ 5588c2ecf20Sopenharmony_ci /* io_pad_cfg_mode output mode is drive always */ 5598c2ecf20Sopenharmony_ci /* io_pad_cfg_drive is set to power 2 (23 mA) */ 5608c2ecf20Sopenharmony_ci u32 ul_gpio_cfg = 0x0113; 5618c2ecf20Sopenharmony_ci u32 ul_invert_ts_clock = 0; 5628c2ecf20Sopenharmony_ci u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; 5638c2ecf20Sopenharmony_ci u32 ul_dvbt_bitrate = 50000000; 5648c2ecf20Sopenharmony_ci u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci u32 ul_insert_rs_byte = 0; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci u32 ul_rf_mirror = 1; 5698c2ecf20Sopenharmony_ci u32 ul_power_down = 0; 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci dprintk(1, "\n"); 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci state->m_has_lna = false; 5748c2ecf20Sopenharmony_ci state->m_has_dvbt = false; 5758c2ecf20Sopenharmony_ci state->m_has_dvbc = false; 5768c2ecf20Sopenharmony_ci state->m_has_atv = false; 5778c2ecf20Sopenharmony_ci state->m_has_oob = false; 5788c2ecf20Sopenharmony_ci state->m_has_audio = false; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci if (!state->m_chunk_size) 5818c2ecf20Sopenharmony_ci state->m_chunk_size = 124; 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci state->m_osc_clock_freq = 0; 5848c2ecf20Sopenharmony_ci state->m_smart_ant_inverted = false; 5858c2ecf20Sopenharmony_ci state->m_b_p_down_open_bridge = false; 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci /* real system clock frequency in kHz */ 5888c2ecf20Sopenharmony_ci state->m_sys_clock_freq = 151875; 5898c2ecf20Sopenharmony_ci /* Timing div, 250ns/Psys */ 5908c2ecf20Sopenharmony_ci /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ 5918c2ecf20Sopenharmony_ci state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) * 5928c2ecf20Sopenharmony_ci HI_I2C_DELAY) / 1000; 5938c2ecf20Sopenharmony_ci /* Clipping */ 5948c2ecf20Sopenharmony_ci if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) 5958c2ecf20Sopenharmony_ci state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; 5968c2ecf20Sopenharmony_ci state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 5978c2ecf20Sopenharmony_ci /* port/bridge/power down ctrl */ 5988c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci state->m_b_power_down = (ul_power_down != 0); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci state->m_drxk_a3_patch_code = false; 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci /* Init AGC and PGA parameters */ 6058c2ecf20Sopenharmony_ci /* VSB IF */ 6068c2ecf20Sopenharmony_ci state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode; 6078c2ecf20Sopenharmony_ci state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level; 6088c2ecf20Sopenharmony_ci state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level; 6098c2ecf20Sopenharmony_ci state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level; 6108c2ecf20Sopenharmony_ci state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed; 6118c2ecf20Sopenharmony_ci state->m_vsb_pga_cfg = 140; 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci /* VSB RF */ 6148c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode; 6158c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level; 6168c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level; 6178c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level; 6188c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed; 6198c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top; 6208c2ecf20Sopenharmony_ci state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current; 6218c2ecf20Sopenharmony_ci state->m_vsb_pre_saw_cfg.reference = 0x07; 6228c2ecf20Sopenharmony_ci state->m_vsb_pre_saw_cfg.use_pre_saw = true; 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci state->m_Quality83percent = DEFAULT_MER_83; 6258c2ecf20Sopenharmony_ci state->m_Quality93percent = DEFAULT_MER_93; 6268c2ecf20Sopenharmony_ci if (ulQual93 <= 500 && ulQual83 < ulQual93) { 6278c2ecf20Sopenharmony_ci state->m_Quality83percent = ulQual83; 6288c2ecf20Sopenharmony_ci state->m_Quality93percent = ulQual93; 6298c2ecf20Sopenharmony_ci } 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci /* ATV IF */ 6328c2ecf20Sopenharmony_ci state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode; 6338c2ecf20Sopenharmony_ci state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level; 6348c2ecf20Sopenharmony_ci state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level; 6358c2ecf20Sopenharmony_ci state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level; 6368c2ecf20Sopenharmony_ci state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci /* ATV RF */ 6398c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode; 6408c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level; 6418c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level; 6428c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level; 6438c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed; 6448c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top; 6458c2ecf20Sopenharmony_ci state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current; 6468c2ecf20Sopenharmony_ci state->m_atv_pre_saw_cfg.reference = 0x04; 6478c2ecf20Sopenharmony_ci state->m_atv_pre_saw_cfg.use_pre_saw = true; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci /* DVBT RF */ 6518c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 6528c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.output_level = 0; 6538c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.min_output_level = 0; 6548c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF; 6558c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.top = 0x2100; 6568c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.cut_off_current = 4000; 6578c2ecf20Sopenharmony_ci state->m_dvbt_rf_agc_cfg.speed = 1; 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci /* DVBT IF */ 6618c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 6628c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.output_level = 0; 6638c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.min_output_level = 0; 6648c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.max_output_level = 9000; 6658c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.top = 13424; 6668c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.cut_off_current = 0; 6678c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.speed = 3; 6688c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30; 6698c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000; 6708c2ecf20Sopenharmony_ci /* state->m_dvbtPgaCfg = 140; */ 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci state->m_dvbt_pre_saw_cfg.reference = 4; 6738c2ecf20Sopenharmony_ci state->m_dvbt_pre_saw_cfg.use_pre_saw = false; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci /* QAM RF */ 6768c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; 6778c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.output_level = 0; 6788c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.min_output_level = 6023; 6798c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.max_output_level = 27000; 6808c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.top = 0x2380; 6818c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.cut_off_current = 4000; 6828c2ecf20Sopenharmony_ci state->m_qam_rf_agc_cfg.speed = 3; 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci /* QAM IF */ 6858c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; 6868c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.output_level = 0; 6878c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.min_output_level = 0; 6888c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.max_output_level = 9000; 6898c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.top = 0x0511; 6908c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.cut_off_current = 0; 6918c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.speed = 3; 6928c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.ingain_tgt_max = 5119; 6938c2ecf20Sopenharmony_ci state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50; 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci state->m_qam_pga_cfg = 140; 6968c2ecf20Sopenharmony_ci state->m_qam_pre_saw_cfg.reference = 4; 6978c2ecf20Sopenharmony_ci state->m_qam_pre_saw_cfg.use_pre_saw = false; 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci state->m_operation_mode = OM_NONE; 7008c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_UNINITIALIZED; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci /* MPEG output configuration */ 7038c2ecf20Sopenharmony_ci state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG output */ 7048c2ecf20Sopenharmony_ci state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */ 7058c2ecf20Sopenharmony_ci state->m_invert_data = false; /* If TRUE; invert DATA signals */ 7068c2ecf20Sopenharmony_ci state->m_invert_err = false; /* If TRUE; invert ERR signal */ 7078c2ecf20Sopenharmony_ci state->m_invert_str = false; /* If TRUE; invert STR signals */ 7088c2ecf20Sopenharmony_ci state->m_invert_val = false; /* If TRUE; invert VAL signals */ 7098c2ecf20Sopenharmony_ci state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */ 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci /* If TRUE; static MPEG clockrate will be used; 7128c2ecf20Sopenharmony_ci otherwise clockrate will adapt to the bitrate of the TS */ 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci state->m_dvbt_bitrate = ul_dvbt_bitrate; 7158c2ecf20Sopenharmony_ci state->m_dvbc_bitrate = ul_dvbc_bitrate; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci state->m_ts_data_strength = (ul_ts_data_strength & 0x07); 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci /* Maximum bitrate in b/s in case static clockrate is selected */ 7208c2ecf20Sopenharmony_ci state->m_mpeg_ts_static_bitrate = 19392658; 7218c2ecf20Sopenharmony_ci state->m_disable_te_ihandling = false; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (ul_insert_rs_byte) 7248c2ecf20Sopenharmony_ci state->m_insert_rs_byte = true; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 7278c2ecf20Sopenharmony_ci if (ul_mpeg_lock_time_out < 10000) 7288c2ecf20Sopenharmony_ci state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out; 7298c2ecf20Sopenharmony_ci state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 7308c2ecf20Sopenharmony_ci if (ul_demod_lock_time_out < 10000) 7318c2ecf20Sopenharmony_ci state->m_demod_lock_time_out = ul_demod_lock_time_out; 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_ci /* QAM defaults */ 7348c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_AUTO; 7358c2ecf20Sopenharmony_ci state->m_qam_interleave_mode = DRXK_QAM_I12_J17; 7368c2ecf20Sopenharmony_ci state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */ 7378c2ecf20Sopenharmony_ci state->m_fec_rs_prescale = 1; 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM; 7408c2ecf20Sopenharmony_ci state->m_agcfast_clip_ctrl_delay = 0; 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci state->m_gpio_cfg = ul_gpio_cfg; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci state->m_b_power_down = false; 7458c2ecf20Sopenharmony_ci state->m_current_power_mode = DRX_POWER_DOWN; 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci state->m_rfmirror = (ul_rf_mirror == 0); 7488c2ecf20Sopenharmony_ci state->m_if_agc_pol = false; 7498c2ecf20Sopenharmony_ci return 0; 7508c2ecf20Sopenharmony_ci} 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistatic int drxx_open(struct drxk_state *state) 7538c2ecf20Sopenharmony_ci{ 7548c2ecf20Sopenharmony_ci int status = 0; 7558c2ecf20Sopenharmony_ci u32 jtag = 0; 7568c2ecf20Sopenharmony_ci u16 bid = 0; 7578c2ecf20Sopenharmony_ci u16 key = 0; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci dprintk(1, "\n"); 7608c2ecf20Sopenharmony_ci /* stop lock indicator process */ 7618c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 7628c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 7638c2ecf20Sopenharmony_ci if (status < 0) 7648c2ecf20Sopenharmony_ci goto error; 7658c2ecf20Sopenharmony_ci /* Check device id */ 7668c2ecf20Sopenharmony_ci status = read16(state, SIO_TOP_COMM_KEY__A, &key); 7678c2ecf20Sopenharmony_ci if (status < 0) 7688c2ecf20Sopenharmony_ci goto error; 7698c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 7708c2ecf20Sopenharmony_ci if (status < 0) 7718c2ecf20Sopenharmony_ci goto error; 7728c2ecf20Sopenharmony_ci status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag); 7738c2ecf20Sopenharmony_ci if (status < 0) 7748c2ecf20Sopenharmony_ci goto error; 7758c2ecf20Sopenharmony_ci status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid); 7768c2ecf20Sopenharmony_ci if (status < 0) 7778c2ecf20Sopenharmony_ci goto error; 7788c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, key); 7798c2ecf20Sopenharmony_cierror: 7808c2ecf20Sopenharmony_ci if (status < 0) 7818c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 7828c2ecf20Sopenharmony_ci return status; 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_cistatic int get_device_capabilities(struct drxk_state *state) 7868c2ecf20Sopenharmony_ci{ 7878c2ecf20Sopenharmony_ci u16 sio_pdr_ohw_cfg = 0; 7888c2ecf20Sopenharmony_ci u32 sio_top_jtagid_lo = 0; 7898c2ecf20Sopenharmony_ci int status; 7908c2ecf20Sopenharmony_ci const char *spin = ""; 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci dprintk(1, "\n"); 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci /* driver 0.9.0 */ 7958c2ecf20Sopenharmony_ci /* stop lock indicator process */ 7968c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 7978c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 7988c2ecf20Sopenharmony_ci if (status < 0) 7998c2ecf20Sopenharmony_ci goto error; 8008c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 8018c2ecf20Sopenharmony_ci if (status < 0) 8028c2ecf20Sopenharmony_ci goto error; 8038c2ecf20Sopenharmony_ci status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg); 8048c2ecf20Sopenharmony_ci if (status < 0) 8058c2ecf20Sopenharmony_ci goto error; 8068c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 8078c2ecf20Sopenharmony_ci if (status < 0) 8088c2ecf20Sopenharmony_ci goto error; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { 8118c2ecf20Sopenharmony_ci case 0: 8128c2ecf20Sopenharmony_ci /* ignore (bypass ?) */ 8138c2ecf20Sopenharmony_ci break; 8148c2ecf20Sopenharmony_ci case 1: 8158c2ecf20Sopenharmony_ci /* 27 MHz */ 8168c2ecf20Sopenharmony_ci state->m_osc_clock_freq = 27000; 8178c2ecf20Sopenharmony_ci break; 8188c2ecf20Sopenharmony_ci case 2: 8198c2ecf20Sopenharmony_ci /* 20.25 MHz */ 8208c2ecf20Sopenharmony_ci state->m_osc_clock_freq = 20250; 8218c2ecf20Sopenharmony_ci break; 8228c2ecf20Sopenharmony_ci case 3: 8238c2ecf20Sopenharmony_ci /* 4 MHz */ 8248c2ecf20Sopenharmony_ci state->m_osc_clock_freq = 20250; 8258c2ecf20Sopenharmony_ci break; 8268c2ecf20Sopenharmony_ci default: 8278c2ecf20Sopenharmony_ci pr_err("Clock Frequency is unknown\n"); 8288c2ecf20Sopenharmony_ci return -EINVAL; 8298c2ecf20Sopenharmony_ci } 8308c2ecf20Sopenharmony_ci /* 8318c2ecf20Sopenharmony_ci Determine device capabilities 8328c2ecf20Sopenharmony_ci Based on pinning v14 8338c2ecf20Sopenharmony_ci */ 8348c2ecf20Sopenharmony_ci status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo); 8358c2ecf20Sopenharmony_ci if (status < 0) 8368c2ecf20Sopenharmony_ci goto error; 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci pr_info("status = 0x%08x\n", sio_top_jtagid_lo); 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci /* driver 0.9.0 */ 8418c2ecf20Sopenharmony_ci switch ((sio_top_jtagid_lo >> 29) & 0xF) { 8428c2ecf20Sopenharmony_ci case 0: 8438c2ecf20Sopenharmony_ci state->m_device_spin = DRXK_SPIN_A1; 8448c2ecf20Sopenharmony_ci spin = "A1"; 8458c2ecf20Sopenharmony_ci break; 8468c2ecf20Sopenharmony_ci case 2: 8478c2ecf20Sopenharmony_ci state->m_device_spin = DRXK_SPIN_A2; 8488c2ecf20Sopenharmony_ci spin = "A2"; 8498c2ecf20Sopenharmony_ci break; 8508c2ecf20Sopenharmony_ci case 3: 8518c2ecf20Sopenharmony_ci state->m_device_spin = DRXK_SPIN_A3; 8528c2ecf20Sopenharmony_ci spin = "A3"; 8538c2ecf20Sopenharmony_ci break; 8548c2ecf20Sopenharmony_ci default: 8558c2ecf20Sopenharmony_ci state->m_device_spin = DRXK_SPIN_UNKNOWN; 8568c2ecf20Sopenharmony_ci status = -EINVAL; 8578c2ecf20Sopenharmony_ci pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF); 8588c2ecf20Sopenharmony_ci goto error2; 8598c2ecf20Sopenharmony_ci } 8608c2ecf20Sopenharmony_ci switch ((sio_top_jtagid_lo >> 12) & 0xFF) { 8618c2ecf20Sopenharmony_ci case 0x13: 8628c2ecf20Sopenharmony_ci /* typeId = DRX3913K_TYPE_ID */ 8638c2ecf20Sopenharmony_ci state->m_has_lna = false; 8648c2ecf20Sopenharmony_ci state->m_has_oob = false; 8658c2ecf20Sopenharmony_ci state->m_has_atv = false; 8668c2ecf20Sopenharmony_ci state->m_has_audio = false; 8678c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 8688c2ecf20Sopenharmony_ci state->m_has_dvbc = true; 8698c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 8708c2ecf20Sopenharmony_ci state->m_has_gpio2 = false; 8718c2ecf20Sopenharmony_ci state->m_has_gpio1 = false; 8728c2ecf20Sopenharmony_ci state->m_has_irqn = false; 8738c2ecf20Sopenharmony_ci break; 8748c2ecf20Sopenharmony_ci case 0x15: 8758c2ecf20Sopenharmony_ci /* typeId = DRX3915K_TYPE_ID */ 8768c2ecf20Sopenharmony_ci state->m_has_lna = false; 8778c2ecf20Sopenharmony_ci state->m_has_oob = false; 8788c2ecf20Sopenharmony_ci state->m_has_atv = true; 8798c2ecf20Sopenharmony_ci state->m_has_audio = false; 8808c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 8818c2ecf20Sopenharmony_ci state->m_has_dvbc = false; 8828c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 8838c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 8848c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 8858c2ecf20Sopenharmony_ci state->m_has_irqn = false; 8868c2ecf20Sopenharmony_ci break; 8878c2ecf20Sopenharmony_ci case 0x16: 8888c2ecf20Sopenharmony_ci /* typeId = DRX3916K_TYPE_ID */ 8898c2ecf20Sopenharmony_ci state->m_has_lna = false; 8908c2ecf20Sopenharmony_ci state->m_has_oob = false; 8918c2ecf20Sopenharmony_ci state->m_has_atv = true; 8928c2ecf20Sopenharmony_ci state->m_has_audio = false; 8938c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 8948c2ecf20Sopenharmony_ci state->m_has_dvbc = false; 8958c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 8968c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 8978c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 8988c2ecf20Sopenharmony_ci state->m_has_irqn = false; 8998c2ecf20Sopenharmony_ci break; 9008c2ecf20Sopenharmony_ci case 0x18: 9018c2ecf20Sopenharmony_ci /* typeId = DRX3918K_TYPE_ID */ 9028c2ecf20Sopenharmony_ci state->m_has_lna = false; 9038c2ecf20Sopenharmony_ci state->m_has_oob = false; 9048c2ecf20Sopenharmony_ci state->m_has_atv = true; 9058c2ecf20Sopenharmony_ci state->m_has_audio = true; 9068c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 9078c2ecf20Sopenharmony_ci state->m_has_dvbc = false; 9088c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 9098c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 9108c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 9118c2ecf20Sopenharmony_ci state->m_has_irqn = false; 9128c2ecf20Sopenharmony_ci break; 9138c2ecf20Sopenharmony_ci case 0x21: 9148c2ecf20Sopenharmony_ci /* typeId = DRX3921K_TYPE_ID */ 9158c2ecf20Sopenharmony_ci state->m_has_lna = false; 9168c2ecf20Sopenharmony_ci state->m_has_oob = false; 9178c2ecf20Sopenharmony_ci state->m_has_atv = true; 9188c2ecf20Sopenharmony_ci state->m_has_audio = true; 9198c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 9208c2ecf20Sopenharmony_ci state->m_has_dvbc = true; 9218c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 9228c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 9238c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 9248c2ecf20Sopenharmony_ci state->m_has_irqn = false; 9258c2ecf20Sopenharmony_ci break; 9268c2ecf20Sopenharmony_ci case 0x23: 9278c2ecf20Sopenharmony_ci /* typeId = DRX3923K_TYPE_ID */ 9288c2ecf20Sopenharmony_ci state->m_has_lna = false; 9298c2ecf20Sopenharmony_ci state->m_has_oob = false; 9308c2ecf20Sopenharmony_ci state->m_has_atv = true; 9318c2ecf20Sopenharmony_ci state->m_has_audio = true; 9328c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 9338c2ecf20Sopenharmony_ci state->m_has_dvbc = true; 9348c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 9358c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 9368c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 9378c2ecf20Sopenharmony_ci state->m_has_irqn = false; 9388c2ecf20Sopenharmony_ci break; 9398c2ecf20Sopenharmony_ci case 0x25: 9408c2ecf20Sopenharmony_ci /* typeId = DRX3925K_TYPE_ID */ 9418c2ecf20Sopenharmony_ci state->m_has_lna = false; 9428c2ecf20Sopenharmony_ci state->m_has_oob = false; 9438c2ecf20Sopenharmony_ci state->m_has_atv = true; 9448c2ecf20Sopenharmony_ci state->m_has_audio = true; 9458c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 9468c2ecf20Sopenharmony_ci state->m_has_dvbc = true; 9478c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 9488c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 9498c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 9508c2ecf20Sopenharmony_ci state->m_has_irqn = false; 9518c2ecf20Sopenharmony_ci break; 9528c2ecf20Sopenharmony_ci case 0x26: 9538c2ecf20Sopenharmony_ci /* typeId = DRX3926K_TYPE_ID */ 9548c2ecf20Sopenharmony_ci state->m_has_lna = false; 9558c2ecf20Sopenharmony_ci state->m_has_oob = false; 9568c2ecf20Sopenharmony_ci state->m_has_atv = true; 9578c2ecf20Sopenharmony_ci state->m_has_audio = false; 9588c2ecf20Sopenharmony_ci state->m_has_dvbt = true; 9598c2ecf20Sopenharmony_ci state->m_has_dvbc = true; 9608c2ecf20Sopenharmony_ci state->m_has_sawsw = true; 9618c2ecf20Sopenharmony_ci state->m_has_gpio2 = true; 9628c2ecf20Sopenharmony_ci state->m_has_gpio1 = true; 9638c2ecf20Sopenharmony_ci state->m_has_irqn = false; 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci default: 9668c2ecf20Sopenharmony_ci pr_err("DeviceID 0x%02x not supported\n", 9678c2ecf20Sopenharmony_ci ((sio_top_jtagid_lo >> 12) & 0xFF)); 9688c2ecf20Sopenharmony_ci status = -EINVAL; 9698c2ecf20Sopenharmony_ci goto error2; 9708c2ecf20Sopenharmony_ci } 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", 9738c2ecf20Sopenharmony_ci ((sio_top_jtagid_lo >> 12) & 0xFF), spin, 9748c2ecf20Sopenharmony_ci state->m_osc_clock_freq / 1000, 9758c2ecf20Sopenharmony_ci state->m_osc_clock_freq % 1000); 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_cierror: 9788c2ecf20Sopenharmony_ci if (status < 0) 9798c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_cierror2: 9828c2ecf20Sopenharmony_ci return status; 9838c2ecf20Sopenharmony_ci} 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_cistatic int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) 9868c2ecf20Sopenharmony_ci{ 9878c2ecf20Sopenharmony_ci int status; 9888c2ecf20Sopenharmony_ci bool powerdown_cmd; 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci dprintk(1, "\n"); 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci /* Write command */ 9938c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd); 9948c2ecf20Sopenharmony_ci if (status < 0) 9958c2ecf20Sopenharmony_ci goto error; 9968c2ecf20Sopenharmony_ci if (cmd == SIO_HI_RA_RAM_CMD_RESET) 9978c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci powerdown_cmd = 10008c2ecf20Sopenharmony_ci (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && 10018c2ecf20Sopenharmony_ci ((state->m_hi_cfg_ctrl) & 10028c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == 10038c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); 10048c2ecf20Sopenharmony_ci if (!powerdown_cmd) { 10058c2ecf20Sopenharmony_ci /* Wait until command rdy */ 10068c2ecf20Sopenharmony_ci u32 retry_count = 0; 10078c2ecf20Sopenharmony_ci u16 wait_cmd; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci do { 10108c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 10118c2ecf20Sopenharmony_ci retry_count += 1; 10128c2ecf20Sopenharmony_ci status = read16(state, SIO_HI_RA_RAM_CMD__A, 10138c2ecf20Sopenharmony_ci &wait_cmd); 10148c2ecf20Sopenharmony_ci } while ((status < 0 || wait_cmd) && (retry_count < DRXK_MAX_RETRIES)); 10158c2ecf20Sopenharmony_ci if (status < 0) 10168c2ecf20Sopenharmony_ci goto error; 10178c2ecf20Sopenharmony_ci status = read16(state, SIO_HI_RA_RAM_RES__A, p_result); 10188c2ecf20Sopenharmony_ci } 10198c2ecf20Sopenharmony_cierror: 10208c2ecf20Sopenharmony_ci if (status < 0) 10218c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci return status; 10248c2ecf20Sopenharmony_ci} 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_cistatic int hi_cfg_command(struct drxk_state *state) 10278c2ecf20Sopenharmony_ci{ 10288c2ecf20Sopenharmony_ci int status; 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci dprintk(1, "\n"); 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci mutex_lock(&state->mutex); 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_6__A, 10358c2ecf20Sopenharmony_ci state->m_hi_cfg_timeout); 10368c2ecf20Sopenharmony_ci if (status < 0) 10378c2ecf20Sopenharmony_ci goto error; 10388c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_5__A, 10398c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl); 10408c2ecf20Sopenharmony_ci if (status < 0) 10418c2ecf20Sopenharmony_ci goto error; 10428c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_4__A, 10438c2ecf20Sopenharmony_ci state->m_hi_cfg_wake_up_key); 10448c2ecf20Sopenharmony_ci if (status < 0) 10458c2ecf20Sopenharmony_ci goto error; 10468c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_3__A, 10478c2ecf20Sopenharmony_ci state->m_hi_cfg_bridge_delay); 10488c2ecf20Sopenharmony_ci if (status < 0) 10498c2ecf20Sopenharmony_ci goto error; 10508c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 10518c2ecf20Sopenharmony_ci state->m_hi_cfg_timing_div); 10528c2ecf20Sopenharmony_ci if (status < 0) 10538c2ecf20Sopenharmony_ci goto error; 10548c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 10558c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 10568c2ecf20Sopenharmony_ci if (status < 0) 10578c2ecf20Sopenharmony_ci goto error; 10588c2ecf20Sopenharmony_ci status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); 10598c2ecf20Sopenharmony_ci if (status < 0) 10608c2ecf20Sopenharmony_ci goto error; 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 10638c2ecf20Sopenharmony_cierror: 10648c2ecf20Sopenharmony_ci mutex_unlock(&state->mutex); 10658c2ecf20Sopenharmony_ci if (status < 0) 10668c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 10678c2ecf20Sopenharmony_ci return status; 10688c2ecf20Sopenharmony_ci} 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_cistatic int init_hi(struct drxk_state *state) 10718c2ecf20Sopenharmony_ci{ 10728c2ecf20Sopenharmony_ci dprintk(1, "\n"); 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_ci state->m_hi_cfg_wake_up_key = (state->demod_address << 1); 10758c2ecf20Sopenharmony_ci state->m_hi_cfg_timeout = 0x96FF; 10768c2ecf20Sopenharmony_ci /* port/bridge/power down ctrl */ 10778c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci return hi_cfg_command(state); 10808c2ecf20Sopenharmony_ci} 10818c2ecf20Sopenharmony_ci 10828c2ecf20Sopenharmony_cistatic int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) 10838c2ecf20Sopenharmony_ci{ 10848c2ecf20Sopenharmony_ci int status; 10858c2ecf20Sopenharmony_ci u16 sio_pdr_mclk_cfg = 0; 10868c2ecf20Sopenharmony_ci u16 sio_pdr_mdx_cfg = 0; 10878c2ecf20Sopenharmony_ci u16 err_cfg = 0; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci dprintk(1, ": mpeg %s, %s mode\n", 10908c2ecf20Sopenharmony_ci mpeg_enable ? "enable" : "disable", 10918c2ecf20Sopenharmony_ci state->m_enable_parallel ? "parallel" : "serial"); 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci /* stop lock indicator process */ 10948c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 10958c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 10968c2ecf20Sopenharmony_ci if (status < 0) 10978c2ecf20Sopenharmony_ci goto error; 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci /* MPEG TS pad configuration */ 11008c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 11018c2ecf20Sopenharmony_ci if (status < 0) 11028c2ecf20Sopenharmony_ci goto error; 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci if (!mpeg_enable) { 11058c2ecf20Sopenharmony_ci /* Set MPEG TS pads to inputmode */ 11068c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000); 11078c2ecf20Sopenharmony_ci if (status < 0) 11088c2ecf20Sopenharmony_ci goto error; 11098c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); 11108c2ecf20Sopenharmony_ci if (status < 0) 11118c2ecf20Sopenharmony_ci goto error; 11128c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000); 11138c2ecf20Sopenharmony_ci if (status < 0) 11148c2ecf20Sopenharmony_ci goto error; 11158c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); 11168c2ecf20Sopenharmony_ci if (status < 0) 11178c2ecf20Sopenharmony_ci goto error; 11188c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000); 11198c2ecf20Sopenharmony_ci if (status < 0) 11208c2ecf20Sopenharmony_ci goto error; 11218c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 11228c2ecf20Sopenharmony_ci if (status < 0) 11238c2ecf20Sopenharmony_ci goto error; 11248c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 11258c2ecf20Sopenharmony_ci if (status < 0) 11268c2ecf20Sopenharmony_ci goto error; 11278c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 11288c2ecf20Sopenharmony_ci if (status < 0) 11298c2ecf20Sopenharmony_ci goto error; 11308c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 11318c2ecf20Sopenharmony_ci if (status < 0) 11328c2ecf20Sopenharmony_ci goto error; 11338c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 11348c2ecf20Sopenharmony_ci if (status < 0) 11358c2ecf20Sopenharmony_ci goto error; 11368c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 11378c2ecf20Sopenharmony_ci if (status < 0) 11388c2ecf20Sopenharmony_ci goto error; 11398c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 11408c2ecf20Sopenharmony_ci if (status < 0) 11418c2ecf20Sopenharmony_ci goto error; 11428c2ecf20Sopenharmony_ci } else { 11438c2ecf20Sopenharmony_ci /* Enable MPEG output */ 11448c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg = 11458c2ecf20Sopenharmony_ci ((state->m_ts_data_strength << 11468c2ecf20Sopenharmony_ci SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003); 11478c2ecf20Sopenharmony_ci sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength << 11488c2ecf20Sopenharmony_ci SIO_PDR_MCLK_CFG_DRIVE__B) | 11498c2ecf20Sopenharmony_ci 0x0003); 11508c2ecf20Sopenharmony_ci 11518c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg); 11528c2ecf20Sopenharmony_ci if (status < 0) 11538c2ecf20Sopenharmony_ci goto error; 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_ci if (state->enable_merr_cfg) 11568c2ecf20Sopenharmony_ci err_cfg = sio_pdr_mdx_cfg; 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); 11598c2ecf20Sopenharmony_ci if (status < 0) 11608c2ecf20Sopenharmony_ci goto error; 11618c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); 11628c2ecf20Sopenharmony_ci if (status < 0) 11638c2ecf20Sopenharmony_ci goto error; 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci if (state->m_enable_parallel) { 11668c2ecf20Sopenharmony_ci /* parallel -> enable MD1 to MD7 */ 11678c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD1_CFG__A, 11688c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11698c2ecf20Sopenharmony_ci if (status < 0) 11708c2ecf20Sopenharmony_ci goto error; 11718c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD2_CFG__A, 11728c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11738c2ecf20Sopenharmony_ci if (status < 0) 11748c2ecf20Sopenharmony_ci goto error; 11758c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD3_CFG__A, 11768c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11778c2ecf20Sopenharmony_ci if (status < 0) 11788c2ecf20Sopenharmony_ci goto error; 11798c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD4_CFG__A, 11808c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11818c2ecf20Sopenharmony_ci if (status < 0) 11828c2ecf20Sopenharmony_ci goto error; 11838c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD5_CFG__A, 11848c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11858c2ecf20Sopenharmony_ci if (status < 0) 11868c2ecf20Sopenharmony_ci goto error; 11878c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD6_CFG__A, 11888c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11898c2ecf20Sopenharmony_ci if (status < 0) 11908c2ecf20Sopenharmony_ci goto error; 11918c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD7_CFG__A, 11928c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg); 11938c2ecf20Sopenharmony_ci if (status < 0) 11948c2ecf20Sopenharmony_ci goto error; 11958c2ecf20Sopenharmony_ci } else { 11968c2ecf20Sopenharmony_ci sio_pdr_mdx_cfg = ((state->m_ts_data_strength << 11978c2ecf20Sopenharmony_ci SIO_PDR_MD0_CFG_DRIVE__B) 11988c2ecf20Sopenharmony_ci | 0x0003); 11998c2ecf20Sopenharmony_ci /* serial -> disable MD1 to MD7 */ 12008c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000); 12018c2ecf20Sopenharmony_ci if (status < 0) 12028c2ecf20Sopenharmony_ci goto error; 12038c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000); 12048c2ecf20Sopenharmony_ci if (status < 0) 12058c2ecf20Sopenharmony_ci goto error; 12068c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000); 12078c2ecf20Sopenharmony_ci if (status < 0) 12088c2ecf20Sopenharmony_ci goto error; 12098c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000); 12108c2ecf20Sopenharmony_ci if (status < 0) 12118c2ecf20Sopenharmony_ci goto error; 12128c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000); 12138c2ecf20Sopenharmony_ci if (status < 0) 12148c2ecf20Sopenharmony_ci goto error; 12158c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000); 12168c2ecf20Sopenharmony_ci if (status < 0) 12178c2ecf20Sopenharmony_ci goto error; 12188c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000); 12198c2ecf20Sopenharmony_ci if (status < 0) 12208c2ecf20Sopenharmony_ci goto error; 12218c2ecf20Sopenharmony_ci } 12228c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg); 12238c2ecf20Sopenharmony_ci if (status < 0) 12248c2ecf20Sopenharmony_ci goto error; 12258c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg); 12268c2ecf20Sopenharmony_ci if (status < 0) 12278c2ecf20Sopenharmony_ci goto error; 12288c2ecf20Sopenharmony_ci } 12298c2ecf20Sopenharmony_ci /* Enable MB output over MPEG pads and ctl input */ 12308c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_MON_CFG__A, 0x0000); 12318c2ecf20Sopenharmony_ci if (status < 0) 12328c2ecf20Sopenharmony_ci goto error; 12338c2ecf20Sopenharmony_ci /* Write nomagic word to enable pdr reg write */ 12348c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 12358c2ecf20Sopenharmony_cierror: 12368c2ecf20Sopenharmony_ci if (status < 0) 12378c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 12388c2ecf20Sopenharmony_ci return status; 12398c2ecf20Sopenharmony_ci} 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_cistatic int mpegts_disable(struct drxk_state *state) 12428c2ecf20Sopenharmony_ci{ 12438c2ecf20Sopenharmony_ci dprintk(1, "\n"); 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci return mpegts_configure_pins(state, false); 12468c2ecf20Sopenharmony_ci} 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_cistatic int bl_chain_cmd(struct drxk_state *state, 12498c2ecf20Sopenharmony_ci u16 rom_offset, u16 nr_of_elements, u32 time_out) 12508c2ecf20Sopenharmony_ci{ 12518c2ecf20Sopenharmony_ci u16 bl_status = 0; 12528c2ecf20Sopenharmony_ci int status; 12538c2ecf20Sopenharmony_ci unsigned long end; 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_ci dprintk(1, "\n"); 12568c2ecf20Sopenharmony_ci mutex_lock(&state->mutex); 12578c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN); 12588c2ecf20Sopenharmony_ci if (status < 0) 12598c2ecf20Sopenharmony_ci goto error; 12608c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset); 12618c2ecf20Sopenharmony_ci if (status < 0) 12628c2ecf20Sopenharmony_ci goto error; 12638c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements); 12648c2ecf20Sopenharmony_ci if (status < 0) 12658c2ecf20Sopenharmony_ci goto error; 12668c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 12678c2ecf20Sopenharmony_ci if (status < 0) 12688c2ecf20Sopenharmony_ci goto error; 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci end = jiffies + msecs_to_jiffies(time_out); 12718c2ecf20Sopenharmony_ci do { 12728c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 12738c2ecf20Sopenharmony_ci status = read16(state, SIO_BL_STATUS__A, &bl_status); 12748c2ecf20Sopenharmony_ci if (status < 0) 12758c2ecf20Sopenharmony_ci goto error; 12768c2ecf20Sopenharmony_ci } while ((bl_status == 0x1) && 12778c2ecf20Sopenharmony_ci ((time_is_after_jiffies(end)))); 12788c2ecf20Sopenharmony_ci 12798c2ecf20Sopenharmony_ci if (bl_status == 0x1) { 12808c2ecf20Sopenharmony_ci pr_err("SIO not ready\n"); 12818c2ecf20Sopenharmony_ci status = -EINVAL; 12828c2ecf20Sopenharmony_ci goto error2; 12838c2ecf20Sopenharmony_ci } 12848c2ecf20Sopenharmony_cierror: 12858c2ecf20Sopenharmony_ci if (status < 0) 12868c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 12878c2ecf20Sopenharmony_cierror2: 12888c2ecf20Sopenharmony_ci mutex_unlock(&state->mutex); 12898c2ecf20Sopenharmony_ci return status; 12908c2ecf20Sopenharmony_ci} 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci 12938c2ecf20Sopenharmony_cistatic int download_microcode(struct drxk_state *state, 12948c2ecf20Sopenharmony_ci const u8 p_mc_image[], u32 length) 12958c2ecf20Sopenharmony_ci{ 12968c2ecf20Sopenharmony_ci const u8 *p_src = p_mc_image; 12978c2ecf20Sopenharmony_ci u32 address; 12988c2ecf20Sopenharmony_ci u16 n_blocks; 12998c2ecf20Sopenharmony_ci u16 block_size; 13008c2ecf20Sopenharmony_ci u32 offset = 0; 13018c2ecf20Sopenharmony_ci u32 i; 13028c2ecf20Sopenharmony_ci int status = 0; 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci dprintk(1, "\n"); 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci /* down the drain (we don't care about MAGIC_WORD) */ 13078c2ecf20Sopenharmony_ci#if 0 13088c2ecf20Sopenharmony_ci /* For future reference */ 13098c2ecf20Sopenharmony_ci drain = (p_src[0] << 8) | p_src[1]; 13108c2ecf20Sopenharmony_ci#endif 13118c2ecf20Sopenharmony_ci p_src += sizeof(u16); 13128c2ecf20Sopenharmony_ci offset += sizeof(u16); 13138c2ecf20Sopenharmony_ci n_blocks = (p_src[0] << 8) | p_src[1]; 13148c2ecf20Sopenharmony_ci p_src += sizeof(u16); 13158c2ecf20Sopenharmony_ci offset += sizeof(u16); 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci for (i = 0; i < n_blocks; i += 1) { 13188c2ecf20Sopenharmony_ci address = (p_src[0] << 24) | (p_src[1] << 16) | 13198c2ecf20Sopenharmony_ci (p_src[2] << 8) | p_src[3]; 13208c2ecf20Sopenharmony_ci p_src += sizeof(u32); 13218c2ecf20Sopenharmony_ci offset += sizeof(u32); 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_ci block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16); 13248c2ecf20Sopenharmony_ci p_src += sizeof(u16); 13258c2ecf20Sopenharmony_ci offset += sizeof(u16); 13268c2ecf20Sopenharmony_ci 13278c2ecf20Sopenharmony_ci#if 0 13288c2ecf20Sopenharmony_ci /* For future reference */ 13298c2ecf20Sopenharmony_ci flags = (p_src[0] << 8) | p_src[1]; 13308c2ecf20Sopenharmony_ci#endif 13318c2ecf20Sopenharmony_ci p_src += sizeof(u16); 13328c2ecf20Sopenharmony_ci offset += sizeof(u16); 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci#if 0 13358c2ecf20Sopenharmony_ci /* For future reference */ 13368c2ecf20Sopenharmony_ci block_crc = (p_src[0] << 8) | p_src[1]; 13378c2ecf20Sopenharmony_ci#endif 13388c2ecf20Sopenharmony_ci p_src += sizeof(u16); 13398c2ecf20Sopenharmony_ci offset += sizeof(u16); 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_ci if (offset + block_size > length) { 13428c2ecf20Sopenharmony_ci pr_err("Firmware is corrupted.\n"); 13438c2ecf20Sopenharmony_ci return -EINVAL; 13448c2ecf20Sopenharmony_ci } 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci status = write_block(state, address, block_size, p_src); 13478c2ecf20Sopenharmony_ci if (status < 0) { 13488c2ecf20Sopenharmony_ci pr_err("Error %d while loading firmware\n", status); 13498c2ecf20Sopenharmony_ci break; 13508c2ecf20Sopenharmony_ci } 13518c2ecf20Sopenharmony_ci p_src += block_size; 13528c2ecf20Sopenharmony_ci offset += block_size; 13538c2ecf20Sopenharmony_ci } 13548c2ecf20Sopenharmony_ci return status; 13558c2ecf20Sopenharmony_ci} 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_cistatic int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable) 13588c2ecf20Sopenharmony_ci{ 13598c2ecf20Sopenharmony_ci int status; 13608c2ecf20Sopenharmony_ci u16 data = 0; 13618c2ecf20Sopenharmony_ci u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; 13628c2ecf20Sopenharmony_ci u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; 13638c2ecf20Sopenharmony_ci unsigned long end; 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci dprintk(1, "\n"); 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci if (!enable) { 13688c2ecf20Sopenharmony_ci desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; 13698c2ecf20Sopenharmony_ci desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; 13708c2ecf20Sopenharmony_ci } 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 13738c2ecf20Sopenharmony_ci if (status >= 0 && data == desired_status) { 13748c2ecf20Sopenharmony_ci /* tokenring already has correct status */ 13758c2ecf20Sopenharmony_ci return status; 13768c2ecf20Sopenharmony_ci } 13778c2ecf20Sopenharmony_ci /* Disable/enable dvbt tokenring bridge */ 13788c2ecf20Sopenharmony_ci status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl); 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT); 13818c2ecf20Sopenharmony_ci do { 13828c2ecf20Sopenharmony_ci status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); 13838c2ecf20Sopenharmony_ci if ((status >= 0 && data == desired_status) 13848c2ecf20Sopenharmony_ci || time_is_after_jiffies(end)) 13858c2ecf20Sopenharmony_ci break; 13868c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 13878c2ecf20Sopenharmony_ci } while (1); 13888c2ecf20Sopenharmony_ci if (data != desired_status) { 13898c2ecf20Sopenharmony_ci pr_err("SIO not ready\n"); 13908c2ecf20Sopenharmony_ci return -EINVAL; 13918c2ecf20Sopenharmony_ci } 13928c2ecf20Sopenharmony_ci return status; 13938c2ecf20Sopenharmony_ci} 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_cistatic int mpegts_stop(struct drxk_state *state) 13968c2ecf20Sopenharmony_ci{ 13978c2ecf20Sopenharmony_ci int status = 0; 13988c2ecf20Sopenharmony_ci u16 fec_oc_snc_mode = 0; 13998c2ecf20Sopenharmony_ci u16 fec_oc_ipr_mode = 0; 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci dprintk(1, "\n"); 14028c2ecf20Sopenharmony_ci 14038c2ecf20Sopenharmony_ci /* Graceful shutdown (byte boundaries) */ 14048c2ecf20Sopenharmony_ci status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 14058c2ecf20Sopenharmony_ci if (status < 0) 14068c2ecf20Sopenharmony_ci goto error; 14078c2ecf20Sopenharmony_ci fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M; 14088c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 14098c2ecf20Sopenharmony_ci if (status < 0) 14108c2ecf20Sopenharmony_ci goto error; 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci /* Suppress MCLK during absence of data */ 14138c2ecf20Sopenharmony_ci status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode); 14148c2ecf20Sopenharmony_ci if (status < 0) 14158c2ecf20Sopenharmony_ci goto error; 14168c2ecf20Sopenharmony_ci fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; 14178c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode); 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_cierror: 14208c2ecf20Sopenharmony_ci if (status < 0) 14218c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 14228c2ecf20Sopenharmony_ci 14238c2ecf20Sopenharmony_ci return status; 14248c2ecf20Sopenharmony_ci} 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_cistatic int scu_command(struct drxk_state *state, 14278c2ecf20Sopenharmony_ci u16 cmd, u8 parameter_len, 14288c2ecf20Sopenharmony_ci u16 *parameter, u8 result_len, u16 *result) 14298c2ecf20Sopenharmony_ci{ 14308c2ecf20Sopenharmony_ci#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15 14318c2ecf20Sopenharmony_ci#error DRXK register mapping no longer compatible with this routine! 14328c2ecf20Sopenharmony_ci#endif 14338c2ecf20Sopenharmony_ci u16 cur_cmd = 0; 14348c2ecf20Sopenharmony_ci int status = -EINVAL; 14358c2ecf20Sopenharmony_ci unsigned long end; 14368c2ecf20Sopenharmony_ci u8 buffer[34]; 14378c2ecf20Sopenharmony_ci int cnt = 0, ii; 14388c2ecf20Sopenharmony_ci const char *p; 14398c2ecf20Sopenharmony_ci char errname[30]; 14408c2ecf20Sopenharmony_ci 14418c2ecf20Sopenharmony_ci dprintk(1, "\n"); 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) || 14448c2ecf20Sopenharmony_ci ((result_len > 0) && (result == NULL))) { 14458c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 14468c2ecf20Sopenharmony_ci return status; 14478c2ecf20Sopenharmony_ci } 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci mutex_lock(&state->mutex); 14508c2ecf20Sopenharmony_ci 14518c2ecf20Sopenharmony_ci /* assume that the command register is ready 14528c2ecf20Sopenharmony_ci since it is checked afterwards */ 14538c2ecf20Sopenharmony_ci if (parameter) { 14548c2ecf20Sopenharmony_ci for (ii = parameter_len - 1; ii >= 0; ii -= 1) { 14558c2ecf20Sopenharmony_ci buffer[cnt++] = (parameter[ii] & 0xFF); 14568c2ecf20Sopenharmony_ci buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF); 14578c2ecf20Sopenharmony_ci } 14588c2ecf20Sopenharmony_ci } 14598c2ecf20Sopenharmony_ci buffer[cnt++] = (cmd & 0xFF); 14608c2ecf20Sopenharmony_ci buffer[cnt++] = ((cmd >> 8) & 0xFF); 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci write_block(state, SCU_RAM_PARAM_0__A - 14638c2ecf20Sopenharmony_ci (parameter_len - 1), cnt, buffer); 14648c2ecf20Sopenharmony_ci /* Wait until SCU has processed command */ 14658c2ecf20Sopenharmony_ci end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME); 14668c2ecf20Sopenharmony_ci do { 14678c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 14688c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd); 14698c2ecf20Sopenharmony_ci if (status < 0) 14708c2ecf20Sopenharmony_ci goto error; 14718c2ecf20Sopenharmony_ci } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); 14728c2ecf20Sopenharmony_ci if (cur_cmd != DRX_SCU_READY) { 14738c2ecf20Sopenharmony_ci pr_err("SCU not ready\n"); 14748c2ecf20Sopenharmony_ci status = -EIO; 14758c2ecf20Sopenharmony_ci goto error2; 14768c2ecf20Sopenharmony_ci } 14778c2ecf20Sopenharmony_ci /* read results */ 14788c2ecf20Sopenharmony_ci if ((result_len > 0) && (result != NULL)) { 14798c2ecf20Sopenharmony_ci s16 err; 14808c2ecf20Sopenharmony_ci int ii; 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci for (ii = result_len - 1; ii >= 0; ii -= 1) { 14838c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_PARAM_0__A - ii, 14848c2ecf20Sopenharmony_ci &result[ii]); 14858c2ecf20Sopenharmony_ci if (status < 0) 14868c2ecf20Sopenharmony_ci goto error; 14878c2ecf20Sopenharmony_ci } 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_ci /* Check if an error was reported by SCU */ 14908c2ecf20Sopenharmony_ci err = (s16)result[0]; 14918c2ecf20Sopenharmony_ci if (err >= 0) 14928c2ecf20Sopenharmony_ci goto error; 14938c2ecf20Sopenharmony_ci 14948c2ecf20Sopenharmony_ci /* check for the known error codes */ 14958c2ecf20Sopenharmony_ci switch (err) { 14968c2ecf20Sopenharmony_ci case SCU_RESULT_UNKCMD: 14978c2ecf20Sopenharmony_ci p = "SCU_RESULT_UNKCMD"; 14988c2ecf20Sopenharmony_ci break; 14998c2ecf20Sopenharmony_ci case SCU_RESULT_UNKSTD: 15008c2ecf20Sopenharmony_ci p = "SCU_RESULT_UNKSTD"; 15018c2ecf20Sopenharmony_ci break; 15028c2ecf20Sopenharmony_ci case SCU_RESULT_SIZE: 15038c2ecf20Sopenharmony_ci p = "SCU_RESULT_SIZE"; 15048c2ecf20Sopenharmony_ci break; 15058c2ecf20Sopenharmony_ci case SCU_RESULT_INVPAR: 15068c2ecf20Sopenharmony_ci p = "SCU_RESULT_INVPAR"; 15078c2ecf20Sopenharmony_ci break; 15088c2ecf20Sopenharmony_ci default: /* Other negative values are errors */ 15098c2ecf20Sopenharmony_ci sprintf(errname, "ERROR: %d\n", err); 15108c2ecf20Sopenharmony_ci p = errname; 15118c2ecf20Sopenharmony_ci } 15128c2ecf20Sopenharmony_ci pr_err("%s while sending cmd 0x%04x with params:", p, cmd); 15138c2ecf20Sopenharmony_ci print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt); 15148c2ecf20Sopenharmony_ci status = -EINVAL; 15158c2ecf20Sopenharmony_ci goto error2; 15168c2ecf20Sopenharmony_ci } 15178c2ecf20Sopenharmony_ci 15188c2ecf20Sopenharmony_cierror: 15198c2ecf20Sopenharmony_ci if (status < 0) 15208c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 15218c2ecf20Sopenharmony_cierror2: 15228c2ecf20Sopenharmony_ci mutex_unlock(&state->mutex); 15238c2ecf20Sopenharmony_ci return status; 15248c2ecf20Sopenharmony_ci} 15258c2ecf20Sopenharmony_ci 15268c2ecf20Sopenharmony_cistatic int set_iqm_af(struct drxk_state *state, bool active) 15278c2ecf20Sopenharmony_ci{ 15288c2ecf20Sopenharmony_ci u16 data = 0; 15298c2ecf20Sopenharmony_ci int status; 15308c2ecf20Sopenharmony_ci 15318c2ecf20Sopenharmony_ci dprintk(1, "\n"); 15328c2ecf20Sopenharmony_ci 15338c2ecf20Sopenharmony_ci /* Configure IQM */ 15348c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 15358c2ecf20Sopenharmony_ci if (status < 0) 15368c2ecf20Sopenharmony_ci goto error; 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci if (!active) { 15398c2ecf20Sopenharmony_ci data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY 15408c2ecf20Sopenharmony_ci | IQM_AF_STDBY_STDBY_AMP_STANDBY 15418c2ecf20Sopenharmony_ci | IQM_AF_STDBY_STDBY_PD_STANDBY 15428c2ecf20Sopenharmony_ci | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY 15438c2ecf20Sopenharmony_ci | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY); 15448c2ecf20Sopenharmony_ci } else { 15458c2ecf20Sopenharmony_ci data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY) 15468c2ecf20Sopenharmony_ci & (~IQM_AF_STDBY_STDBY_AMP_STANDBY) 15478c2ecf20Sopenharmony_ci & (~IQM_AF_STDBY_STDBY_PD_STANDBY) 15488c2ecf20Sopenharmony_ci & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY) 15498c2ecf20Sopenharmony_ci & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY) 15508c2ecf20Sopenharmony_ci ); 15518c2ecf20Sopenharmony_ci } 15528c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 15538c2ecf20Sopenharmony_ci 15548c2ecf20Sopenharmony_cierror: 15558c2ecf20Sopenharmony_ci if (status < 0) 15568c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 15578c2ecf20Sopenharmony_ci return status; 15588c2ecf20Sopenharmony_ci} 15598c2ecf20Sopenharmony_ci 15608c2ecf20Sopenharmony_cistatic int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) 15618c2ecf20Sopenharmony_ci{ 15628c2ecf20Sopenharmony_ci int status = 0; 15638c2ecf20Sopenharmony_ci u16 sio_cc_pwd_mode = 0; 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci dprintk(1, "\n"); 15668c2ecf20Sopenharmony_ci 15678c2ecf20Sopenharmony_ci /* Check arguments */ 15688c2ecf20Sopenharmony_ci if (mode == NULL) 15698c2ecf20Sopenharmony_ci return -EINVAL; 15708c2ecf20Sopenharmony_ci 15718c2ecf20Sopenharmony_ci switch (*mode) { 15728c2ecf20Sopenharmony_ci case DRX_POWER_UP: 15738c2ecf20Sopenharmony_ci sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; 15748c2ecf20Sopenharmony_ci break; 15758c2ecf20Sopenharmony_ci case DRXK_POWER_DOWN_OFDM: 15768c2ecf20Sopenharmony_ci sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM; 15778c2ecf20Sopenharmony_ci break; 15788c2ecf20Sopenharmony_ci case DRXK_POWER_DOWN_CORE: 15798c2ecf20Sopenharmony_ci sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; 15808c2ecf20Sopenharmony_ci break; 15818c2ecf20Sopenharmony_ci case DRXK_POWER_DOWN_PLL: 15828c2ecf20Sopenharmony_ci sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; 15838c2ecf20Sopenharmony_ci break; 15848c2ecf20Sopenharmony_ci case DRX_POWER_DOWN: 15858c2ecf20Sopenharmony_ci sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; 15868c2ecf20Sopenharmony_ci break; 15878c2ecf20Sopenharmony_ci default: 15888c2ecf20Sopenharmony_ci /* Unknow sleep mode */ 15898c2ecf20Sopenharmony_ci return -EINVAL; 15908c2ecf20Sopenharmony_ci } 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci /* If already in requested power mode, do nothing */ 15938c2ecf20Sopenharmony_ci if (state->m_current_power_mode == *mode) 15948c2ecf20Sopenharmony_ci return 0; 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_ci /* For next steps make sure to start from DRX_POWER_UP mode */ 15978c2ecf20Sopenharmony_ci if (state->m_current_power_mode != DRX_POWER_UP) { 15988c2ecf20Sopenharmony_ci status = power_up_device(state); 15998c2ecf20Sopenharmony_ci if (status < 0) 16008c2ecf20Sopenharmony_ci goto error; 16018c2ecf20Sopenharmony_ci status = dvbt_enable_ofdm_token_ring(state, true); 16028c2ecf20Sopenharmony_ci if (status < 0) 16038c2ecf20Sopenharmony_ci goto error; 16048c2ecf20Sopenharmony_ci } 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci if (*mode == DRX_POWER_UP) { 16078c2ecf20Sopenharmony_ci /* Restore analog & pin configuration */ 16088c2ecf20Sopenharmony_ci } else { 16098c2ecf20Sopenharmony_ci /* Power down to requested mode */ 16108c2ecf20Sopenharmony_ci /* Backup some register settings */ 16118c2ecf20Sopenharmony_ci /* Set pins with possible pull-ups connected 16128c2ecf20Sopenharmony_ci to them in input mode */ 16138c2ecf20Sopenharmony_ci /* Analog power down */ 16148c2ecf20Sopenharmony_ci /* ADC power down */ 16158c2ecf20Sopenharmony_ci /* Power down device */ 16168c2ecf20Sopenharmony_ci /* stop all comm_exec */ 16178c2ecf20Sopenharmony_ci /* Stop and power down previous standard */ 16188c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 16198c2ecf20Sopenharmony_ci case OM_DVBT: 16208c2ecf20Sopenharmony_ci status = mpegts_stop(state); 16218c2ecf20Sopenharmony_ci if (status < 0) 16228c2ecf20Sopenharmony_ci goto error; 16238c2ecf20Sopenharmony_ci status = power_down_dvbt(state, false); 16248c2ecf20Sopenharmony_ci if (status < 0) 16258c2ecf20Sopenharmony_ci goto error; 16268c2ecf20Sopenharmony_ci break; 16278c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 16288c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 16298c2ecf20Sopenharmony_ci status = mpegts_stop(state); 16308c2ecf20Sopenharmony_ci if (status < 0) 16318c2ecf20Sopenharmony_ci goto error; 16328c2ecf20Sopenharmony_ci status = power_down_qam(state); 16338c2ecf20Sopenharmony_ci if (status < 0) 16348c2ecf20Sopenharmony_ci goto error; 16358c2ecf20Sopenharmony_ci break; 16368c2ecf20Sopenharmony_ci default: 16378c2ecf20Sopenharmony_ci break; 16388c2ecf20Sopenharmony_ci } 16398c2ecf20Sopenharmony_ci status = dvbt_enable_ofdm_token_ring(state, false); 16408c2ecf20Sopenharmony_ci if (status < 0) 16418c2ecf20Sopenharmony_ci goto error; 16428c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode); 16438c2ecf20Sopenharmony_ci if (status < 0) 16448c2ecf20Sopenharmony_ci goto error; 16458c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 16468c2ecf20Sopenharmony_ci if (status < 0) 16478c2ecf20Sopenharmony_ci goto error; 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_ci if (*mode != DRXK_POWER_DOWN_OFDM) { 16508c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl |= 16518c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 16528c2ecf20Sopenharmony_ci status = hi_cfg_command(state); 16538c2ecf20Sopenharmony_ci if (status < 0) 16548c2ecf20Sopenharmony_ci goto error; 16558c2ecf20Sopenharmony_ci } 16568c2ecf20Sopenharmony_ci } 16578c2ecf20Sopenharmony_ci state->m_current_power_mode = *mode; 16588c2ecf20Sopenharmony_ci 16598c2ecf20Sopenharmony_cierror: 16608c2ecf20Sopenharmony_ci if (status < 0) 16618c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci return status; 16648c2ecf20Sopenharmony_ci} 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_cistatic int power_down_dvbt(struct drxk_state *state, bool set_power_mode) 16678c2ecf20Sopenharmony_ci{ 16688c2ecf20Sopenharmony_ci enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 16698c2ecf20Sopenharmony_ci u16 cmd_result = 0; 16708c2ecf20Sopenharmony_ci u16 data = 0; 16718c2ecf20Sopenharmony_ci int status; 16728c2ecf20Sopenharmony_ci 16738c2ecf20Sopenharmony_ci dprintk(1, "\n"); 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci status = read16(state, SCU_COMM_EXEC__A, &data); 16768c2ecf20Sopenharmony_ci if (status < 0) 16778c2ecf20Sopenharmony_ci goto error; 16788c2ecf20Sopenharmony_ci if (data == SCU_COMM_EXEC_ACTIVE) { 16798c2ecf20Sopenharmony_ci /* Send OFDM stop command */ 16808c2ecf20Sopenharmony_ci status = scu_command(state, 16818c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_OFDM 16828c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 16838c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 16848c2ecf20Sopenharmony_ci if (status < 0) 16858c2ecf20Sopenharmony_ci goto error; 16868c2ecf20Sopenharmony_ci /* Send OFDM reset command */ 16878c2ecf20Sopenharmony_ci status = scu_command(state, 16888c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_OFDM 16898c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 16908c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 16918c2ecf20Sopenharmony_ci if (status < 0) 16928c2ecf20Sopenharmony_ci goto error; 16938c2ecf20Sopenharmony_ci } 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci /* Reset datapath for OFDM, processors first */ 16968c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 16978c2ecf20Sopenharmony_ci if (status < 0) 16988c2ecf20Sopenharmony_ci goto error; 16998c2ecf20Sopenharmony_ci status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 17008c2ecf20Sopenharmony_ci if (status < 0) 17018c2ecf20Sopenharmony_ci goto error; 17028c2ecf20Sopenharmony_ci status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 17038c2ecf20Sopenharmony_ci if (status < 0) 17048c2ecf20Sopenharmony_ci goto error; 17058c2ecf20Sopenharmony_ci 17068c2ecf20Sopenharmony_ci /* powerdown AFE */ 17078c2ecf20Sopenharmony_ci status = set_iqm_af(state, false); 17088c2ecf20Sopenharmony_ci if (status < 0) 17098c2ecf20Sopenharmony_ci goto error; 17108c2ecf20Sopenharmony_ci 17118c2ecf20Sopenharmony_ci /* powerdown to OFDM mode */ 17128c2ecf20Sopenharmony_ci if (set_power_mode) { 17138c2ecf20Sopenharmony_ci status = ctrl_power_mode(state, &power_mode); 17148c2ecf20Sopenharmony_ci if (status < 0) 17158c2ecf20Sopenharmony_ci goto error; 17168c2ecf20Sopenharmony_ci } 17178c2ecf20Sopenharmony_cierror: 17188c2ecf20Sopenharmony_ci if (status < 0) 17198c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 17208c2ecf20Sopenharmony_ci return status; 17218c2ecf20Sopenharmony_ci} 17228c2ecf20Sopenharmony_ci 17238c2ecf20Sopenharmony_cistatic int setoperation_mode(struct drxk_state *state, 17248c2ecf20Sopenharmony_ci enum operation_mode o_mode) 17258c2ecf20Sopenharmony_ci{ 17268c2ecf20Sopenharmony_ci int status = 0; 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci dprintk(1, "\n"); 17298c2ecf20Sopenharmony_ci /* 17308c2ecf20Sopenharmony_ci Stop and power down previous standard 17318c2ecf20Sopenharmony_ci TODO investigate total power down instead of partial 17328c2ecf20Sopenharmony_ci power down depending on "previous" standard. 17338c2ecf20Sopenharmony_ci */ 17348c2ecf20Sopenharmony_ci 17358c2ecf20Sopenharmony_ci /* disable HW lock indicator */ 17368c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 17378c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 17388c2ecf20Sopenharmony_ci if (status < 0) 17398c2ecf20Sopenharmony_ci goto error; 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_ci /* Device is already at the required mode */ 17428c2ecf20Sopenharmony_ci if (state->m_operation_mode == o_mode) 17438c2ecf20Sopenharmony_ci return 0; 17448c2ecf20Sopenharmony_ci 17458c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 17468c2ecf20Sopenharmony_ci /* OM_NONE was added for start up */ 17478c2ecf20Sopenharmony_ci case OM_NONE: 17488c2ecf20Sopenharmony_ci break; 17498c2ecf20Sopenharmony_ci case OM_DVBT: 17508c2ecf20Sopenharmony_ci status = mpegts_stop(state); 17518c2ecf20Sopenharmony_ci if (status < 0) 17528c2ecf20Sopenharmony_ci goto error; 17538c2ecf20Sopenharmony_ci status = power_down_dvbt(state, true); 17548c2ecf20Sopenharmony_ci if (status < 0) 17558c2ecf20Sopenharmony_ci goto error; 17568c2ecf20Sopenharmony_ci state->m_operation_mode = OM_NONE; 17578c2ecf20Sopenharmony_ci break; 17588c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 17598c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 17608c2ecf20Sopenharmony_ci status = mpegts_stop(state); 17618c2ecf20Sopenharmony_ci if (status < 0) 17628c2ecf20Sopenharmony_ci goto error; 17638c2ecf20Sopenharmony_ci status = power_down_qam(state); 17648c2ecf20Sopenharmony_ci if (status < 0) 17658c2ecf20Sopenharmony_ci goto error; 17668c2ecf20Sopenharmony_ci state->m_operation_mode = OM_NONE; 17678c2ecf20Sopenharmony_ci break; 17688c2ecf20Sopenharmony_ci case OM_QAM_ITU_B: 17698c2ecf20Sopenharmony_ci default: 17708c2ecf20Sopenharmony_ci status = -EINVAL; 17718c2ecf20Sopenharmony_ci goto error; 17728c2ecf20Sopenharmony_ci } 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci /* 17758c2ecf20Sopenharmony_ci Power up new standard 17768c2ecf20Sopenharmony_ci */ 17778c2ecf20Sopenharmony_ci switch (o_mode) { 17788c2ecf20Sopenharmony_ci case OM_DVBT: 17798c2ecf20Sopenharmony_ci dprintk(1, ": DVB-T\n"); 17808c2ecf20Sopenharmony_ci state->m_operation_mode = o_mode; 17818c2ecf20Sopenharmony_ci status = set_dvbt_standard(state, o_mode); 17828c2ecf20Sopenharmony_ci if (status < 0) 17838c2ecf20Sopenharmony_ci goto error; 17848c2ecf20Sopenharmony_ci break; 17858c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 17868c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 17878c2ecf20Sopenharmony_ci dprintk(1, ": DVB-C Annex %c\n", 17888c2ecf20Sopenharmony_ci (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C'); 17898c2ecf20Sopenharmony_ci state->m_operation_mode = o_mode; 17908c2ecf20Sopenharmony_ci status = set_qam_standard(state, o_mode); 17918c2ecf20Sopenharmony_ci if (status < 0) 17928c2ecf20Sopenharmony_ci goto error; 17938c2ecf20Sopenharmony_ci break; 17948c2ecf20Sopenharmony_ci case OM_QAM_ITU_B: 17958c2ecf20Sopenharmony_ci default: 17968c2ecf20Sopenharmony_ci status = -EINVAL; 17978c2ecf20Sopenharmony_ci } 17988c2ecf20Sopenharmony_cierror: 17998c2ecf20Sopenharmony_ci if (status < 0) 18008c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 18018c2ecf20Sopenharmony_ci return status; 18028c2ecf20Sopenharmony_ci} 18038c2ecf20Sopenharmony_ci 18048c2ecf20Sopenharmony_cistatic int start(struct drxk_state *state, s32 offset_freq, 18058c2ecf20Sopenharmony_ci s32 intermediate_frequency) 18068c2ecf20Sopenharmony_ci{ 18078c2ecf20Sopenharmony_ci int status = -EINVAL; 18088c2ecf20Sopenharmony_ci 18098c2ecf20Sopenharmony_ci u16 i_freqk_hz; 18108c2ecf20Sopenharmony_ci s32 offsetk_hz = offset_freq / 1000; 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci dprintk(1, "\n"); 18138c2ecf20Sopenharmony_ci if (state->m_drxk_state != DRXK_STOPPED && 18148c2ecf20Sopenharmony_ci state->m_drxk_state != DRXK_DTV_STARTED) 18158c2ecf20Sopenharmony_ci goto error; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON); 18188c2ecf20Sopenharmony_ci 18198c2ecf20Sopenharmony_ci if (intermediate_frequency < 0) { 18208c2ecf20Sopenharmony_ci state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect; 18218c2ecf20Sopenharmony_ci intermediate_frequency = -intermediate_frequency; 18228c2ecf20Sopenharmony_ci } 18238c2ecf20Sopenharmony_ci 18248c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 18258c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 18268c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 18278c2ecf20Sopenharmony_ci i_freqk_hz = (intermediate_frequency / 1000); 18288c2ecf20Sopenharmony_ci status = set_qam(state, i_freqk_hz, offsetk_hz); 18298c2ecf20Sopenharmony_ci if (status < 0) 18308c2ecf20Sopenharmony_ci goto error; 18318c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_DTV_STARTED; 18328c2ecf20Sopenharmony_ci break; 18338c2ecf20Sopenharmony_ci case OM_DVBT: 18348c2ecf20Sopenharmony_ci i_freqk_hz = (intermediate_frequency / 1000); 18358c2ecf20Sopenharmony_ci status = mpegts_stop(state); 18368c2ecf20Sopenharmony_ci if (status < 0) 18378c2ecf20Sopenharmony_ci goto error; 18388c2ecf20Sopenharmony_ci status = set_dvbt(state, i_freqk_hz, offsetk_hz); 18398c2ecf20Sopenharmony_ci if (status < 0) 18408c2ecf20Sopenharmony_ci goto error; 18418c2ecf20Sopenharmony_ci status = dvbt_start(state); 18428c2ecf20Sopenharmony_ci if (status < 0) 18438c2ecf20Sopenharmony_ci goto error; 18448c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_DTV_STARTED; 18458c2ecf20Sopenharmony_ci break; 18468c2ecf20Sopenharmony_ci default: 18478c2ecf20Sopenharmony_ci break; 18488c2ecf20Sopenharmony_ci } 18498c2ecf20Sopenharmony_cierror: 18508c2ecf20Sopenharmony_ci if (status < 0) 18518c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 18528c2ecf20Sopenharmony_ci return status; 18538c2ecf20Sopenharmony_ci} 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_cistatic int shut_down(struct drxk_state *state) 18568c2ecf20Sopenharmony_ci{ 18578c2ecf20Sopenharmony_ci dprintk(1, "\n"); 18588c2ecf20Sopenharmony_ci 18598c2ecf20Sopenharmony_ci mpegts_stop(state); 18608c2ecf20Sopenharmony_ci return 0; 18618c2ecf20Sopenharmony_ci} 18628c2ecf20Sopenharmony_ci 18638c2ecf20Sopenharmony_cistatic int get_lock_status(struct drxk_state *state, u32 *p_lock_status) 18648c2ecf20Sopenharmony_ci{ 18658c2ecf20Sopenharmony_ci int status = -EINVAL; 18668c2ecf20Sopenharmony_ci 18678c2ecf20Sopenharmony_ci dprintk(1, "\n"); 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci if (p_lock_status == NULL) 18708c2ecf20Sopenharmony_ci goto error; 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci *p_lock_status = NOT_LOCKED; 18738c2ecf20Sopenharmony_ci 18748c2ecf20Sopenharmony_ci /* define the SCU command code */ 18758c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 18768c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 18778c2ecf20Sopenharmony_ci case OM_QAM_ITU_B: 18788c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 18798c2ecf20Sopenharmony_ci status = get_qam_lock_status(state, p_lock_status); 18808c2ecf20Sopenharmony_ci break; 18818c2ecf20Sopenharmony_ci case OM_DVBT: 18828c2ecf20Sopenharmony_ci status = get_dvbt_lock_status(state, p_lock_status); 18838c2ecf20Sopenharmony_ci break; 18848c2ecf20Sopenharmony_ci default: 18858c2ecf20Sopenharmony_ci pr_debug("Unsupported operation mode %d in %s\n", 18868c2ecf20Sopenharmony_ci state->m_operation_mode, __func__); 18878c2ecf20Sopenharmony_ci return 0; 18888c2ecf20Sopenharmony_ci } 18898c2ecf20Sopenharmony_cierror: 18908c2ecf20Sopenharmony_ci if (status < 0) 18918c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 18928c2ecf20Sopenharmony_ci return status; 18938c2ecf20Sopenharmony_ci} 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_cistatic int mpegts_start(struct drxk_state *state) 18968c2ecf20Sopenharmony_ci{ 18978c2ecf20Sopenharmony_ci int status; 18988c2ecf20Sopenharmony_ci 18998c2ecf20Sopenharmony_ci u16 fec_oc_snc_mode = 0; 19008c2ecf20Sopenharmony_ci 19018c2ecf20Sopenharmony_ci /* Allow OC to sync again */ 19028c2ecf20Sopenharmony_ci status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); 19038c2ecf20Sopenharmony_ci if (status < 0) 19048c2ecf20Sopenharmony_ci goto error; 19058c2ecf20Sopenharmony_ci fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; 19068c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); 19078c2ecf20Sopenharmony_ci if (status < 0) 19088c2ecf20Sopenharmony_ci goto error; 19098c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_UNLOCK__A, 1); 19108c2ecf20Sopenharmony_cierror: 19118c2ecf20Sopenharmony_ci if (status < 0) 19128c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 19138c2ecf20Sopenharmony_ci return status; 19148c2ecf20Sopenharmony_ci} 19158c2ecf20Sopenharmony_ci 19168c2ecf20Sopenharmony_cistatic int mpegts_dto_init(struct drxk_state *state) 19178c2ecf20Sopenharmony_ci{ 19188c2ecf20Sopenharmony_ci int status; 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci dprintk(1, "\n"); 19218c2ecf20Sopenharmony_ci 19228c2ecf20Sopenharmony_ci /* Rate integration settings */ 19238c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000); 19248c2ecf20Sopenharmony_ci if (status < 0) 19258c2ecf20Sopenharmony_ci goto error; 19268c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C); 19278c2ecf20Sopenharmony_ci if (status < 0) 19288c2ecf20Sopenharmony_ci goto error; 19298c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A); 19308c2ecf20Sopenharmony_ci if (status < 0) 19318c2ecf20Sopenharmony_ci goto error; 19328c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008); 19338c2ecf20Sopenharmony_ci if (status < 0) 19348c2ecf20Sopenharmony_ci goto error; 19358c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006); 19368c2ecf20Sopenharmony_ci if (status < 0) 19378c2ecf20Sopenharmony_ci goto error; 19388c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680); 19398c2ecf20Sopenharmony_ci if (status < 0) 19408c2ecf20Sopenharmony_ci goto error; 19418c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080); 19428c2ecf20Sopenharmony_ci if (status < 0) 19438c2ecf20Sopenharmony_ci goto error; 19448c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4); 19458c2ecf20Sopenharmony_ci if (status < 0) 19468c2ecf20Sopenharmony_ci goto error; 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci /* Additional configuration */ 19498c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_OCR_INVERT__A, 0); 19508c2ecf20Sopenharmony_ci if (status < 0) 19518c2ecf20Sopenharmony_ci goto error; 19528c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_LWM__A, 2); 19538c2ecf20Sopenharmony_ci if (status < 0) 19548c2ecf20Sopenharmony_ci goto error; 19558c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_HWM__A, 12); 19568c2ecf20Sopenharmony_cierror: 19578c2ecf20Sopenharmony_ci if (status < 0) 19588c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 19598c2ecf20Sopenharmony_ci 19608c2ecf20Sopenharmony_ci return status; 19618c2ecf20Sopenharmony_ci} 19628c2ecf20Sopenharmony_ci 19638c2ecf20Sopenharmony_cistatic int mpegts_dto_setup(struct drxk_state *state, 19648c2ecf20Sopenharmony_ci enum operation_mode o_mode) 19658c2ecf20Sopenharmony_ci{ 19668c2ecf20Sopenharmony_ci int status; 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_ci u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */ 19698c2ecf20Sopenharmony_ci u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */ 19708c2ecf20Sopenharmony_ci u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */ 19718c2ecf20Sopenharmony_ci u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */ 19728c2ecf20Sopenharmony_ci u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */ 19738c2ecf20Sopenharmony_ci u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */ 19748c2ecf20Sopenharmony_ci u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */ 19758c2ecf20Sopenharmony_ci u16 fec_oc_tmd_mode = 0; 19768c2ecf20Sopenharmony_ci u16 fec_oc_tmd_int_upd_rate = 0; 19778c2ecf20Sopenharmony_ci u32 max_bit_rate = 0; 19788c2ecf20Sopenharmony_ci bool static_clk = false; 19798c2ecf20Sopenharmony_ci 19808c2ecf20Sopenharmony_ci dprintk(1, "\n"); 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_ci /* Check insertion of the Reed-Solomon parity bytes */ 19838c2ecf20Sopenharmony_ci status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode); 19848c2ecf20Sopenharmony_ci if (status < 0) 19858c2ecf20Sopenharmony_ci goto error; 19868c2ecf20Sopenharmony_ci status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode); 19878c2ecf20Sopenharmony_ci if (status < 0) 19888c2ecf20Sopenharmony_ci goto error; 19898c2ecf20Sopenharmony_ci fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M); 19908c2ecf20Sopenharmony_ci fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); 19918c2ecf20Sopenharmony_ci if (state->m_insert_rs_byte) { 19928c2ecf20Sopenharmony_ci /* enable parity symbol forward */ 19938c2ecf20Sopenharmony_ci fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M; 19948c2ecf20Sopenharmony_ci /* MVAL disable during parity bytes */ 19958c2ecf20Sopenharmony_ci fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; 19968c2ecf20Sopenharmony_ci /* TS burst length to 204 */ 19978c2ecf20Sopenharmony_ci fec_oc_dto_burst_len = 204; 19988c2ecf20Sopenharmony_ci } 19998c2ecf20Sopenharmony_ci 20008c2ecf20Sopenharmony_ci /* Check serial or parallel output */ 20018c2ecf20Sopenharmony_ci fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); 20028c2ecf20Sopenharmony_ci if (!state->m_enable_parallel) { 20038c2ecf20Sopenharmony_ci /* MPEG data output is serial -> set ipr_mode[0] */ 20048c2ecf20Sopenharmony_ci fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; 20058c2ecf20Sopenharmony_ci } 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci switch (o_mode) { 20088c2ecf20Sopenharmony_ci case OM_DVBT: 20098c2ecf20Sopenharmony_ci max_bit_rate = state->m_dvbt_bitrate; 20108c2ecf20Sopenharmony_ci fec_oc_tmd_mode = 3; 20118c2ecf20Sopenharmony_ci fec_oc_rcn_ctl_rate = 0xC00000; 20128c2ecf20Sopenharmony_ci static_clk = state->m_dvbt_static_clk; 20138c2ecf20Sopenharmony_ci break; 20148c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 20158c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 20168c2ecf20Sopenharmony_ci fec_oc_tmd_mode = 0x0004; 20178c2ecf20Sopenharmony_ci fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */ 20188c2ecf20Sopenharmony_ci max_bit_rate = state->m_dvbc_bitrate; 20198c2ecf20Sopenharmony_ci static_clk = state->m_dvbc_static_clk; 20208c2ecf20Sopenharmony_ci break; 20218c2ecf20Sopenharmony_ci default: 20228c2ecf20Sopenharmony_ci status = -EINVAL; 20238c2ecf20Sopenharmony_ci } /* switch (standard) */ 20248c2ecf20Sopenharmony_ci if (status < 0) 20258c2ecf20Sopenharmony_ci goto error; 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci /* Configure DTO's */ 20288c2ecf20Sopenharmony_ci if (static_clk) { 20298c2ecf20Sopenharmony_ci u32 bit_rate = 0; 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_ci /* Rational DTO for MCLK source (static MCLK rate), 20328c2ecf20Sopenharmony_ci Dynamic DTO for optimal grouping 20338c2ecf20Sopenharmony_ci (avoid intra-packet gaps), 20348c2ecf20Sopenharmony_ci DTO offset enable to sync TS burst with MSTRT */ 20358c2ecf20Sopenharmony_ci fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M | 20368c2ecf20Sopenharmony_ci FEC_OC_DTO_MODE_OFFSET_ENABLE__M); 20378c2ecf20Sopenharmony_ci fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M | 20388c2ecf20Sopenharmony_ci FEC_OC_FCT_MODE_VIRT_ENA__M); 20398c2ecf20Sopenharmony_ci 20408c2ecf20Sopenharmony_ci /* Check user defined bitrate */ 20418c2ecf20Sopenharmony_ci bit_rate = max_bit_rate; 20428c2ecf20Sopenharmony_ci if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */ 20438c2ecf20Sopenharmony_ci bit_rate = 75900000UL; 20448c2ecf20Sopenharmony_ci } 20458c2ecf20Sopenharmony_ci /* Rational DTO period: 20468c2ecf20Sopenharmony_ci dto_period = (Fsys / bitrate) - 2 20478c2ecf20Sopenharmony_ci 20488c2ecf20Sopenharmony_ci result should be floored, 20498c2ecf20Sopenharmony_ci to make sure >= requested bitrate 20508c2ecf20Sopenharmony_ci */ 20518c2ecf20Sopenharmony_ci fec_oc_dto_period = (u16) (((state->m_sys_clock_freq) 20528c2ecf20Sopenharmony_ci * 1000) / bit_rate); 20538c2ecf20Sopenharmony_ci if (fec_oc_dto_period <= 2) 20548c2ecf20Sopenharmony_ci fec_oc_dto_period = 0; 20558c2ecf20Sopenharmony_ci else 20568c2ecf20Sopenharmony_ci fec_oc_dto_period -= 2; 20578c2ecf20Sopenharmony_ci fec_oc_tmd_int_upd_rate = 8; 20588c2ecf20Sopenharmony_ci } else { 20598c2ecf20Sopenharmony_ci /* (commonAttr->static_clk == false) => dynamic mode */ 20608c2ecf20Sopenharmony_ci fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M; 20618c2ecf20Sopenharmony_ci fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE; 20628c2ecf20Sopenharmony_ci fec_oc_tmd_int_upd_rate = 5; 20638c2ecf20Sopenharmony_ci } 20648c2ecf20Sopenharmony_ci 20658c2ecf20Sopenharmony_ci /* Write appropriate registers with requested configuration */ 20668c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len); 20678c2ecf20Sopenharmony_ci if (status < 0) 20688c2ecf20Sopenharmony_ci goto error; 20698c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period); 20708c2ecf20Sopenharmony_ci if (status < 0) 20718c2ecf20Sopenharmony_ci goto error; 20728c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode); 20738c2ecf20Sopenharmony_ci if (status < 0) 20748c2ecf20Sopenharmony_ci goto error; 20758c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode); 20768c2ecf20Sopenharmony_ci if (status < 0) 20778c2ecf20Sopenharmony_ci goto error; 20788c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode); 20798c2ecf20Sopenharmony_ci if (status < 0) 20808c2ecf20Sopenharmony_ci goto error; 20818c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode); 20828c2ecf20Sopenharmony_ci if (status < 0) 20838c2ecf20Sopenharmony_ci goto error; 20848c2ecf20Sopenharmony_ci 20858c2ecf20Sopenharmony_ci /* Rate integration settings */ 20868c2ecf20Sopenharmony_ci status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate); 20878c2ecf20Sopenharmony_ci if (status < 0) 20888c2ecf20Sopenharmony_ci goto error; 20898c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, 20908c2ecf20Sopenharmony_ci fec_oc_tmd_int_upd_rate); 20918c2ecf20Sopenharmony_ci if (status < 0) 20928c2ecf20Sopenharmony_ci goto error; 20938c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode); 20948c2ecf20Sopenharmony_cierror: 20958c2ecf20Sopenharmony_ci if (status < 0) 20968c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 20978c2ecf20Sopenharmony_ci return status; 20988c2ecf20Sopenharmony_ci} 20998c2ecf20Sopenharmony_ci 21008c2ecf20Sopenharmony_cistatic int mpegts_configure_polarity(struct drxk_state *state) 21018c2ecf20Sopenharmony_ci{ 21028c2ecf20Sopenharmony_ci u16 fec_oc_reg_ipr_invert = 0; 21038c2ecf20Sopenharmony_ci 21048c2ecf20Sopenharmony_ci /* Data mask for the output data byte */ 21058c2ecf20Sopenharmony_ci u16 invert_data_mask = 21068c2ecf20Sopenharmony_ci FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M | 21078c2ecf20Sopenharmony_ci FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M | 21088c2ecf20Sopenharmony_ci FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M | 21098c2ecf20Sopenharmony_ci FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M; 21108c2ecf20Sopenharmony_ci 21118c2ecf20Sopenharmony_ci dprintk(1, "\n"); 21128c2ecf20Sopenharmony_ci 21138c2ecf20Sopenharmony_ci /* Control selective inversion of output bits */ 21148c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert &= (~(invert_data_mask)); 21158c2ecf20Sopenharmony_ci if (state->m_invert_data) 21168c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert |= invert_data_mask; 21178c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M)); 21188c2ecf20Sopenharmony_ci if (state->m_invert_err) 21198c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M; 21208c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); 21218c2ecf20Sopenharmony_ci if (state->m_invert_str) 21228c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M; 21238c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); 21248c2ecf20Sopenharmony_ci if (state->m_invert_val) 21258c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M; 21268c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); 21278c2ecf20Sopenharmony_ci if (state->m_invert_clk) 21288c2ecf20Sopenharmony_ci fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M; 21298c2ecf20Sopenharmony_ci 21308c2ecf20Sopenharmony_ci return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert); 21318c2ecf20Sopenharmony_ci} 21328c2ecf20Sopenharmony_ci 21338c2ecf20Sopenharmony_ci#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_cistatic int set_agc_rf(struct drxk_state *state, 21368c2ecf20Sopenharmony_ci struct s_cfg_agc *p_agc_cfg, bool is_dtv) 21378c2ecf20Sopenharmony_ci{ 21388c2ecf20Sopenharmony_ci int status = -EINVAL; 21398c2ecf20Sopenharmony_ci u16 data = 0; 21408c2ecf20Sopenharmony_ci struct s_cfg_agc *p_if_agc_settings; 21418c2ecf20Sopenharmony_ci 21428c2ecf20Sopenharmony_ci dprintk(1, "\n"); 21438c2ecf20Sopenharmony_ci 21448c2ecf20Sopenharmony_ci if (p_agc_cfg == NULL) 21458c2ecf20Sopenharmony_ci goto error; 21468c2ecf20Sopenharmony_ci 21478c2ecf20Sopenharmony_ci switch (p_agc_cfg->ctrl_mode) { 21488c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_AUTO: 21498c2ecf20Sopenharmony_ci /* Enable RF AGC DAC */ 21508c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 21518c2ecf20Sopenharmony_ci if (status < 0) 21528c2ecf20Sopenharmony_ci goto error; 21538c2ecf20Sopenharmony_ci data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 21548c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 21558c2ecf20Sopenharmony_ci if (status < 0) 21568c2ecf20Sopenharmony_ci goto error; 21578c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 21588c2ecf20Sopenharmony_ci if (status < 0) 21598c2ecf20Sopenharmony_ci goto error; 21608c2ecf20Sopenharmony_ci 21618c2ecf20Sopenharmony_ci /* Enable SCU RF AGC loop */ 21628c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 21638c2ecf20Sopenharmony_ci 21648c2ecf20Sopenharmony_ci /* Polarity */ 21658c2ecf20Sopenharmony_ci if (state->m_rf_agc_pol) 21668c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21678c2ecf20Sopenharmony_ci else 21688c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 21698c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 21708c2ecf20Sopenharmony_ci if (status < 0) 21718c2ecf20Sopenharmony_ci goto error; 21728c2ecf20Sopenharmony_ci 21738c2ecf20Sopenharmony_ci /* Set speed (using complementary reduction value) */ 21748c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 21758c2ecf20Sopenharmony_ci if (status < 0) 21768c2ecf20Sopenharmony_ci goto error; 21778c2ecf20Sopenharmony_ci 21788c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M; 21798c2ecf20Sopenharmony_ci data |= (~(p_agc_cfg->speed << 21808c2ecf20Sopenharmony_ci SCU_RAM_AGC_KI_RED_RAGC_RED__B) 21818c2ecf20Sopenharmony_ci & SCU_RAM_AGC_KI_RED_RAGC_RED__M); 21828c2ecf20Sopenharmony_ci 21838c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 21848c2ecf20Sopenharmony_ci if (status < 0) 21858c2ecf20Sopenharmony_ci goto error; 21868c2ecf20Sopenharmony_ci 21878c2ecf20Sopenharmony_ci if (is_dvbt(state)) 21888c2ecf20Sopenharmony_ci p_if_agc_settings = &state->m_dvbt_if_agc_cfg; 21898c2ecf20Sopenharmony_ci else if (is_qam(state)) 21908c2ecf20Sopenharmony_ci p_if_agc_settings = &state->m_qam_if_agc_cfg; 21918c2ecf20Sopenharmony_ci else 21928c2ecf20Sopenharmony_ci p_if_agc_settings = &state->m_atv_if_agc_cfg; 21938c2ecf20Sopenharmony_ci if (p_if_agc_settings == NULL) { 21948c2ecf20Sopenharmony_ci status = -EINVAL; 21958c2ecf20Sopenharmony_ci goto error; 21968c2ecf20Sopenharmony_ci } 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_ci /* Set TOP, only if IF-AGC is in AUTO mode */ 21998c2ecf20Sopenharmony_ci if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) { 22008c2ecf20Sopenharmony_ci status = write16(state, 22018c2ecf20Sopenharmony_ci SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 22028c2ecf20Sopenharmony_ci p_agc_cfg->top); 22038c2ecf20Sopenharmony_ci if (status < 0) 22048c2ecf20Sopenharmony_ci goto error; 22058c2ecf20Sopenharmony_ci } 22068c2ecf20Sopenharmony_ci 22078c2ecf20Sopenharmony_ci /* Cut-Off current */ 22088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 22098c2ecf20Sopenharmony_ci p_agc_cfg->cut_off_current); 22108c2ecf20Sopenharmony_ci if (status < 0) 22118c2ecf20Sopenharmony_ci goto error; 22128c2ecf20Sopenharmony_ci 22138c2ecf20Sopenharmony_ci /* Max. output level */ 22148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_MAX__A, 22158c2ecf20Sopenharmony_ci p_agc_cfg->max_output_level); 22168c2ecf20Sopenharmony_ci if (status < 0) 22178c2ecf20Sopenharmony_ci goto error; 22188c2ecf20Sopenharmony_ci 22198c2ecf20Sopenharmony_ci break; 22208c2ecf20Sopenharmony_ci 22218c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_USER: 22228c2ecf20Sopenharmony_ci /* Enable RF AGC DAC */ 22238c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 22248c2ecf20Sopenharmony_ci if (status < 0) 22258c2ecf20Sopenharmony_ci goto error; 22268c2ecf20Sopenharmony_ci data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22278c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 22288c2ecf20Sopenharmony_ci if (status < 0) 22298c2ecf20Sopenharmony_ci goto error; 22308c2ecf20Sopenharmony_ci 22318c2ecf20Sopenharmony_ci /* Disable SCU RF AGC loop */ 22328c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22338c2ecf20Sopenharmony_ci if (status < 0) 22348c2ecf20Sopenharmony_ci goto error; 22358c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 22368c2ecf20Sopenharmony_ci if (state->m_rf_agc_pol) 22378c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22388c2ecf20Sopenharmony_ci else 22398c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; 22408c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22418c2ecf20Sopenharmony_ci if (status < 0) 22428c2ecf20Sopenharmony_ci goto error; 22438c2ecf20Sopenharmony_ci 22448c2ecf20Sopenharmony_ci /* SCU c.o.c. to 0, enabling full control range */ 22458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0); 22468c2ecf20Sopenharmony_ci if (status < 0) 22478c2ecf20Sopenharmony_ci goto error; 22488c2ecf20Sopenharmony_ci 22498c2ecf20Sopenharmony_ci /* Write value to output pin */ 22508c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 22518c2ecf20Sopenharmony_ci p_agc_cfg->output_level); 22528c2ecf20Sopenharmony_ci if (status < 0) 22538c2ecf20Sopenharmony_ci goto error; 22548c2ecf20Sopenharmony_ci break; 22558c2ecf20Sopenharmony_ci 22568c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_OFF: 22578c2ecf20Sopenharmony_ci /* Disable RF AGC DAC */ 22588c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 22598c2ecf20Sopenharmony_ci if (status < 0) 22608c2ecf20Sopenharmony_ci goto error; 22618c2ecf20Sopenharmony_ci data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY; 22628c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 22638c2ecf20Sopenharmony_ci if (status < 0) 22648c2ecf20Sopenharmony_ci goto error; 22658c2ecf20Sopenharmony_ci 22668c2ecf20Sopenharmony_ci /* Disable SCU RF AGC loop */ 22678c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 22688c2ecf20Sopenharmony_ci if (status < 0) 22698c2ecf20Sopenharmony_ci goto error; 22708c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; 22718c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 22728c2ecf20Sopenharmony_ci if (status < 0) 22738c2ecf20Sopenharmony_ci goto error; 22748c2ecf20Sopenharmony_ci break; 22758c2ecf20Sopenharmony_ci 22768c2ecf20Sopenharmony_ci default: 22778c2ecf20Sopenharmony_ci status = -EINVAL; 22788c2ecf20Sopenharmony_ci 22798c2ecf20Sopenharmony_ci } 22808c2ecf20Sopenharmony_cierror: 22818c2ecf20Sopenharmony_ci if (status < 0) 22828c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 22838c2ecf20Sopenharmony_ci return status; 22848c2ecf20Sopenharmony_ci} 22858c2ecf20Sopenharmony_ci 22868c2ecf20Sopenharmony_ci#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000 22878c2ecf20Sopenharmony_ci 22888c2ecf20Sopenharmony_cistatic int set_agc_if(struct drxk_state *state, 22898c2ecf20Sopenharmony_ci struct s_cfg_agc *p_agc_cfg, bool is_dtv) 22908c2ecf20Sopenharmony_ci{ 22918c2ecf20Sopenharmony_ci u16 data = 0; 22928c2ecf20Sopenharmony_ci int status = 0; 22938c2ecf20Sopenharmony_ci struct s_cfg_agc *p_rf_agc_settings; 22948c2ecf20Sopenharmony_ci 22958c2ecf20Sopenharmony_ci dprintk(1, "\n"); 22968c2ecf20Sopenharmony_ci 22978c2ecf20Sopenharmony_ci switch (p_agc_cfg->ctrl_mode) { 22988c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_AUTO: 22998c2ecf20Sopenharmony_ci 23008c2ecf20Sopenharmony_ci /* Enable IF AGC DAC */ 23018c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 23028c2ecf20Sopenharmony_ci if (status < 0) 23038c2ecf20Sopenharmony_ci goto error; 23048c2ecf20Sopenharmony_ci data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23058c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 23068c2ecf20Sopenharmony_ci if (status < 0) 23078c2ecf20Sopenharmony_ci goto error; 23088c2ecf20Sopenharmony_ci 23098c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23108c2ecf20Sopenharmony_ci if (status < 0) 23118c2ecf20Sopenharmony_ci goto error; 23128c2ecf20Sopenharmony_ci 23138c2ecf20Sopenharmony_ci /* Enable SCU IF AGC loop */ 23148c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23158c2ecf20Sopenharmony_ci 23168c2ecf20Sopenharmony_ci /* Polarity */ 23178c2ecf20Sopenharmony_ci if (state->m_if_agc_pol) 23188c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23198c2ecf20Sopenharmony_ci else 23208c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23218c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23228c2ecf20Sopenharmony_ci if (status < 0) 23238c2ecf20Sopenharmony_ci goto error; 23248c2ecf20Sopenharmony_ci 23258c2ecf20Sopenharmony_ci /* Set speed (using complementary reduction value) */ 23268c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_KI_RED__A, &data); 23278c2ecf20Sopenharmony_ci if (status < 0) 23288c2ecf20Sopenharmony_ci goto error; 23298c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M; 23308c2ecf20Sopenharmony_ci data |= (~(p_agc_cfg->speed << 23318c2ecf20Sopenharmony_ci SCU_RAM_AGC_KI_RED_IAGC_RED__B) 23328c2ecf20Sopenharmony_ci & SCU_RAM_AGC_KI_RED_IAGC_RED__M); 23338c2ecf20Sopenharmony_ci 23348c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_RED__A, data); 23358c2ecf20Sopenharmony_ci if (status < 0) 23368c2ecf20Sopenharmony_ci goto error; 23378c2ecf20Sopenharmony_ci 23388c2ecf20Sopenharmony_ci if (is_qam(state)) 23398c2ecf20Sopenharmony_ci p_rf_agc_settings = &state->m_qam_rf_agc_cfg; 23408c2ecf20Sopenharmony_ci else 23418c2ecf20Sopenharmony_ci p_rf_agc_settings = &state->m_atv_rf_agc_cfg; 23428c2ecf20Sopenharmony_ci if (p_rf_agc_settings == NULL) 23438c2ecf20Sopenharmony_ci return -1; 23448c2ecf20Sopenharmony_ci /* Restore TOP */ 23458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 23468c2ecf20Sopenharmony_ci p_rf_agc_settings->top); 23478c2ecf20Sopenharmony_ci if (status < 0) 23488c2ecf20Sopenharmony_ci goto error; 23498c2ecf20Sopenharmony_ci break; 23508c2ecf20Sopenharmony_ci 23518c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_USER: 23528c2ecf20Sopenharmony_ci 23538c2ecf20Sopenharmony_ci /* Enable IF AGC DAC */ 23548c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 23558c2ecf20Sopenharmony_ci if (status < 0) 23568c2ecf20Sopenharmony_ci goto error; 23578c2ecf20Sopenharmony_ci data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23588c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 23598c2ecf20Sopenharmony_ci if (status < 0) 23608c2ecf20Sopenharmony_ci goto error; 23618c2ecf20Sopenharmony_ci 23628c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23638c2ecf20Sopenharmony_ci if (status < 0) 23648c2ecf20Sopenharmony_ci goto error; 23658c2ecf20Sopenharmony_ci 23668c2ecf20Sopenharmony_ci /* Disable SCU IF AGC loop */ 23678c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 23688c2ecf20Sopenharmony_ci 23698c2ecf20Sopenharmony_ci /* Polarity */ 23708c2ecf20Sopenharmony_ci if (state->m_if_agc_pol) 23718c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23728c2ecf20Sopenharmony_ci else 23738c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; 23748c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 23758c2ecf20Sopenharmony_ci if (status < 0) 23768c2ecf20Sopenharmony_ci goto error; 23778c2ecf20Sopenharmony_ci 23788c2ecf20Sopenharmony_ci /* Write value to output pin */ 23798c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 23808c2ecf20Sopenharmony_ci p_agc_cfg->output_level); 23818c2ecf20Sopenharmony_ci if (status < 0) 23828c2ecf20Sopenharmony_ci goto error; 23838c2ecf20Sopenharmony_ci break; 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_ci case DRXK_AGC_CTRL_OFF: 23868c2ecf20Sopenharmony_ci 23878c2ecf20Sopenharmony_ci /* Disable If AGC DAC */ 23888c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_STDBY__A, &data); 23898c2ecf20Sopenharmony_ci if (status < 0) 23908c2ecf20Sopenharmony_ci goto error; 23918c2ecf20Sopenharmony_ci data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY; 23928c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_STDBY__A, data); 23938c2ecf20Sopenharmony_ci if (status < 0) 23948c2ecf20Sopenharmony_ci goto error; 23958c2ecf20Sopenharmony_ci 23968c2ecf20Sopenharmony_ci /* Disable SCU IF AGC loop */ 23978c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_CONFIG__A, &data); 23988c2ecf20Sopenharmony_ci if (status < 0) 23998c2ecf20Sopenharmony_ci goto error; 24008c2ecf20Sopenharmony_ci data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; 24018c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CONFIG__A, data); 24028c2ecf20Sopenharmony_ci if (status < 0) 24038c2ecf20Sopenharmony_ci goto error; 24048c2ecf20Sopenharmony_ci break; 24058c2ecf20Sopenharmony_ci } /* switch (agcSettingsIf->ctrl_mode) */ 24068c2ecf20Sopenharmony_ci 24078c2ecf20Sopenharmony_ci /* always set the top to support 24088c2ecf20Sopenharmony_ci configurations without if-loop */ 24098c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top); 24108c2ecf20Sopenharmony_cierror: 24118c2ecf20Sopenharmony_ci if (status < 0) 24128c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 24138c2ecf20Sopenharmony_ci return status; 24148c2ecf20Sopenharmony_ci} 24158c2ecf20Sopenharmony_ci 24168c2ecf20Sopenharmony_cistatic int get_qam_signal_to_noise(struct drxk_state *state, 24178c2ecf20Sopenharmony_ci s32 *p_signal_to_noise) 24188c2ecf20Sopenharmony_ci{ 24198c2ecf20Sopenharmony_ci int status = 0; 24208c2ecf20Sopenharmony_ci u16 qam_sl_err_power = 0; /* accum. error between 24218c2ecf20Sopenharmony_ci raw and sliced symbols */ 24228c2ecf20Sopenharmony_ci u32 qam_sl_sig_power = 0; /* used for MER, depends of 24238c2ecf20Sopenharmony_ci QAM modulation */ 24248c2ecf20Sopenharmony_ci u32 qam_sl_mer = 0; /* QAM MER */ 24258c2ecf20Sopenharmony_ci 24268c2ecf20Sopenharmony_ci dprintk(1, "\n"); 24278c2ecf20Sopenharmony_ci 24288c2ecf20Sopenharmony_ci /* MER calculation */ 24298c2ecf20Sopenharmony_ci 24308c2ecf20Sopenharmony_ci /* get the register value needed for MER */ 24318c2ecf20Sopenharmony_ci status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power); 24328c2ecf20Sopenharmony_ci if (status < 0) { 24338c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 24348c2ecf20Sopenharmony_ci return -EINVAL; 24358c2ecf20Sopenharmony_ci } 24368c2ecf20Sopenharmony_ci 24378c2ecf20Sopenharmony_ci switch (state->props.modulation) { 24388c2ecf20Sopenharmony_ci case QAM_16: 24398c2ecf20Sopenharmony_ci qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; 24408c2ecf20Sopenharmony_ci break; 24418c2ecf20Sopenharmony_ci case QAM_32: 24428c2ecf20Sopenharmony_ci qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; 24438c2ecf20Sopenharmony_ci break; 24448c2ecf20Sopenharmony_ci case QAM_64: 24458c2ecf20Sopenharmony_ci qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; 24468c2ecf20Sopenharmony_ci break; 24478c2ecf20Sopenharmony_ci case QAM_128: 24488c2ecf20Sopenharmony_ci qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; 24498c2ecf20Sopenharmony_ci break; 24508c2ecf20Sopenharmony_ci default: 24518c2ecf20Sopenharmony_ci case QAM_256: 24528c2ecf20Sopenharmony_ci qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; 24538c2ecf20Sopenharmony_ci break; 24548c2ecf20Sopenharmony_ci } 24558c2ecf20Sopenharmony_ci 24568c2ecf20Sopenharmony_ci if (qam_sl_err_power > 0) { 24578c2ecf20Sopenharmony_ci qam_sl_mer = log10times100(qam_sl_sig_power) - 24588c2ecf20Sopenharmony_ci log10times100((u32) qam_sl_err_power); 24598c2ecf20Sopenharmony_ci } 24608c2ecf20Sopenharmony_ci *p_signal_to_noise = qam_sl_mer; 24618c2ecf20Sopenharmony_ci 24628c2ecf20Sopenharmony_ci return status; 24638c2ecf20Sopenharmony_ci} 24648c2ecf20Sopenharmony_ci 24658c2ecf20Sopenharmony_cistatic int get_dvbt_signal_to_noise(struct drxk_state *state, 24668c2ecf20Sopenharmony_ci s32 *p_signal_to_noise) 24678c2ecf20Sopenharmony_ci{ 24688c2ecf20Sopenharmony_ci int status; 24698c2ecf20Sopenharmony_ci u16 reg_data = 0; 24708c2ecf20Sopenharmony_ci u32 eq_reg_td_sqr_err_i = 0; 24718c2ecf20Sopenharmony_ci u32 eq_reg_td_sqr_err_q = 0; 24728c2ecf20Sopenharmony_ci u16 eq_reg_td_sqr_err_exp = 0; 24738c2ecf20Sopenharmony_ci u16 eq_reg_td_tps_pwr_ofs = 0; 24748c2ecf20Sopenharmony_ci u16 eq_reg_td_req_smb_cnt = 0; 24758c2ecf20Sopenharmony_ci u32 tps_cnt = 0; 24768c2ecf20Sopenharmony_ci u32 sqr_err_iq = 0; 24778c2ecf20Sopenharmony_ci u32 a = 0; 24788c2ecf20Sopenharmony_ci u32 b = 0; 24798c2ecf20Sopenharmony_ci u32 c = 0; 24808c2ecf20Sopenharmony_ci u32 i_mer = 0; 24818c2ecf20Sopenharmony_ci u16 transmission_params = 0; 24828c2ecf20Sopenharmony_ci 24838c2ecf20Sopenharmony_ci dprintk(1, "\n"); 24848c2ecf20Sopenharmony_ci 24858c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, 24868c2ecf20Sopenharmony_ci &eq_reg_td_tps_pwr_ofs); 24878c2ecf20Sopenharmony_ci if (status < 0) 24888c2ecf20Sopenharmony_ci goto error; 24898c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, 24908c2ecf20Sopenharmony_ci &eq_reg_td_req_smb_cnt); 24918c2ecf20Sopenharmony_ci if (status < 0) 24928c2ecf20Sopenharmony_ci goto error; 24938c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, 24948c2ecf20Sopenharmony_ci &eq_reg_td_sqr_err_exp); 24958c2ecf20Sopenharmony_ci if (status < 0) 24968c2ecf20Sopenharmony_ci goto error; 24978c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, 24988c2ecf20Sopenharmony_ci ®_data); 24998c2ecf20Sopenharmony_ci if (status < 0) 25008c2ecf20Sopenharmony_ci goto error; 25018c2ecf20Sopenharmony_ci /* Extend SQR_ERR_I operational range */ 25028c2ecf20Sopenharmony_ci eq_reg_td_sqr_err_i = (u32) reg_data; 25038c2ecf20Sopenharmony_ci if ((eq_reg_td_sqr_err_exp > 11) && 25048c2ecf20Sopenharmony_ci (eq_reg_td_sqr_err_i < 0x00000FFFUL)) { 25058c2ecf20Sopenharmony_ci eq_reg_td_sqr_err_i += 0x00010000UL; 25068c2ecf20Sopenharmony_ci } 25078c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data); 25088c2ecf20Sopenharmony_ci if (status < 0) 25098c2ecf20Sopenharmony_ci goto error; 25108c2ecf20Sopenharmony_ci /* Extend SQR_ERR_Q operational range */ 25118c2ecf20Sopenharmony_ci eq_reg_td_sqr_err_q = (u32) reg_data; 25128c2ecf20Sopenharmony_ci if ((eq_reg_td_sqr_err_exp > 11) && 25138c2ecf20Sopenharmony_ci (eq_reg_td_sqr_err_q < 0x00000FFFUL)) 25148c2ecf20Sopenharmony_ci eq_reg_td_sqr_err_q += 0x00010000UL; 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, 25178c2ecf20Sopenharmony_ci &transmission_params); 25188c2ecf20Sopenharmony_ci if (status < 0) 25198c2ecf20Sopenharmony_ci goto error; 25208c2ecf20Sopenharmony_ci 25218c2ecf20Sopenharmony_ci /* Check input data for MER */ 25228c2ecf20Sopenharmony_ci 25238c2ecf20Sopenharmony_ci /* MER calculation (in 0.1 dB) without math.h */ 25248c2ecf20Sopenharmony_ci if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0)) 25258c2ecf20Sopenharmony_ci i_mer = 0; 25268c2ecf20Sopenharmony_ci else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) { 25278c2ecf20Sopenharmony_ci /* No error at all, this must be the HW reset value 25288c2ecf20Sopenharmony_ci * Apparently no first measurement yet 25298c2ecf20Sopenharmony_ci * Set MER to 0.0 */ 25308c2ecf20Sopenharmony_ci i_mer = 0; 25318c2ecf20Sopenharmony_ci } else { 25328c2ecf20Sopenharmony_ci sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) << 25338c2ecf20Sopenharmony_ci eq_reg_td_sqr_err_exp; 25348c2ecf20Sopenharmony_ci if ((transmission_params & 25358c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_OP_PARAM_MODE__M) 25368c2ecf20Sopenharmony_ci == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K) 25378c2ecf20Sopenharmony_ci tps_cnt = 17; 25388c2ecf20Sopenharmony_ci else 25398c2ecf20Sopenharmony_ci tps_cnt = 68; 25408c2ecf20Sopenharmony_ci 25418c2ecf20Sopenharmony_ci /* IMER = 100 * log10 (x) 25428c2ecf20Sopenharmony_ci where x = (eq_reg_td_tps_pwr_ofs^2 * 25438c2ecf20Sopenharmony_ci eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq 25448c2ecf20Sopenharmony_ci 25458c2ecf20Sopenharmony_ci => IMER = a + b -c 25468c2ecf20Sopenharmony_ci where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2) 25478c2ecf20Sopenharmony_ci b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt) 25488c2ecf20Sopenharmony_ci c = 100 * log10 (sqr_err_iq) 25498c2ecf20Sopenharmony_ci */ 25508c2ecf20Sopenharmony_ci 25518c2ecf20Sopenharmony_ci /* log(x) x = 9bits * 9bits->18 bits */ 25528c2ecf20Sopenharmony_ci a = log10times100(eq_reg_td_tps_pwr_ofs * 25538c2ecf20Sopenharmony_ci eq_reg_td_tps_pwr_ofs); 25548c2ecf20Sopenharmony_ci /* log(x) x = 16bits * 7bits->23 bits */ 25558c2ecf20Sopenharmony_ci b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt); 25568c2ecf20Sopenharmony_ci /* log(x) x = (16bits + 16bits) << 15 ->32 bits */ 25578c2ecf20Sopenharmony_ci c = log10times100(sqr_err_iq); 25588c2ecf20Sopenharmony_ci 25598c2ecf20Sopenharmony_ci i_mer = a + b - c; 25608c2ecf20Sopenharmony_ci } 25618c2ecf20Sopenharmony_ci *p_signal_to_noise = i_mer; 25628c2ecf20Sopenharmony_ci 25638c2ecf20Sopenharmony_cierror: 25648c2ecf20Sopenharmony_ci if (status < 0) 25658c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 25668c2ecf20Sopenharmony_ci return status; 25678c2ecf20Sopenharmony_ci} 25688c2ecf20Sopenharmony_ci 25698c2ecf20Sopenharmony_cistatic int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) 25708c2ecf20Sopenharmony_ci{ 25718c2ecf20Sopenharmony_ci dprintk(1, "\n"); 25728c2ecf20Sopenharmony_ci 25738c2ecf20Sopenharmony_ci *p_signal_to_noise = 0; 25748c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 25758c2ecf20Sopenharmony_ci case OM_DVBT: 25768c2ecf20Sopenharmony_ci return get_dvbt_signal_to_noise(state, p_signal_to_noise); 25778c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 25788c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 25798c2ecf20Sopenharmony_ci return get_qam_signal_to_noise(state, p_signal_to_noise); 25808c2ecf20Sopenharmony_ci default: 25818c2ecf20Sopenharmony_ci break; 25828c2ecf20Sopenharmony_ci } 25838c2ecf20Sopenharmony_ci return 0; 25848c2ecf20Sopenharmony_ci} 25858c2ecf20Sopenharmony_ci 25868c2ecf20Sopenharmony_ci#if 0 25878c2ecf20Sopenharmony_cistatic int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) 25888c2ecf20Sopenharmony_ci{ 25898c2ecf20Sopenharmony_ci /* SNR Values for quasi errorfree reception rom Nordig 2.2 */ 25908c2ecf20Sopenharmony_ci int status = 0; 25918c2ecf20Sopenharmony_ci 25928c2ecf20Sopenharmony_ci dprintk(1, "\n"); 25938c2ecf20Sopenharmony_ci 25948c2ecf20Sopenharmony_ci static s32 QE_SN[] = { 25958c2ecf20Sopenharmony_ci 51, /* QPSK 1/2 */ 25968c2ecf20Sopenharmony_ci 69, /* QPSK 2/3 */ 25978c2ecf20Sopenharmony_ci 79, /* QPSK 3/4 */ 25988c2ecf20Sopenharmony_ci 89, /* QPSK 5/6 */ 25998c2ecf20Sopenharmony_ci 97, /* QPSK 7/8 */ 26008c2ecf20Sopenharmony_ci 108, /* 16-QAM 1/2 */ 26018c2ecf20Sopenharmony_ci 131, /* 16-QAM 2/3 */ 26028c2ecf20Sopenharmony_ci 146, /* 16-QAM 3/4 */ 26038c2ecf20Sopenharmony_ci 156, /* 16-QAM 5/6 */ 26048c2ecf20Sopenharmony_ci 160, /* 16-QAM 7/8 */ 26058c2ecf20Sopenharmony_ci 165, /* 64-QAM 1/2 */ 26068c2ecf20Sopenharmony_ci 187, /* 64-QAM 2/3 */ 26078c2ecf20Sopenharmony_ci 202, /* 64-QAM 3/4 */ 26088c2ecf20Sopenharmony_ci 216, /* 64-QAM 5/6 */ 26098c2ecf20Sopenharmony_ci 225, /* 64-QAM 7/8 */ 26108c2ecf20Sopenharmony_ci }; 26118c2ecf20Sopenharmony_ci 26128c2ecf20Sopenharmony_ci *p_quality = 0; 26138c2ecf20Sopenharmony_ci 26148c2ecf20Sopenharmony_ci do { 26158c2ecf20Sopenharmony_ci s32 signal_to_noise = 0; 26168c2ecf20Sopenharmony_ci u16 constellation = 0; 26178c2ecf20Sopenharmony_ci u16 code_rate = 0; 26188c2ecf20Sopenharmony_ci u32 signal_to_noise_rel; 26198c2ecf20Sopenharmony_ci u32 ber_quality; 26208c2ecf20Sopenharmony_ci 26218c2ecf20Sopenharmony_ci status = get_dvbt_signal_to_noise(state, &signal_to_noise); 26228c2ecf20Sopenharmony_ci if (status < 0) 26238c2ecf20Sopenharmony_ci break; 26248c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, 26258c2ecf20Sopenharmony_ci &constellation); 26268c2ecf20Sopenharmony_ci if (status < 0) 26278c2ecf20Sopenharmony_ci break; 26288c2ecf20Sopenharmony_ci constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; 26298c2ecf20Sopenharmony_ci 26308c2ecf20Sopenharmony_ci status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, 26318c2ecf20Sopenharmony_ci &code_rate); 26328c2ecf20Sopenharmony_ci if (status < 0) 26338c2ecf20Sopenharmony_ci break; 26348c2ecf20Sopenharmony_ci code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; 26358c2ecf20Sopenharmony_ci 26368c2ecf20Sopenharmony_ci if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || 26378c2ecf20Sopenharmony_ci code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) 26388c2ecf20Sopenharmony_ci break; 26398c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 26408c2ecf20Sopenharmony_ci QE_SN[constellation * 5 + code_rate]; 26418c2ecf20Sopenharmony_ci ber_quality = 100; 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_ci if (signal_to_noise_rel < -70) 26448c2ecf20Sopenharmony_ci *p_quality = 0; 26458c2ecf20Sopenharmony_ci else if (signal_to_noise_rel < 30) 26468c2ecf20Sopenharmony_ci *p_quality = ((signal_to_noise_rel + 70) * 26478c2ecf20Sopenharmony_ci ber_quality) / 100; 26488c2ecf20Sopenharmony_ci else 26498c2ecf20Sopenharmony_ci *p_quality = ber_quality; 26508c2ecf20Sopenharmony_ci } while (0); 26518c2ecf20Sopenharmony_ci return 0; 26528c2ecf20Sopenharmony_ci}; 26538c2ecf20Sopenharmony_ci 26548c2ecf20Sopenharmony_cistatic int get_dvbc_quality(struct drxk_state *state, s32 *p_quality) 26558c2ecf20Sopenharmony_ci{ 26568c2ecf20Sopenharmony_ci int status = 0; 26578c2ecf20Sopenharmony_ci *p_quality = 0; 26588c2ecf20Sopenharmony_ci 26598c2ecf20Sopenharmony_ci dprintk(1, "\n"); 26608c2ecf20Sopenharmony_ci 26618c2ecf20Sopenharmony_ci do { 26628c2ecf20Sopenharmony_ci u32 signal_to_noise = 0; 26638c2ecf20Sopenharmony_ci u32 ber_quality = 100; 26648c2ecf20Sopenharmony_ci u32 signal_to_noise_rel = 0; 26658c2ecf20Sopenharmony_ci 26668c2ecf20Sopenharmony_ci status = get_qam_signal_to_noise(state, &signal_to_noise); 26678c2ecf20Sopenharmony_ci if (status < 0) 26688c2ecf20Sopenharmony_ci break; 26698c2ecf20Sopenharmony_ci 26708c2ecf20Sopenharmony_ci switch (state->props.modulation) { 26718c2ecf20Sopenharmony_ci case QAM_16: 26728c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 200; 26738c2ecf20Sopenharmony_ci break; 26748c2ecf20Sopenharmony_ci case QAM_32: 26758c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 230; 26768c2ecf20Sopenharmony_ci break; /* Not in NorDig */ 26778c2ecf20Sopenharmony_ci case QAM_64: 26788c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 260; 26798c2ecf20Sopenharmony_ci break; 26808c2ecf20Sopenharmony_ci case QAM_128: 26818c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 290; 26828c2ecf20Sopenharmony_ci break; 26838c2ecf20Sopenharmony_ci default: 26848c2ecf20Sopenharmony_ci case QAM_256: 26858c2ecf20Sopenharmony_ci signal_to_noise_rel = signal_to_noise - 320; 26868c2ecf20Sopenharmony_ci break; 26878c2ecf20Sopenharmony_ci } 26888c2ecf20Sopenharmony_ci 26898c2ecf20Sopenharmony_ci if (signal_to_noise_rel < -70) 26908c2ecf20Sopenharmony_ci *p_quality = 0; 26918c2ecf20Sopenharmony_ci else if (signal_to_noise_rel < 30) 26928c2ecf20Sopenharmony_ci *p_quality = ((signal_to_noise_rel + 70) * 26938c2ecf20Sopenharmony_ci ber_quality) / 100; 26948c2ecf20Sopenharmony_ci else 26958c2ecf20Sopenharmony_ci *p_quality = ber_quality; 26968c2ecf20Sopenharmony_ci } while (0); 26978c2ecf20Sopenharmony_ci 26988c2ecf20Sopenharmony_ci return status; 26998c2ecf20Sopenharmony_ci} 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_cistatic int get_quality(struct drxk_state *state, s32 *p_quality) 27028c2ecf20Sopenharmony_ci{ 27038c2ecf20Sopenharmony_ci dprintk(1, "\n"); 27048c2ecf20Sopenharmony_ci 27058c2ecf20Sopenharmony_ci switch (state->m_operation_mode) { 27068c2ecf20Sopenharmony_ci case OM_DVBT: 27078c2ecf20Sopenharmony_ci return get_dvbt_quality(state, p_quality); 27088c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 27098c2ecf20Sopenharmony_ci return get_dvbc_quality(state, p_quality); 27108c2ecf20Sopenharmony_ci default: 27118c2ecf20Sopenharmony_ci break; 27128c2ecf20Sopenharmony_ci } 27138c2ecf20Sopenharmony_ci 27148c2ecf20Sopenharmony_ci return 0; 27158c2ecf20Sopenharmony_ci} 27168c2ecf20Sopenharmony_ci#endif 27178c2ecf20Sopenharmony_ci 27188c2ecf20Sopenharmony_ci/* Free data ram in SIO HI */ 27198c2ecf20Sopenharmony_ci#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040 27208c2ecf20Sopenharmony_ci#define SIO_HI_RA_RAM_USR_END__A 0x420060 27218c2ecf20Sopenharmony_ci 27228c2ecf20Sopenharmony_ci#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A) 27238c2ecf20Sopenharmony_ci#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7) 27248c2ecf20Sopenharmony_ci#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ 27258c2ecf20Sopenharmony_ci#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_ci#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F) 27288c2ecf20Sopenharmony_ci#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F) 27298c2ecf20Sopenharmony_ci#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF) 27308c2ecf20Sopenharmony_ci 27318c2ecf20Sopenharmony_cistatic int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) 27328c2ecf20Sopenharmony_ci{ 27338c2ecf20Sopenharmony_ci int status = -EINVAL; 27348c2ecf20Sopenharmony_ci 27358c2ecf20Sopenharmony_ci dprintk(1, "\n"); 27368c2ecf20Sopenharmony_ci 27378c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 27388c2ecf20Sopenharmony_ci return 0; 27398c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_POWERED_DOWN) 27408c2ecf20Sopenharmony_ci goto error; 27418c2ecf20Sopenharmony_ci 27428c2ecf20Sopenharmony_ci if (state->no_i2c_bridge) 27438c2ecf20Sopenharmony_ci return 0; 27448c2ecf20Sopenharmony_ci 27458c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_1__A, 27468c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); 27478c2ecf20Sopenharmony_ci if (status < 0) 27488c2ecf20Sopenharmony_ci goto error; 27498c2ecf20Sopenharmony_ci if (b_enable_bridge) { 27508c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 27518c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); 27528c2ecf20Sopenharmony_ci if (status < 0) 27538c2ecf20Sopenharmony_ci goto error; 27548c2ecf20Sopenharmony_ci } else { 27558c2ecf20Sopenharmony_ci status = write16(state, SIO_HI_RA_RAM_PAR_2__A, 27568c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); 27578c2ecf20Sopenharmony_ci if (status < 0) 27588c2ecf20Sopenharmony_ci goto error; 27598c2ecf20Sopenharmony_ci } 27608c2ecf20Sopenharmony_ci 27618c2ecf20Sopenharmony_ci status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); 27628c2ecf20Sopenharmony_ci 27638c2ecf20Sopenharmony_cierror: 27648c2ecf20Sopenharmony_ci if (status < 0) 27658c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 27668c2ecf20Sopenharmony_ci return status; 27678c2ecf20Sopenharmony_ci} 27688c2ecf20Sopenharmony_ci 27698c2ecf20Sopenharmony_cistatic int set_pre_saw(struct drxk_state *state, 27708c2ecf20Sopenharmony_ci struct s_cfg_pre_saw *p_pre_saw_cfg) 27718c2ecf20Sopenharmony_ci{ 27728c2ecf20Sopenharmony_ci int status = -EINVAL; 27738c2ecf20Sopenharmony_ci 27748c2ecf20Sopenharmony_ci dprintk(1, "\n"); 27758c2ecf20Sopenharmony_ci 27768c2ecf20Sopenharmony_ci if ((p_pre_saw_cfg == NULL) 27778c2ecf20Sopenharmony_ci || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M)) 27788c2ecf20Sopenharmony_ci goto error; 27798c2ecf20Sopenharmony_ci 27808c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference); 27818c2ecf20Sopenharmony_cierror: 27828c2ecf20Sopenharmony_ci if (status < 0) 27838c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 27848c2ecf20Sopenharmony_ci return status; 27858c2ecf20Sopenharmony_ci} 27868c2ecf20Sopenharmony_ci 27878c2ecf20Sopenharmony_cistatic int bl_direct_cmd(struct drxk_state *state, u32 target_addr, 27888c2ecf20Sopenharmony_ci u16 rom_offset, u16 nr_of_elements, u32 time_out) 27898c2ecf20Sopenharmony_ci{ 27908c2ecf20Sopenharmony_ci u16 bl_status = 0; 27918c2ecf20Sopenharmony_ci u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF); 27928c2ecf20Sopenharmony_ci u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF); 27938c2ecf20Sopenharmony_ci int status; 27948c2ecf20Sopenharmony_ci unsigned long end; 27958c2ecf20Sopenharmony_ci 27968c2ecf20Sopenharmony_ci dprintk(1, "\n"); 27978c2ecf20Sopenharmony_ci 27988c2ecf20Sopenharmony_ci mutex_lock(&state->mutex); 27998c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT); 28008c2ecf20Sopenharmony_ci if (status < 0) 28018c2ecf20Sopenharmony_ci goto error; 28028c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_TGT_HDR__A, blockbank); 28038c2ecf20Sopenharmony_ci if (status < 0) 28048c2ecf20Sopenharmony_ci goto error; 28058c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_TGT_ADDR__A, offset); 28068c2ecf20Sopenharmony_ci if (status < 0) 28078c2ecf20Sopenharmony_ci goto error; 28088c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset); 28098c2ecf20Sopenharmony_ci if (status < 0) 28108c2ecf20Sopenharmony_ci goto error; 28118c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements); 28128c2ecf20Sopenharmony_ci if (status < 0) 28138c2ecf20Sopenharmony_ci goto error; 28148c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); 28158c2ecf20Sopenharmony_ci if (status < 0) 28168c2ecf20Sopenharmony_ci goto error; 28178c2ecf20Sopenharmony_ci 28188c2ecf20Sopenharmony_ci end = jiffies + msecs_to_jiffies(time_out); 28198c2ecf20Sopenharmony_ci do { 28208c2ecf20Sopenharmony_ci status = read16(state, SIO_BL_STATUS__A, &bl_status); 28218c2ecf20Sopenharmony_ci if (status < 0) 28228c2ecf20Sopenharmony_ci goto error; 28238c2ecf20Sopenharmony_ci } while ((bl_status == 0x1) && time_is_after_jiffies(end)); 28248c2ecf20Sopenharmony_ci if (bl_status == 0x1) { 28258c2ecf20Sopenharmony_ci pr_err("SIO not ready\n"); 28268c2ecf20Sopenharmony_ci status = -EINVAL; 28278c2ecf20Sopenharmony_ci goto error2; 28288c2ecf20Sopenharmony_ci } 28298c2ecf20Sopenharmony_cierror: 28308c2ecf20Sopenharmony_ci if (status < 0) 28318c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 28328c2ecf20Sopenharmony_cierror2: 28338c2ecf20Sopenharmony_ci mutex_unlock(&state->mutex); 28348c2ecf20Sopenharmony_ci return status; 28358c2ecf20Sopenharmony_ci 28368c2ecf20Sopenharmony_ci} 28378c2ecf20Sopenharmony_ci 28388c2ecf20Sopenharmony_cistatic int adc_sync_measurement(struct drxk_state *state, u16 *count) 28398c2ecf20Sopenharmony_ci{ 28408c2ecf20Sopenharmony_ci u16 data = 0; 28418c2ecf20Sopenharmony_ci int status; 28428c2ecf20Sopenharmony_ci 28438c2ecf20Sopenharmony_ci dprintk(1, "\n"); 28448c2ecf20Sopenharmony_ci 28458c2ecf20Sopenharmony_ci /* start measurement */ 28468c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE); 28478c2ecf20Sopenharmony_ci if (status < 0) 28488c2ecf20Sopenharmony_ci goto error; 28498c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_START_LOCK__A, 1); 28508c2ecf20Sopenharmony_ci if (status < 0) 28518c2ecf20Sopenharmony_ci goto error; 28528c2ecf20Sopenharmony_ci 28538c2ecf20Sopenharmony_ci *count = 0; 28548c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_PHASE0__A, &data); 28558c2ecf20Sopenharmony_ci if (status < 0) 28568c2ecf20Sopenharmony_ci goto error; 28578c2ecf20Sopenharmony_ci if (data == 127) 28588c2ecf20Sopenharmony_ci *count = *count + 1; 28598c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_PHASE1__A, &data); 28608c2ecf20Sopenharmony_ci if (status < 0) 28618c2ecf20Sopenharmony_ci goto error; 28628c2ecf20Sopenharmony_ci if (data == 127) 28638c2ecf20Sopenharmony_ci *count = *count + 1; 28648c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_PHASE2__A, &data); 28658c2ecf20Sopenharmony_ci if (status < 0) 28668c2ecf20Sopenharmony_ci goto error; 28678c2ecf20Sopenharmony_ci if (data == 127) 28688c2ecf20Sopenharmony_ci *count = *count + 1; 28698c2ecf20Sopenharmony_ci 28708c2ecf20Sopenharmony_cierror: 28718c2ecf20Sopenharmony_ci if (status < 0) 28728c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 28738c2ecf20Sopenharmony_ci return status; 28748c2ecf20Sopenharmony_ci} 28758c2ecf20Sopenharmony_ci 28768c2ecf20Sopenharmony_cistatic int adc_synchronization(struct drxk_state *state) 28778c2ecf20Sopenharmony_ci{ 28788c2ecf20Sopenharmony_ci u16 count = 0; 28798c2ecf20Sopenharmony_ci int status; 28808c2ecf20Sopenharmony_ci 28818c2ecf20Sopenharmony_ci dprintk(1, "\n"); 28828c2ecf20Sopenharmony_ci 28838c2ecf20Sopenharmony_ci status = adc_sync_measurement(state, &count); 28848c2ecf20Sopenharmony_ci if (status < 0) 28858c2ecf20Sopenharmony_ci goto error; 28868c2ecf20Sopenharmony_ci 28878c2ecf20Sopenharmony_ci if (count == 1) { 28888c2ecf20Sopenharmony_ci /* Try sampling on a different edge */ 28898c2ecf20Sopenharmony_ci u16 clk_neg = 0; 28908c2ecf20Sopenharmony_ci 28918c2ecf20Sopenharmony_ci status = read16(state, IQM_AF_CLKNEG__A, &clk_neg); 28928c2ecf20Sopenharmony_ci if (status < 0) 28938c2ecf20Sopenharmony_ci goto error; 28948c2ecf20Sopenharmony_ci if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) == 28958c2ecf20Sopenharmony_ci IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { 28968c2ecf20Sopenharmony_ci clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 28978c2ecf20Sopenharmony_ci clk_neg |= 28988c2ecf20Sopenharmony_ci IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG; 28998c2ecf20Sopenharmony_ci } else { 29008c2ecf20Sopenharmony_ci clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); 29018c2ecf20Sopenharmony_ci clk_neg |= 29028c2ecf20Sopenharmony_ci IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS; 29038c2ecf20Sopenharmony_ci } 29048c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_CLKNEG__A, clk_neg); 29058c2ecf20Sopenharmony_ci if (status < 0) 29068c2ecf20Sopenharmony_ci goto error; 29078c2ecf20Sopenharmony_ci status = adc_sync_measurement(state, &count); 29088c2ecf20Sopenharmony_ci if (status < 0) 29098c2ecf20Sopenharmony_ci goto error; 29108c2ecf20Sopenharmony_ci } 29118c2ecf20Sopenharmony_ci 29128c2ecf20Sopenharmony_ci if (count < 2) 29138c2ecf20Sopenharmony_ci status = -EINVAL; 29148c2ecf20Sopenharmony_cierror: 29158c2ecf20Sopenharmony_ci if (status < 0) 29168c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 29178c2ecf20Sopenharmony_ci return status; 29188c2ecf20Sopenharmony_ci} 29198c2ecf20Sopenharmony_ci 29208c2ecf20Sopenharmony_cistatic int set_frequency_shifter(struct drxk_state *state, 29218c2ecf20Sopenharmony_ci u16 intermediate_freqk_hz, 29228c2ecf20Sopenharmony_ci s32 tuner_freq_offset, bool is_dtv) 29238c2ecf20Sopenharmony_ci{ 29248c2ecf20Sopenharmony_ci bool select_pos_image = false; 29258c2ecf20Sopenharmony_ci u32 rf_freq_residual = tuner_freq_offset; 29268c2ecf20Sopenharmony_ci u32 fm_frequency_shift = 0; 29278c2ecf20Sopenharmony_ci bool tuner_mirror = !state->m_b_mirror_freq_spect; 29288c2ecf20Sopenharmony_ci u32 adc_freq; 29298c2ecf20Sopenharmony_ci bool adc_flip; 29308c2ecf20Sopenharmony_ci int status; 29318c2ecf20Sopenharmony_ci u32 if_freq_actual; 29328c2ecf20Sopenharmony_ci u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3); 29338c2ecf20Sopenharmony_ci u32 frequency_shift; 29348c2ecf20Sopenharmony_ci bool image_to_select; 29358c2ecf20Sopenharmony_ci 29368c2ecf20Sopenharmony_ci dprintk(1, "\n"); 29378c2ecf20Sopenharmony_ci 29388c2ecf20Sopenharmony_ci /* 29398c2ecf20Sopenharmony_ci Program frequency shifter 29408c2ecf20Sopenharmony_ci No need to account for mirroring on RF 29418c2ecf20Sopenharmony_ci */ 29428c2ecf20Sopenharmony_ci if (is_dtv) { 29438c2ecf20Sopenharmony_ci if ((state->m_operation_mode == OM_QAM_ITU_A) || 29448c2ecf20Sopenharmony_ci (state->m_operation_mode == OM_QAM_ITU_C) || 29458c2ecf20Sopenharmony_ci (state->m_operation_mode == OM_DVBT)) 29468c2ecf20Sopenharmony_ci select_pos_image = true; 29478c2ecf20Sopenharmony_ci else 29488c2ecf20Sopenharmony_ci select_pos_image = false; 29498c2ecf20Sopenharmony_ci } 29508c2ecf20Sopenharmony_ci if (tuner_mirror) 29518c2ecf20Sopenharmony_ci /* tuner doesn't mirror */ 29528c2ecf20Sopenharmony_ci if_freq_actual = intermediate_freqk_hz + 29538c2ecf20Sopenharmony_ci rf_freq_residual + fm_frequency_shift; 29548c2ecf20Sopenharmony_ci else 29558c2ecf20Sopenharmony_ci /* tuner mirrors */ 29568c2ecf20Sopenharmony_ci if_freq_actual = intermediate_freqk_hz - 29578c2ecf20Sopenharmony_ci rf_freq_residual - fm_frequency_shift; 29588c2ecf20Sopenharmony_ci if (if_freq_actual > sampling_frequency / 2) { 29598c2ecf20Sopenharmony_ci /* adc mirrors */ 29608c2ecf20Sopenharmony_ci adc_freq = sampling_frequency - if_freq_actual; 29618c2ecf20Sopenharmony_ci adc_flip = true; 29628c2ecf20Sopenharmony_ci } else { 29638c2ecf20Sopenharmony_ci /* adc doesn't mirror */ 29648c2ecf20Sopenharmony_ci adc_freq = if_freq_actual; 29658c2ecf20Sopenharmony_ci adc_flip = false; 29668c2ecf20Sopenharmony_ci } 29678c2ecf20Sopenharmony_ci 29688c2ecf20Sopenharmony_ci frequency_shift = adc_freq; 29698c2ecf20Sopenharmony_ci image_to_select = state->m_rfmirror ^ tuner_mirror ^ 29708c2ecf20Sopenharmony_ci adc_flip ^ select_pos_image; 29718c2ecf20Sopenharmony_ci state->m_iqm_fs_rate_ofs = 29728c2ecf20Sopenharmony_ci Frac28a((frequency_shift), sampling_frequency); 29738c2ecf20Sopenharmony_ci 29748c2ecf20Sopenharmony_ci if (image_to_select) 29758c2ecf20Sopenharmony_ci state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1; 29768c2ecf20Sopenharmony_ci 29778c2ecf20Sopenharmony_ci /* Program frequency shifter with tuner offset compensation */ 29788c2ecf20Sopenharmony_ci /* frequency_shift += tuner_freq_offset; TODO */ 29798c2ecf20Sopenharmony_ci status = write32(state, IQM_FS_RATE_OFS_LO__A, 29808c2ecf20Sopenharmony_ci state->m_iqm_fs_rate_ofs); 29818c2ecf20Sopenharmony_ci if (status < 0) 29828c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 29838c2ecf20Sopenharmony_ci return status; 29848c2ecf20Sopenharmony_ci} 29858c2ecf20Sopenharmony_ci 29868c2ecf20Sopenharmony_cistatic int init_agc(struct drxk_state *state, bool is_dtv) 29878c2ecf20Sopenharmony_ci{ 29888c2ecf20Sopenharmony_ci u16 ingain_tgt = 0; 29898c2ecf20Sopenharmony_ci u16 ingain_tgt_min = 0; 29908c2ecf20Sopenharmony_ci u16 ingain_tgt_max = 0; 29918c2ecf20Sopenharmony_ci u16 clp_cyclen = 0; 29928c2ecf20Sopenharmony_ci u16 clp_sum_min = 0; 29938c2ecf20Sopenharmony_ci u16 clp_dir_to = 0; 29948c2ecf20Sopenharmony_ci u16 sns_sum_min = 0; 29958c2ecf20Sopenharmony_ci u16 sns_sum_max = 0; 29968c2ecf20Sopenharmony_ci u16 clp_sum_max = 0; 29978c2ecf20Sopenharmony_ci u16 sns_dir_to = 0; 29988c2ecf20Sopenharmony_ci u16 ki_innergain_min = 0; 29998c2ecf20Sopenharmony_ci u16 if_iaccu_hi_tgt = 0; 30008c2ecf20Sopenharmony_ci u16 if_iaccu_hi_tgt_min = 0; 30018c2ecf20Sopenharmony_ci u16 if_iaccu_hi_tgt_max = 0; 30028c2ecf20Sopenharmony_ci u16 data = 0; 30038c2ecf20Sopenharmony_ci u16 fast_clp_ctrl_delay = 0; 30048c2ecf20Sopenharmony_ci u16 clp_ctrl_mode = 0; 30058c2ecf20Sopenharmony_ci int status = 0; 30068c2ecf20Sopenharmony_ci 30078c2ecf20Sopenharmony_ci dprintk(1, "\n"); 30088c2ecf20Sopenharmony_ci 30098c2ecf20Sopenharmony_ci /* Common settings */ 30108c2ecf20Sopenharmony_ci sns_sum_max = 1023; 30118c2ecf20Sopenharmony_ci if_iaccu_hi_tgt_min = 2047; 30128c2ecf20Sopenharmony_ci clp_cyclen = 500; 30138c2ecf20Sopenharmony_ci clp_sum_max = 1023; 30148c2ecf20Sopenharmony_ci 30158c2ecf20Sopenharmony_ci /* AGCInit() not available for DVBT; init done in microcode */ 30168c2ecf20Sopenharmony_ci if (!is_qam(state)) { 30178c2ecf20Sopenharmony_ci pr_err("%s: mode %d is not DVB-C\n", 30188c2ecf20Sopenharmony_ci __func__, state->m_operation_mode); 30198c2ecf20Sopenharmony_ci return -EINVAL; 30208c2ecf20Sopenharmony_ci } 30218c2ecf20Sopenharmony_ci 30228c2ecf20Sopenharmony_ci /* FIXME: Analog TV AGC require different settings */ 30238c2ecf20Sopenharmony_ci 30248c2ecf20Sopenharmony_ci /* Standard specific settings */ 30258c2ecf20Sopenharmony_ci clp_sum_min = 8; 30268c2ecf20Sopenharmony_ci clp_dir_to = (u16) -9; 30278c2ecf20Sopenharmony_ci clp_ctrl_mode = 0; 30288c2ecf20Sopenharmony_ci sns_sum_min = 8; 30298c2ecf20Sopenharmony_ci sns_dir_to = (u16) -9; 30308c2ecf20Sopenharmony_ci ki_innergain_min = (u16) -1030; 30318c2ecf20Sopenharmony_ci if_iaccu_hi_tgt_max = 0x2380; 30328c2ecf20Sopenharmony_ci if_iaccu_hi_tgt = 0x2380; 30338c2ecf20Sopenharmony_ci ingain_tgt_min = 0x0511; 30348c2ecf20Sopenharmony_ci ingain_tgt = 0x0511; 30358c2ecf20Sopenharmony_ci ingain_tgt_max = 5119; 30368c2ecf20Sopenharmony_ci fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay; 30378c2ecf20Sopenharmony_ci 30388c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 30398c2ecf20Sopenharmony_ci fast_clp_ctrl_delay); 30408c2ecf20Sopenharmony_ci if (status < 0) 30418c2ecf20Sopenharmony_ci goto error; 30428c2ecf20Sopenharmony_ci 30438c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode); 30448c2ecf20Sopenharmony_ci if (status < 0) 30458c2ecf20Sopenharmony_ci goto error; 30468c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt); 30478c2ecf20Sopenharmony_ci if (status < 0) 30488c2ecf20Sopenharmony_ci goto error; 30498c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min); 30508c2ecf20Sopenharmony_ci if (status < 0) 30518c2ecf20Sopenharmony_ci goto error; 30528c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max); 30538c2ecf20Sopenharmony_ci if (status < 0) 30548c2ecf20Sopenharmony_ci goto error; 30558c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, 30568c2ecf20Sopenharmony_ci if_iaccu_hi_tgt_min); 30578c2ecf20Sopenharmony_ci if (status < 0) 30588c2ecf20Sopenharmony_ci goto error; 30598c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 30608c2ecf20Sopenharmony_ci if_iaccu_hi_tgt_max); 30618c2ecf20Sopenharmony_ci if (status < 0) 30628c2ecf20Sopenharmony_ci goto error; 30638c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0); 30648c2ecf20Sopenharmony_ci if (status < 0) 30658c2ecf20Sopenharmony_ci goto error; 30668c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0); 30678c2ecf20Sopenharmony_ci if (status < 0) 30688c2ecf20Sopenharmony_ci goto error; 30698c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0); 30708c2ecf20Sopenharmony_ci if (status < 0) 30718c2ecf20Sopenharmony_ci goto error; 30728c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0); 30738c2ecf20Sopenharmony_ci if (status < 0) 30748c2ecf20Sopenharmony_ci goto error; 30758c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max); 30768c2ecf20Sopenharmony_ci if (status < 0) 30778c2ecf20Sopenharmony_ci goto error; 30788c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max); 30798c2ecf20Sopenharmony_ci if (status < 0) 30808c2ecf20Sopenharmony_ci goto error; 30818c2ecf20Sopenharmony_ci 30828c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, 30838c2ecf20Sopenharmony_ci ki_innergain_min); 30848c2ecf20Sopenharmony_ci if (status < 0) 30858c2ecf20Sopenharmony_ci goto error; 30868c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 30878c2ecf20Sopenharmony_ci if_iaccu_hi_tgt); 30888c2ecf20Sopenharmony_ci if (status < 0) 30898c2ecf20Sopenharmony_ci goto error; 30908c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen); 30918c2ecf20Sopenharmony_ci if (status < 0) 30928c2ecf20Sopenharmony_ci goto error; 30938c2ecf20Sopenharmony_ci 30948c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023); 30958c2ecf20Sopenharmony_ci if (status < 0) 30968c2ecf20Sopenharmony_ci goto error; 30978c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023); 30988c2ecf20Sopenharmony_ci if (status < 0) 30998c2ecf20Sopenharmony_ci goto error; 31008c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50); 31018c2ecf20Sopenharmony_ci if (status < 0) 31028c2ecf20Sopenharmony_ci goto error; 31038c2ecf20Sopenharmony_ci 31048c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20); 31058c2ecf20Sopenharmony_ci if (status < 0) 31068c2ecf20Sopenharmony_ci goto error; 31078c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min); 31088c2ecf20Sopenharmony_ci if (status < 0) 31098c2ecf20Sopenharmony_ci goto error; 31108c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min); 31118c2ecf20Sopenharmony_ci if (status < 0) 31128c2ecf20Sopenharmony_ci goto error; 31138c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to); 31148c2ecf20Sopenharmony_ci if (status < 0) 31158c2ecf20Sopenharmony_ci goto error; 31168c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to); 31178c2ecf20Sopenharmony_ci if (status < 0) 31188c2ecf20Sopenharmony_ci goto error; 31198c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff); 31208c2ecf20Sopenharmony_ci if (status < 0) 31218c2ecf20Sopenharmony_ci goto error; 31228c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0); 31238c2ecf20Sopenharmony_ci if (status < 0) 31248c2ecf20Sopenharmony_ci goto error; 31258c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117); 31268c2ecf20Sopenharmony_ci if (status < 0) 31278c2ecf20Sopenharmony_ci goto error; 31288c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657); 31298c2ecf20Sopenharmony_ci if (status < 0) 31308c2ecf20Sopenharmony_ci goto error; 31318c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0); 31328c2ecf20Sopenharmony_ci if (status < 0) 31338c2ecf20Sopenharmony_ci goto error; 31348c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0); 31358c2ecf20Sopenharmony_ci if (status < 0) 31368c2ecf20Sopenharmony_ci goto error; 31378c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0); 31388c2ecf20Sopenharmony_ci if (status < 0) 31398c2ecf20Sopenharmony_ci goto error; 31408c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1); 31418c2ecf20Sopenharmony_ci if (status < 0) 31428c2ecf20Sopenharmony_ci goto error; 31438c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0); 31448c2ecf20Sopenharmony_ci if (status < 0) 31458c2ecf20Sopenharmony_ci goto error; 31468c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0); 31478c2ecf20Sopenharmony_ci if (status < 0) 31488c2ecf20Sopenharmony_ci goto error; 31498c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0); 31508c2ecf20Sopenharmony_ci if (status < 0) 31518c2ecf20Sopenharmony_ci goto error; 31528c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1); 31538c2ecf20Sopenharmony_ci if (status < 0) 31548c2ecf20Sopenharmony_ci goto error; 31558c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500); 31568c2ecf20Sopenharmony_ci if (status < 0) 31578c2ecf20Sopenharmony_ci goto error; 31588c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500); 31598c2ecf20Sopenharmony_ci if (status < 0) 31608c2ecf20Sopenharmony_ci goto error; 31618c2ecf20Sopenharmony_ci 31628c2ecf20Sopenharmony_ci /* Initialize inner-loop KI gain factors */ 31638c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_KI__A, &data); 31648c2ecf20Sopenharmony_ci if (status < 0) 31658c2ecf20Sopenharmony_ci goto error; 31668c2ecf20Sopenharmony_ci 31678c2ecf20Sopenharmony_ci data = 0x0657; 31688c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_KI_RF__M; 31698c2ecf20Sopenharmony_ci data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B); 31708c2ecf20Sopenharmony_ci data &= ~SCU_RAM_AGC_KI_IF__M; 31718c2ecf20Sopenharmony_ci data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B); 31728c2ecf20Sopenharmony_ci 31738c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_KI__A, data); 31748c2ecf20Sopenharmony_cierror: 31758c2ecf20Sopenharmony_ci if (status < 0) 31768c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 31778c2ecf20Sopenharmony_ci return status; 31788c2ecf20Sopenharmony_ci} 31798c2ecf20Sopenharmony_ci 31808c2ecf20Sopenharmony_cistatic int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err) 31818c2ecf20Sopenharmony_ci{ 31828c2ecf20Sopenharmony_ci int status; 31838c2ecf20Sopenharmony_ci 31848c2ecf20Sopenharmony_ci dprintk(1, "\n"); 31858c2ecf20Sopenharmony_ci if (packet_err == NULL) 31868c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 31878c2ecf20Sopenharmony_ci else 31888c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 31898c2ecf20Sopenharmony_ci packet_err); 31908c2ecf20Sopenharmony_ci if (status < 0) 31918c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 31928c2ecf20Sopenharmony_ci return status; 31938c2ecf20Sopenharmony_ci} 31948c2ecf20Sopenharmony_ci 31958c2ecf20Sopenharmony_cistatic int dvbt_sc_command(struct drxk_state *state, 31968c2ecf20Sopenharmony_ci u16 cmd, u16 subcmd, 31978c2ecf20Sopenharmony_ci u16 param0, u16 param1, u16 param2, 31988c2ecf20Sopenharmony_ci u16 param3, u16 param4) 31998c2ecf20Sopenharmony_ci{ 32008c2ecf20Sopenharmony_ci u16 cur_cmd = 0; 32018c2ecf20Sopenharmony_ci u16 err_code = 0; 32028c2ecf20Sopenharmony_ci u16 retry_cnt = 0; 32038c2ecf20Sopenharmony_ci u16 sc_exec = 0; 32048c2ecf20Sopenharmony_ci int status; 32058c2ecf20Sopenharmony_ci 32068c2ecf20Sopenharmony_ci dprintk(1, "\n"); 32078c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec); 32088c2ecf20Sopenharmony_ci if (sc_exec != 1) { 32098c2ecf20Sopenharmony_ci /* SC is not running */ 32108c2ecf20Sopenharmony_ci status = -EINVAL; 32118c2ecf20Sopenharmony_ci } 32128c2ecf20Sopenharmony_ci if (status < 0) 32138c2ecf20Sopenharmony_ci goto error; 32148c2ecf20Sopenharmony_ci 32158c2ecf20Sopenharmony_ci /* Wait until sc is ready to receive command */ 32168c2ecf20Sopenharmony_ci retry_cnt = 0; 32178c2ecf20Sopenharmony_ci do { 32188c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 32198c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 32208c2ecf20Sopenharmony_ci retry_cnt++; 32218c2ecf20Sopenharmony_ci } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 32228c2ecf20Sopenharmony_ci if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32238c2ecf20Sopenharmony_ci goto error; 32248c2ecf20Sopenharmony_ci 32258c2ecf20Sopenharmony_ci /* Write sub-command */ 32268c2ecf20Sopenharmony_ci switch (cmd) { 32278c2ecf20Sopenharmony_ci /* All commands using sub-cmd */ 32288c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROC_START: 32298c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32308c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32318c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd); 32328c2ecf20Sopenharmony_ci if (status < 0) 32338c2ecf20Sopenharmony_ci goto error; 32348c2ecf20Sopenharmony_ci break; 32358c2ecf20Sopenharmony_ci default: 32368c2ecf20Sopenharmony_ci /* Do nothing */ 32378c2ecf20Sopenharmony_ci break; 32388c2ecf20Sopenharmony_ci } 32398c2ecf20Sopenharmony_ci 32408c2ecf20Sopenharmony_ci /* Write needed parameters and the command */ 32418c2ecf20Sopenharmony_ci status = 0; 32428c2ecf20Sopenharmony_ci switch (cmd) { 32438c2ecf20Sopenharmony_ci /* All commands using 5 parameters */ 32448c2ecf20Sopenharmony_ci /* All commands using 4 parameters */ 32458c2ecf20Sopenharmony_ci /* All commands using 3 parameters */ 32468c2ecf20Sopenharmony_ci /* All commands using 2 parameters */ 32478c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROC_START: 32488c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 32498c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 32508c2ecf20Sopenharmony_ci status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1); 32518c2ecf20Sopenharmony_ci fallthrough; /* All commands using 1 parameters */ 32528c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 32538c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_USER_IO: 32548c2ecf20Sopenharmony_ci status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0); 32558c2ecf20Sopenharmony_ci fallthrough; /* All commands using 0 parameters */ 32568c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 32578c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_NULL: 32588c2ecf20Sopenharmony_ci /* Write command */ 32598c2ecf20Sopenharmony_ci status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd); 32608c2ecf20Sopenharmony_ci break; 32618c2ecf20Sopenharmony_ci default: 32628c2ecf20Sopenharmony_ci /* Unknown command */ 32638c2ecf20Sopenharmony_ci status = -EINVAL; 32648c2ecf20Sopenharmony_ci } 32658c2ecf20Sopenharmony_ci if (status < 0) 32668c2ecf20Sopenharmony_ci goto error; 32678c2ecf20Sopenharmony_ci 32688c2ecf20Sopenharmony_ci /* Wait until sc is ready processing command */ 32698c2ecf20Sopenharmony_ci retry_cnt = 0; 32708c2ecf20Sopenharmony_ci do { 32718c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 32728c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); 32738c2ecf20Sopenharmony_ci retry_cnt++; 32748c2ecf20Sopenharmony_ci } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); 32758c2ecf20Sopenharmony_ci if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) 32768c2ecf20Sopenharmony_ci goto error; 32778c2ecf20Sopenharmony_ci 32788c2ecf20Sopenharmony_ci /* Check for illegal cmd */ 32798c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code); 32808c2ecf20Sopenharmony_ci if (err_code == 0xFFFF) { 32818c2ecf20Sopenharmony_ci /* illegal command */ 32828c2ecf20Sopenharmony_ci status = -EINVAL; 32838c2ecf20Sopenharmony_ci } 32848c2ecf20Sopenharmony_ci if (status < 0) 32858c2ecf20Sopenharmony_ci goto error; 32868c2ecf20Sopenharmony_ci 32878c2ecf20Sopenharmony_ci /* Retrieve results parameters from SC */ 32888c2ecf20Sopenharmony_ci switch (cmd) { 32898c2ecf20Sopenharmony_ci /* All commands yielding 5 results */ 32908c2ecf20Sopenharmony_ci /* All commands yielding 4 results */ 32918c2ecf20Sopenharmony_ci /* All commands yielding 3 results */ 32928c2ecf20Sopenharmony_ci /* All commands yielding 2 results */ 32938c2ecf20Sopenharmony_ci /* All commands yielding 1 result */ 32948c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_USER_IO: 32958c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: 32968c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0)); 32978c2ecf20Sopenharmony_ci /* All commands yielding 0 results */ 32988c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: 32998c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_TIMER: 33008c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROC_START: 33018c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: 33028c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: 33038c2ecf20Sopenharmony_ci case OFDM_SC_RA_RAM_CMD_NULL: 33048c2ecf20Sopenharmony_ci break; 33058c2ecf20Sopenharmony_ci default: 33068c2ecf20Sopenharmony_ci /* Unknown command */ 33078c2ecf20Sopenharmony_ci status = -EINVAL; 33088c2ecf20Sopenharmony_ci break; 33098c2ecf20Sopenharmony_ci } /* switch (cmd->cmd) */ 33108c2ecf20Sopenharmony_cierror: 33118c2ecf20Sopenharmony_ci if (status < 0) 33128c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 33138c2ecf20Sopenharmony_ci return status; 33148c2ecf20Sopenharmony_ci} 33158c2ecf20Sopenharmony_ci 33168c2ecf20Sopenharmony_cistatic int power_up_dvbt(struct drxk_state *state) 33178c2ecf20Sopenharmony_ci{ 33188c2ecf20Sopenharmony_ci enum drx_power_mode power_mode = DRX_POWER_UP; 33198c2ecf20Sopenharmony_ci int status; 33208c2ecf20Sopenharmony_ci 33218c2ecf20Sopenharmony_ci dprintk(1, "\n"); 33228c2ecf20Sopenharmony_ci status = ctrl_power_mode(state, &power_mode); 33238c2ecf20Sopenharmony_ci if (status < 0) 33248c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 33258c2ecf20Sopenharmony_ci return status; 33268c2ecf20Sopenharmony_ci} 33278c2ecf20Sopenharmony_ci 33288c2ecf20Sopenharmony_cistatic int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled) 33298c2ecf20Sopenharmony_ci{ 33308c2ecf20Sopenharmony_ci int status; 33318c2ecf20Sopenharmony_ci 33328c2ecf20Sopenharmony_ci dprintk(1, "\n"); 33338c2ecf20Sopenharmony_ci if (*enabled) 33348c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_BYPASSDET__A, 0); 33358c2ecf20Sopenharmony_ci else 33368c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_BYPASSDET__A, 1); 33378c2ecf20Sopenharmony_ci if (status < 0) 33388c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 33398c2ecf20Sopenharmony_ci return status; 33408c2ecf20Sopenharmony_ci} 33418c2ecf20Sopenharmony_ci 33428c2ecf20Sopenharmony_ci#define DEFAULT_FR_THRES_8K 4000 33438c2ecf20Sopenharmony_cistatic int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) 33448c2ecf20Sopenharmony_ci{ 33458c2ecf20Sopenharmony_ci 33468c2ecf20Sopenharmony_ci int status; 33478c2ecf20Sopenharmony_ci 33488c2ecf20Sopenharmony_ci dprintk(1, "\n"); 33498c2ecf20Sopenharmony_ci if (*enabled) { 33508c2ecf20Sopenharmony_ci /* write mask to 1 */ 33518c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 33528c2ecf20Sopenharmony_ci DEFAULT_FR_THRES_8K); 33538c2ecf20Sopenharmony_ci } else { 33548c2ecf20Sopenharmony_ci /* write mask to 0 */ 33558c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0); 33568c2ecf20Sopenharmony_ci } 33578c2ecf20Sopenharmony_ci if (status < 0) 33588c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 33598c2ecf20Sopenharmony_ci 33608c2ecf20Sopenharmony_ci return status; 33618c2ecf20Sopenharmony_ci} 33628c2ecf20Sopenharmony_ci 33638c2ecf20Sopenharmony_cistatic int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, 33648c2ecf20Sopenharmony_ci struct drxk_cfg_dvbt_echo_thres_t *echo_thres) 33658c2ecf20Sopenharmony_ci{ 33668c2ecf20Sopenharmony_ci u16 data = 0; 33678c2ecf20Sopenharmony_ci int status; 33688c2ecf20Sopenharmony_ci 33698c2ecf20Sopenharmony_ci dprintk(1, "\n"); 33708c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data); 33718c2ecf20Sopenharmony_ci if (status < 0) 33728c2ecf20Sopenharmony_ci goto error; 33738c2ecf20Sopenharmony_ci 33748c2ecf20Sopenharmony_ci switch (echo_thres->fft_mode) { 33758c2ecf20Sopenharmony_ci case DRX_FFTMODE_2K: 33768c2ecf20Sopenharmony_ci data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M; 33778c2ecf20Sopenharmony_ci data |= ((echo_thres->threshold << 33788c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_ECHO_THRES_2K__B) 33798c2ecf20Sopenharmony_ci & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M)); 33808c2ecf20Sopenharmony_ci break; 33818c2ecf20Sopenharmony_ci case DRX_FFTMODE_8K: 33828c2ecf20Sopenharmony_ci data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M; 33838c2ecf20Sopenharmony_ci data |= ((echo_thres->threshold << 33848c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_ECHO_THRES_8K__B) 33858c2ecf20Sopenharmony_ci & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M)); 33868c2ecf20Sopenharmony_ci break; 33878c2ecf20Sopenharmony_ci default: 33888c2ecf20Sopenharmony_ci return -EINVAL; 33898c2ecf20Sopenharmony_ci } 33908c2ecf20Sopenharmony_ci 33918c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data); 33928c2ecf20Sopenharmony_cierror: 33938c2ecf20Sopenharmony_ci if (status < 0) 33948c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 33958c2ecf20Sopenharmony_ci return status; 33968c2ecf20Sopenharmony_ci} 33978c2ecf20Sopenharmony_ci 33988c2ecf20Sopenharmony_cistatic int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, 33998c2ecf20Sopenharmony_ci enum drxk_cfg_dvbt_sqi_speed *speed) 34008c2ecf20Sopenharmony_ci{ 34018c2ecf20Sopenharmony_ci int status = -EINVAL; 34028c2ecf20Sopenharmony_ci 34038c2ecf20Sopenharmony_ci dprintk(1, "\n"); 34048c2ecf20Sopenharmony_ci 34058c2ecf20Sopenharmony_ci switch (*speed) { 34068c2ecf20Sopenharmony_ci case DRXK_DVBT_SQI_SPEED_FAST: 34078c2ecf20Sopenharmony_ci case DRXK_DVBT_SQI_SPEED_MEDIUM: 34088c2ecf20Sopenharmony_ci case DRXK_DVBT_SQI_SPEED_SLOW: 34098c2ecf20Sopenharmony_ci break; 34108c2ecf20Sopenharmony_ci default: 34118c2ecf20Sopenharmony_ci goto error; 34128c2ecf20Sopenharmony_ci } 34138c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A, 34148c2ecf20Sopenharmony_ci (u16) *speed); 34158c2ecf20Sopenharmony_cierror: 34168c2ecf20Sopenharmony_ci if (status < 0) 34178c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 34188c2ecf20Sopenharmony_ci return status; 34198c2ecf20Sopenharmony_ci} 34208c2ecf20Sopenharmony_ci 34218c2ecf20Sopenharmony_ci/*============================================================================*/ 34228c2ecf20Sopenharmony_ci 34238c2ecf20Sopenharmony_ci/* 34248c2ecf20Sopenharmony_ci* \brief Activate DVBT specific presets 34258c2ecf20Sopenharmony_ci* \param demod instance of demodulator. 34268c2ecf20Sopenharmony_ci* \return DRXStatus_t. 34278c2ecf20Sopenharmony_ci* 34288c2ecf20Sopenharmony_ci* Called in DVBTSetStandard 34298c2ecf20Sopenharmony_ci* 34308c2ecf20Sopenharmony_ci*/ 34318c2ecf20Sopenharmony_cistatic int dvbt_activate_presets(struct drxk_state *state) 34328c2ecf20Sopenharmony_ci{ 34338c2ecf20Sopenharmony_ci int status; 34348c2ecf20Sopenharmony_ci bool setincenable = false; 34358c2ecf20Sopenharmony_ci bool setfrenable = true; 34368c2ecf20Sopenharmony_ci 34378c2ecf20Sopenharmony_ci struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K }; 34388c2ecf20Sopenharmony_ci struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K }; 34398c2ecf20Sopenharmony_ci 34408c2ecf20Sopenharmony_ci dprintk(1, "\n"); 34418c2ecf20Sopenharmony_ci status = dvbt_ctrl_set_inc_enable(state, &setincenable); 34428c2ecf20Sopenharmony_ci if (status < 0) 34438c2ecf20Sopenharmony_ci goto error; 34448c2ecf20Sopenharmony_ci status = dvbt_ctrl_set_fr_enable(state, &setfrenable); 34458c2ecf20Sopenharmony_ci if (status < 0) 34468c2ecf20Sopenharmony_ci goto error; 34478c2ecf20Sopenharmony_ci status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k); 34488c2ecf20Sopenharmony_ci if (status < 0) 34498c2ecf20Sopenharmony_ci goto error; 34508c2ecf20Sopenharmony_ci status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k); 34518c2ecf20Sopenharmony_ci if (status < 0) 34528c2ecf20Sopenharmony_ci goto error; 34538c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, 34548c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.ingain_tgt_max); 34558c2ecf20Sopenharmony_cierror: 34568c2ecf20Sopenharmony_ci if (status < 0) 34578c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 34588c2ecf20Sopenharmony_ci return status; 34598c2ecf20Sopenharmony_ci} 34608c2ecf20Sopenharmony_ci 34618c2ecf20Sopenharmony_ci/*============================================================================*/ 34628c2ecf20Sopenharmony_ci 34638c2ecf20Sopenharmony_ci/* 34648c2ecf20Sopenharmony_ci* \brief Initialize channelswitch-independent settings for DVBT. 34658c2ecf20Sopenharmony_ci* \param demod instance of demodulator. 34668c2ecf20Sopenharmony_ci* \return DRXStatus_t. 34678c2ecf20Sopenharmony_ci* 34688c2ecf20Sopenharmony_ci* For ROM code channel filter taps are loaded from the bootloader. For microcode 34698c2ecf20Sopenharmony_ci* the DVB-T taps from the drxk_filters.h are used. 34708c2ecf20Sopenharmony_ci*/ 34718c2ecf20Sopenharmony_cistatic int set_dvbt_standard(struct drxk_state *state, 34728c2ecf20Sopenharmony_ci enum operation_mode o_mode) 34738c2ecf20Sopenharmony_ci{ 34748c2ecf20Sopenharmony_ci u16 cmd_result = 0; 34758c2ecf20Sopenharmony_ci u16 data = 0; 34768c2ecf20Sopenharmony_ci int status; 34778c2ecf20Sopenharmony_ci 34788c2ecf20Sopenharmony_ci dprintk(1, "\n"); 34798c2ecf20Sopenharmony_ci 34808c2ecf20Sopenharmony_ci power_up_dvbt(state); 34818c2ecf20Sopenharmony_ci /* added antenna switch */ 34828c2ecf20Sopenharmony_ci switch_antenna_to_dvbt(state); 34838c2ecf20Sopenharmony_ci /* send OFDM reset command */ 34848c2ecf20Sopenharmony_ci status = scu_command(state, 34858c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_OFDM 34868c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 34878c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 34888c2ecf20Sopenharmony_ci if (status < 0) 34898c2ecf20Sopenharmony_ci goto error; 34908c2ecf20Sopenharmony_ci 34918c2ecf20Sopenharmony_ci /* send OFDM setenv command */ 34928c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 34938c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 34948c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 34958c2ecf20Sopenharmony_ci if (status < 0) 34968c2ecf20Sopenharmony_ci goto error; 34978c2ecf20Sopenharmony_ci 34988c2ecf20Sopenharmony_ci /* reset datapath for OFDM, processors first */ 34998c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 35008c2ecf20Sopenharmony_ci if (status < 0) 35018c2ecf20Sopenharmony_ci goto error; 35028c2ecf20Sopenharmony_ci status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 35038c2ecf20Sopenharmony_ci if (status < 0) 35048c2ecf20Sopenharmony_ci goto error; 35058c2ecf20Sopenharmony_ci status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 35068c2ecf20Sopenharmony_ci if (status < 0) 35078c2ecf20Sopenharmony_ci goto error; 35088c2ecf20Sopenharmony_ci 35098c2ecf20Sopenharmony_ci /* IQM setup */ 35108c2ecf20Sopenharmony_ci /* synchronize on ofdstate->m_festart */ 35118c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_UPD_SEL__A, 1); 35128c2ecf20Sopenharmony_ci if (status < 0) 35138c2ecf20Sopenharmony_ci goto error; 35148c2ecf20Sopenharmony_ci /* window size for clipping ADC detection */ 35158c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_CLP_LEN__A, 0); 35168c2ecf20Sopenharmony_ci if (status < 0) 35178c2ecf20Sopenharmony_ci goto error; 35188c2ecf20Sopenharmony_ci /* window size for for sense pre-SAW detection */ 35198c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_SNS_LEN__A, 0); 35208c2ecf20Sopenharmony_ci if (status < 0) 35218c2ecf20Sopenharmony_ci goto error; 35228c2ecf20Sopenharmony_ci /* sense threshold for sense pre-SAW detection */ 35238c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 35248c2ecf20Sopenharmony_ci if (status < 0) 35258c2ecf20Sopenharmony_ci goto error; 35268c2ecf20Sopenharmony_ci status = set_iqm_af(state, true); 35278c2ecf20Sopenharmony_ci if (status < 0) 35288c2ecf20Sopenharmony_ci goto error; 35298c2ecf20Sopenharmony_ci 35308c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_AGC_RF__A, 0); 35318c2ecf20Sopenharmony_ci if (status < 0) 35328c2ecf20Sopenharmony_ci goto error; 35338c2ecf20Sopenharmony_ci 35348c2ecf20Sopenharmony_ci /* Impulse noise cruncher setup */ 35358c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */ 35368c2ecf20Sopenharmony_ci if (status < 0) 35378c2ecf20Sopenharmony_ci goto error; 35388c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */ 35398c2ecf20Sopenharmony_ci if (status < 0) 35408c2ecf20Sopenharmony_ci goto error; 35418c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */ 35428c2ecf20Sopenharmony_ci if (status < 0) 35438c2ecf20Sopenharmony_ci goto error; 35448c2ecf20Sopenharmony_ci 35458c2ecf20Sopenharmony_ci status = write16(state, IQM_RC_STRETCH__A, 16); 35468c2ecf20Sopenharmony_ci if (status < 0) 35478c2ecf20Sopenharmony_ci goto error; 35488c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ 35498c2ecf20Sopenharmony_ci if (status < 0) 35508c2ecf20Sopenharmony_ci goto error; 35518c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */ 35528c2ecf20Sopenharmony_ci if (status < 0) 35538c2ecf20Sopenharmony_ci goto error; 35548c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_SCALE__A, 1600); 35558c2ecf20Sopenharmony_ci if (status < 0) 35568c2ecf20Sopenharmony_ci goto error; 35578c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_SCALE_SH__A, 0); 35588c2ecf20Sopenharmony_ci if (status < 0) 35598c2ecf20Sopenharmony_ci goto error; 35608c2ecf20Sopenharmony_ci 35618c2ecf20Sopenharmony_ci /* virtual clipping threshold for clipping ADC detection */ 35628c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_CLP_TH__A, 448); 35638c2ecf20Sopenharmony_ci if (status < 0) 35648c2ecf20Sopenharmony_ci goto error; 35658c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */ 35668c2ecf20Sopenharmony_ci if (status < 0) 35678c2ecf20Sopenharmony_ci goto error; 35688c2ecf20Sopenharmony_ci 35698c2ecf20Sopenharmony_ci status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, 35708c2ecf20Sopenharmony_ci DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); 35718c2ecf20Sopenharmony_ci if (status < 0) 35728c2ecf20Sopenharmony_ci goto error; 35738c2ecf20Sopenharmony_ci 35748c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */ 35758c2ecf20Sopenharmony_ci if (status < 0) 35768c2ecf20Sopenharmony_ci goto error; 35778c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2); 35788c2ecf20Sopenharmony_ci if (status < 0) 35798c2ecf20Sopenharmony_ci goto error; 35808c2ecf20Sopenharmony_ci /* enable power measurement interrupt */ 35818c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_COMM_INT_MSK__A, 1); 35828c2ecf20Sopenharmony_ci if (status < 0) 35838c2ecf20Sopenharmony_ci goto error; 35848c2ecf20Sopenharmony_ci status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 35858c2ecf20Sopenharmony_ci if (status < 0) 35868c2ecf20Sopenharmony_ci goto error; 35878c2ecf20Sopenharmony_ci 35888c2ecf20Sopenharmony_ci /* IQM will not be reset from here, sync ADC and update/init AGC */ 35898c2ecf20Sopenharmony_ci status = adc_synchronization(state); 35908c2ecf20Sopenharmony_ci if (status < 0) 35918c2ecf20Sopenharmony_ci goto error; 35928c2ecf20Sopenharmony_ci status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg); 35938c2ecf20Sopenharmony_ci if (status < 0) 35948c2ecf20Sopenharmony_ci goto error; 35958c2ecf20Sopenharmony_ci 35968c2ecf20Sopenharmony_ci /* Halt SCU to enable safe non-atomic accesses */ 35978c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 35988c2ecf20Sopenharmony_ci if (status < 0) 35998c2ecf20Sopenharmony_ci goto error; 36008c2ecf20Sopenharmony_ci 36018c2ecf20Sopenharmony_ci status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true); 36028c2ecf20Sopenharmony_ci if (status < 0) 36038c2ecf20Sopenharmony_ci goto error; 36048c2ecf20Sopenharmony_ci status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true); 36058c2ecf20Sopenharmony_ci if (status < 0) 36068c2ecf20Sopenharmony_ci goto error; 36078c2ecf20Sopenharmony_ci 36088c2ecf20Sopenharmony_ci /* Set Noise Estimation notch width and enable DC fix */ 36098c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data); 36108c2ecf20Sopenharmony_ci if (status < 0) 36118c2ecf20Sopenharmony_ci goto error; 36128c2ecf20Sopenharmony_ci data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M; 36138c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data); 36148c2ecf20Sopenharmony_ci if (status < 0) 36158c2ecf20Sopenharmony_ci goto error; 36168c2ecf20Sopenharmony_ci 36178c2ecf20Sopenharmony_ci /* Activate SCU to enable SCU commands */ 36188c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 36198c2ecf20Sopenharmony_ci if (status < 0) 36208c2ecf20Sopenharmony_ci goto error; 36218c2ecf20Sopenharmony_ci 36228c2ecf20Sopenharmony_ci if (!state->m_drxk_a3_rom_code) { 36238c2ecf20Sopenharmony_ci /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */ 36248c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 36258c2ecf20Sopenharmony_ci state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay); 36268c2ecf20Sopenharmony_ci if (status < 0) 36278c2ecf20Sopenharmony_ci goto error; 36288c2ecf20Sopenharmony_ci } 36298c2ecf20Sopenharmony_ci 36308c2ecf20Sopenharmony_ci /* OFDM_SC setup */ 36318c2ecf20Sopenharmony_ci#ifdef COMPILE_FOR_NONRT 36328c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1); 36338c2ecf20Sopenharmony_ci if (status < 0) 36348c2ecf20Sopenharmony_ci goto error; 36358c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2); 36368c2ecf20Sopenharmony_ci if (status < 0) 36378c2ecf20Sopenharmony_ci goto error; 36388c2ecf20Sopenharmony_ci#endif 36398c2ecf20Sopenharmony_ci 36408c2ecf20Sopenharmony_ci /* FEC setup */ 36418c2ecf20Sopenharmony_ci status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */ 36428c2ecf20Sopenharmony_ci if (status < 0) 36438c2ecf20Sopenharmony_ci goto error; 36448c2ecf20Sopenharmony_ci 36458c2ecf20Sopenharmony_ci 36468c2ecf20Sopenharmony_ci#ifdef COMPILE_FOR_NONRT 36478c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400); 36488c2ecf20Sopenharmony_ci if (status < 0) 36498c2ecf20Sopenharmony_ci goto error; 36508c2ecf20Sopenharmony_ci#else 36518c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000); 36528c2ecf20Sopenharmony_ci if (status < 0) 36538c2ecf20Sopenharmony_ci goto error; 36548c2ecf20Sopenharmony_ci#endif 36558c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001); 36568c2ecf20Sopenharmony_ci if (status < 0) 36578c2ecf20Sopenharmony_ci goto error; 36588c2ecf20Sopenharmony_ci 36598c2ecf20Sopenharmony_ci /* Setup MPEG bus */ 36608c2ecf20Sopenharmony_ci status = mpegts_dto_setup(state, OM_DVBT); 36618c2ecf20Sopenharmony_ci if (status < 0) 36628c2ecf20Sopenharmony_ci goto error; 36638c2ecf20Sopenharmony_ci /* Set DVBT Presets */ 36648c2ecf20Sopenharmony_ci status = dvbt_activate_presets(state); 36658c2ecf20Sopenharmony_ci if (status < 0) 36668c2ecf20Sopenharmony_ci goto error; 36678c2ecf20Sopenharmony_ci 36688c2ecf20Sopenharmony_cierror: 36698c2ecf20Sopenharmony_ci if (status < 0) 36708c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 36718c2ecf20Sopenharmony_ci return status; 36728c2ecf20Sopenharmony_ci} 36738c2ecf20Sopenharmony_ci 36748c2ecf20Sopenharmony_ci/*============================================================================*/ 36758c2ecf20Sopenharmony_ci/* 36768c2ecf20Sopenharmony_ci* \brief start dvbt demodulating for channel. 36778c2ecf20Sopenharmony_ci* \param demod instance of demodulator. 36788c2ecf20Sopenharmony_ci* \return DRXStatus_t. 36798c2ecf20Sopenharmony_ci*/ 36808c2ecf20Sopenharmony_cistatic int dvbt_start(struct drxk_state *state) 36818c2ecf20Sopenharmony_ci{ 36828c2ecf20Sopenharmony_ci u16 param1; 36838c2ecf20Sopenharmony_ci int status; 36848c2ecf20Sopenharmony_ci /* drxk_ofdm_sc_cmd_t scCmd; */ 36858c2ecf20Sopenharmony_ci 36868c2ecf20Sopenharmony_ci dprintk(1, "\n"); 36878c2ecf20Sopenharmony_ci /* start correct processes to get in lock */ 36888c2ecf20Sopenharmony_ci /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */ 36898c2ecf20Sopenharmony_ci param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN; 36908c2ecf20Sopenharmony_ci status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, 36918c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 36928c2ecf20Sopenharmony_ci 0, 0, 0); 36938c2ecf20Sopenharmony_ci if (status < 0) 36948c2ecf20Sopenharmony_ci goto error; 36958c2ecf20Sopenharmony_ci /* start FEC OC */ 36968c2ecf20Sopenharmony_ci status = mpegts_start(state); 36978c2ecf20Sopenharmony_ci if (status < 0) 36988c2ecf20Sopenharmony_ci goto error; 36998c2ecf20Sopenharmony_ci status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 37008c2ecf20Sopenharmony_ci if (status < 0) 37018c2ecf20Sopenharmony_ci goto error; 37028c2ecf20Sopenharmony_cierror: 37038c2ecf20Sopenharmony_ci if (status < 0) 37048c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 37058c2ecf20Sopenharmony_ci return status; 37068c2ecf20Sopenharmony_ci} 37078c2ecf20Sopenharmony_ci 37088c2ecf20Sopenharmony_ci 37098c2ecf20Sopenharmony_ci/*============================================================================*/ 37108c2ecf20Sopenharmony_ci 37118c2ecf20Sopenharmony_ci/* 37128c2ecf20Sopenharmony_ci* \brief Set up dvbt demodulator for channel. 37138c2ecf20Sopenharmony_ci* \param demod instance of demodulator. 37148c2ecf20Sopenharmony_ci* \return DRXStatus_t. 37158c2ecf20Sopenharmony_ci* // original DVBTSetChannel() 37168c2ecf20Sopenharmony_ci*/ 37178c2ecf20Sopenharmony_cistatic int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, 37188c2ecf20Sopenharmony_ci s32 tuner_freq_offset) 37198c2ecf20Sopenharmony_ci{ 37208c2ecf20Sopenharmony_ci u16 cmd_result = 0; 37218c2ecf20Sopenharmony_ci u16 transmission_params = 0; 37228c2ecf20Sopenharmony_ci u16 operation_mode = 0; 37238c2ecf20Sopenharmony_ci u32 iqm_rc_rate_ofs = 0; 37248c2ecf20Sopenharmony_ci u32 bandwidth = 0; 37258c2ecf20Sopenharmony_ci u16 param1; 37268c2ecf20Sopenharmony_ci int status; 37278c2ecf20Sopenharmony_ci 37288c2ecf20Sopenharmony_ci dprintk(1, "IF =%d, TFO = %d\n", 37298c2ecf20Sopenharmony_ci intermediate_freqk_hz, tuner_freq_offset); 37308c2ecf20Sopenharmony_ci 37318c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 37328c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 37338c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 37348c2ecf20Sopenharmony_ci if (status < 0) 37358c2ecf20Sopenharmony_ci goto error; 37368c2ecf20Sopenharmony_ci 37378c2ecf20Sopenharmony_ci /* Halt SCU to enable safe non-atomic accesses */ 37388c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 37398c2ecf20Sopenharmony_ci if (status < 0) 37408c2ecf20Sopenharmony_ci goto error; 37418c2ecf20Sopenharmony_ci 37428c2ecf20Sopenharmony_ci /* Stop processors */ 37438c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP); 37448c2ecf20Sopenharmony_ci if (status < 0) 37458c2ecf20Sopenharmony_ci goto error; 37468c2ecf20Sopenharmony_ci status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP); 37478c2ecf20Sopenharmony_ci if (status < 0) 37488c2ecf20Sopenharmony_ci goto error; 37498c2ecf20Sopenharmony_ci 37508c2ecf20Sopenharmony_ci /* Mandatory fix, always stop CP, required to set spl offset back to 37518c2ecf20Sopenharmony_ci hardware default (is set to 0 by ucode during pilot detection */ 37528c2ecf20Sopenharmony_ci status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP); 37538c2ecf20Sopenharmony_ci if (status < 0) 37548c2ecf20Sopenharmony_ci goto error; 37558c2ecf20Sopenharmony_ci 37568c2ecf20Sopenharmony_ci /*== Write channel settings to device ================================*/ 37578c2ecf20Sopenharmony_ci 37588c2ecf20Sopenharmony_ci /* mode */ 37598c2ecf20Sopenharmony_ci switch (state->props.transmission_mode) { 37608c2ecf20Sopenharmony_ci case TRANSMISSION_MODE_AUTO: 37618c2ecf20Sopenharmony_ci default: 37628c2ecf20Sopenharmony_ci operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; 37638c2ecf20Sopenharmony_ci fallthrough; /* try first guess DRX_FFTMODE_8K */ 37648c2ecf20Sopenharmony_ci case TRANSMISSION_MODE_8K: 37658c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; 37668c2ecf20Sopenharmony_ci break; 37678c2ecf20Sopenharmony_ci case TRANSMISSION_MODE_2K: 37688c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; 37698c2ecf20Sopenharmony_ci break; 37708c2ecf20Sopenharmony_ci } 37718c2ecf20Sopenharmony_ci 37728c2ecf20Sopenharmony_ci /* guard */ 37738c2ecf20Sopenharmony_ci switch (state->props.guard_interval) { 37748c2ecf20Sopenharmony_ci default: 37758c2ecf20Sopenharmony_ci case GUARD_INTERVAL_AUTO: 37768c2ecf20Sopenharmony_ci operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; 37778c2ecf20Sopenharmony_ci fallthrough; /* try first guess DRX_GUARD_1DIV4 */ 37788c2ecf20Sopenharmony_ci case GUARD_INTERVAL_1_4: 37798c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; 37808c2ecf20Sopenharmony_ci break; 37818c2ecf20Sopenharmony_ci case GUARD_INTERVAL_1_32: 37828c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; 37838c2ecf20Sopenharmony_ci break; 37848c2ecf20Sopenharmony_ci case GUARD_INTERVAL_1_16: 37858c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; 37868c2ecf20Sopenharmony_ci break; 37878c2ecf20Sopenharmony_ci case GUARD_INTERVAL_1_8: 37888c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; 37898c2ecf20Sopenharmony_ci break; 37908c2ecf20Sopenharmony_ci } 37918c2ecf20Sopenharmony_ci 37928c2ecf20Sopenharmony_ci /* hierarchy */ 37938c2ecf20Sopenharmony_ci switch (state->props.hierarchy) { 37948c2ecf20Sopenharmony_ci case HIERARCHY_AUTO: 37958c2ecf20Sopenharmony_ci case HIERARCHY_NONE: 37968c2ecf20Sopenharmony_ci default: 37978c2ecf20Sopenharmony_ci operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; 37988c2ecf20Sopenharmony_ci /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */ 37998c2ecf20Sopenharmony_ci /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ 38008c2ecf20Sopenharmony_ci fallthrough; 38018c2ecf20Sopenharmony_ci case HIERARCHY_1: 38028c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; 38038c2ecf20Sopenharmony_ci break; 38048c2ecf20Sopenharmony_ci case HIERARCHY_2: 38058c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; 38068c2ecf20Sopenharmony_ci break; 38078c2ecf20Sopenharmony_ci case HIERARCHY_4: 38088c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; 38098c2ecf20Sopenharmony_ci break; 38108c2ecf20Sopenharmony_ci } 38118c2ecf20Sopenharmony_ci 38128c2ecf20Sopenharmony_ci 38138c2ecf20Sopenharmony_ci /* modulation */ 38148c2ecf20Sopenharmony_ci switch (state->props.modulation) { 38158c2ecf20Sopenharmony_ci case QAM_AUTO: 38168c2ecf20Sopenharmony_ci default: 38178c2ecf20Sopenharmony_ci operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; 38188c2ecf20Sopenharmony_ci fallthrough; /* try first guess DRX_CONSTELLATION_QAM64 */ 38198c2ecf20Sopenharmony_ci case QAM_64: 38208c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; 38218c2ecf20Sopenharmony_ci break; 38228c2ecf20Sopenharmony_ci case QPSK: 38238c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; 38248c2ecf20Sopenharmony_ci break; 38258c2ecf20Sopenharmony_ci case QAM_16: 38268c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; 38278c2ecf20Sopenharmony_ci break; 38288c2ecf20Sopenharmony_ci } 38298c2ecf20Sopenharmony_ci#if 0 38308c2ecf20Sopenharmony_ci /* No hierarchical channels support in BDA */ 38318c2ecf20Sopenharmony_ci /* Priority (only for hierarchical channels) */ 38328c2ecf20Sopenharmony_ci switch (channel->priority) { 38338c2ecf20Sopenharmony_ci case DRX_PRIORITY_LOW: 38348c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; 38358c2ecf20Sopenharmony_ci WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38368c2ecf20Sopenharmony_ci OFDM_EC_SB_PRIOR_LO); 38378c2ecf20Sopenharmony_ci break; 38388c2ecf20Sopenharmony_ci case DRX_PRIORITY_HIGH: 38398c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 38408c2ecf20Sopenharmony_ci WR16(dev_addr, OFDM_EC_SB_PRIOR__A, 38418c2ecf20Sopenharmony_ci OFDM_EC_SB_PRIOR_HI)); 38428c2ecf20Sopenharmony_ci break; 38438c2ecf20Sopenharmony_ci case DRX_PRIORITY_UNKNOWN: 38448c2ecf20Sopenharmony_ci default: 38458c2ecf20Sopenharmony_ci status = -EINVAL; 38468c2ecf20Sopenharmony_ci goto error; 38478c2ecf20Sopenharmony_ci } 38488c2ecf20Sopenharmony_ci#else 38498c2ecf20Sopenharmony_ci /* Set Priority high */ 38508c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; 38518c2ecf20Sopenharmony_ci status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI); 38528c2ecf20Sopenharmony_ci if (status < 0) 38538c2ecf20Sopenharmony_ci goto error; 38548c2ecf20Sopenharmony_ci#endif 38558c2ecf20Sopenharmony_ci 38568c2ecf20Sopenharmony_ci /* coderate */ 38578c2ecf20Sopenharmony_ci switch (state->props.code_rate_HP) { 38588c2ecf20Sopenharmony_ci case FEC_AUTO: 38598c2ecf20Sopenharmony_ci default: 38608c2ecf20Sopenharmony_ci operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; 38618c2ecf20Sopenharmony_ci fallthrough; /* try first guess DRX_CODERATE_2DIV3 */ 38628c2ecf20Sopenharmony_ci case FEC_2_3: 38638c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; 38648c2ecf20Sopenharmony_ci break; 38658c2ecf20Sopenharmony_ci case FEC_1_2: 38668c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; 38678c2ecf20Sopenharmony_ci break; 38688c2ecf20Sopenharmony_ci case FEC_3_4: 38698c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; 38708c2ecf20Sopenharmony_ci break; 38718c2ecf20Sopenharmony_ci case FEC_5_6: 38728c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; 38738c2ecf20Sopenharmony_ci break; 38748c2ecf20Sopenharmony_ci case FEC_7_8: 38758c2ecf20Sopenharmony_ci transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; 38768c2ecf20Sopenharmony_ci break; 38778c2ecf20Sopenharmony_ci } 38788c2ecf20Sopenharmony_ci 38798c2ecf20Sopenharmony_ci /* 38808c2ecf20Sopenharmony_ci * SAW filter selection: normally not necessary, but if wanted 38818c2ecf20Sopenharmony_ci * the application can select a SAW filter via the driver by 38828c2ecf20Sopenharmony_ci * using UIOs 38838c2ecf20Sopenharmony_ci */ 38848c2ecf20Sopenharmony_ci 38858c2ecf20Sopenharmony_ci /* First determine real bandwidth (Hz) */ 38868c2ecf20Sopenharmony_ci /* Also set delay for impulse noise cruncher */ 38878c2ecf20Sopenharmony_ci /* 38888c2ecf20Sopenharmony_ci * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is 38898c2ecf20Sopenharmony_ci * changed by SC for fix for some 8K,1/8 guard but is restored by 38908c2ecf20Sopenharmony_ci * InitEC and ResetEC functions 38918c2ecf20Sopenharmony_ci */ 38928c2ecf20Sopenharmony_ci switch (state->props.bandwidth_hz) { 38938c2ecf20Sopenharmony_ci case 0: 38948c2ecf20Sopenharmony_ci state->props.bandwidth_hz = 8000000; 38958c2ecf20Sopenharmony_ci fallthrough; 38968c2ecf20Sopenharmony_ci case 8000000: 38978c2ecf20Sopenharmony_ci bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; 38988c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 38998c2ecf20Sopenharmony_ci 3052); 39008c2ecf20Sopenharmony_ci if (status < 0) 39018c2ecf20Sopenharmony_ci goto error; 39028c2ecf20Sopenharmony_ci /* cochannel protection for PAL 8 MHz */ 39038c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 39048c2ecf20Sopenharmony_ci 7); 39058c2ecf20Sopenharmony_ci if (status < 0) 39068c2ecf20Sopenharmony_ci goto error; 39078c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 39088c2ecf20Sopenharmony_ci 7); 39098c2ecf20Sopenharmony_ci if (status < 0) 39108c2ecf20Sopenharmony_ci goto error; 39118c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 39128c2ecf20Sopenharmony_ci 7); 39138c2ecf20Sopenharmony_ci if (status < 0) 39148c2ecf20Sopenharmony_ci goto error; 39158c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 39168c2ecf20Sopenharmony_ci 1); 39178c2ecf20Sopenharmony_ci if (status < 0) 39188c2ecf20Sopenharmony_ci goto error; 39198c2ecf20Sopenharmony_ci break; 39208c2ecf20Sopenharmony_ci case 7000000: 39218c2ecf20Sopenharmony_ci bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; 39228c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 39238c2ecf20Sopenharmony_ci 3491); 39248c2ecf20Sopenharmony_ci if (status < 0) 39258c2ecf20Sopenharmony_ci goto error; 39268c2ecf20Sopenharmony_ci /* cochannel protection for PAL 7 MHz */ 39278c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 39288c2ecf20Sopenharmony_ci 8); 39298c2ecf20Sopenharmony_ci if (status < 0) 39308c2ecf20Sopenharmony_ci goto error; 39318c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 39328c2ecf20Sopenharmony_ci 8); 39338c2ecf20Sopenharmony_ci if (status < 0) 39348c2ecf20Sopenharmony_ci goto error; 39358c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 39368c2ecf20Sopenharmony_ci 4); 39378c2ecf20Sopenharmony_ci if (status < 0) 39388c2ecf20Sopenharmony_ci goto error; 39398c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 39408c2ecf20Sopenharmony_ci 1); 39418c2ecf20Sopenharmony_ci if (status < 0) 39428c2ecf20Sopenharmony_ci goto error; 39438c2ecf20Sopenharmony_ci break; 39448c2ecf20Sopenharmony_ci case 6000000: 39458c2ecf20Sopenharmony_ci bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; 39468c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 39478c2ecf20Sopenharmony_ci 4073); 39488c2ecf20Sopenharmony_ci if (status < 0) 39498c2ecf20Sopenharmony_ci goto error; 39508c2ecf20Sopenharmony_ci /* cochannel protection for NTSC 6 MHz */ 39518c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 39528c2ecf20Sopenharmony_ci 19); 39538c2ecf20Sopenharmony_ci if (status < 0) 39548c2ecf20Sopenharmony_ci goto error; 39558c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 39568c2ecf20Sopenharmony_ci 19); 39578c2ecf20Sopenharmony_ci if (status < 0) 39588c2ecf20Sopenharmony_ci goto error; 39598c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 39608c2ecf20Sopenharmony_ci 14); 39618c2ecf20Sopenharmony_ci if (status < 0) 39628c2ecf20Sopenharmony_ci goto error; 39638c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 39648c2ecf20Sopenharmony_ci 1); 39658c2ecf20Sopenharmony_ci if (status < 0) 39668c2ecf20Sopenharmony_ci goto error; 39678c2ecf20Sopenharmony_ci break; 39688c2ecf20Sopenharmony_ci default: 39698c2ecf20Sopenharmony_ci status = -EINVAL; 39708c2ecf20Sopenharmony_ci goto error; 39718c2ecf20Sopenharmony_ci } 39728c2ecf20Sopenharmony_ci 39738c2ecf20Sopenharmony_ci if (iqm_rc_rate_ofs == 0) { 39748c2ecf20Sopenharmony_ci /* Now compute IQM_RC_RATE_OFS 39758c2ecf20Sopenharmony_ci (((SysFreq/BandWidth)/2)/2) -1) * 2^23) 39768c2ecf20Sopenharmony_ci => 39778c2ecf20Sopenharmony_ci ((SysFreq / BandWidth) * (2^21)) - (2^23) 39788c2ecf20Sopenharmony_ci */ 39798c2ecf20Sopenharmony_ci /* (SysFreq / BandWidth) * (2^28) */ 39808c2ecf20Sopenharmony_ci /* 39818c2ecf20Sopenharmony_ci * assert (MAX(sysClk)/MIN(bandwidth) < 16) 39828c2ecf20Sopenharmony_ci * => assert(MAX(sysClk) < 16*MIN(bandwidth)) 39838c2ecf20Sopenharmony_ci * => assert(109714272 > 48000000) = true 39848c2ecf20Sopenharmony_ci * so Frac 28 can be used 39858c2ecf20Sopenharmony_ci */ 39868c2ecf20Sopenharmony_ci iqm_rc_rate_ofs = Frac28a((u32) 39878c2ecf20Sopenharmony_ci ((state->m_sys_clock_freq * 39888c2ecf20Sopenharmony_ci 1000) / 3), bandwidth); 39898c2ecf20Sopenharmony_ci /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ 39908c2ecf20Sopenharmony_ci if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40) 39918c2ecf20Sopenharmony_ci iqm_rc_rate_ofs += 0x80L; 39928c2ecf20Sopenharmony_ci iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7; 39938c2ecf20Sopenharmony_ci /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */ 39948c2ecf20Sopenharmony_ci iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23); 39958c2ecf20Sopenharmony_ci } 39968c2ecf20Sopenharmony_ci 39978c2ecf20Sopenharmony_ci iqm_rc_rate_ofs &= 39988c2ecf20Sopenharmony_ci ((((u32) IQM_RC_RATE_OFS_HI__M) << 39998c2ecf20Sopenharmony_ci IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M); 40008c2ecf20Sopenharmony_ci status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs); 40018c2ecf20Sopenharmony_ci if (status < 0) 40028c2ecf20Sopenharmony_ci goto error; 40038c2ecf20Sopenharmony_ci 40048c2ecf20Sopenharmony_ci /* Bandwidth setting done */ 40058c2ecf20Sopenharmony_ci 40068c2ecf20Sopenharmony_ci#if 0 40078c2ecf20Sopenharmony_ci status = dvbt_set_frequency_shift(demod, channel, tuner_offset); 40088c2ecf20Sopenharmony_ci if (status < 0) 40098c2ecf20Sopenharmony_ci goto error; 40108c2ecf20Sopenharmony_ci#endif 40118c2ecf20Sopenharmony_ci status = set_frequency_shifter(state, intermediate_freqk_hz, 40128c2ecf20Sopenharmony_ci tuner_freq_offset, true); 40138c2ecf20Sopenharmony_ci if (status < 0) 40148c2ecf20Sopenharmony_ci goto error; 40158c2ecf20Sopenharmony_ci 40168c2ecf20Sopenharmony_ci /*== start SC, write channel settings to SC ==========================*/ 40178c2ecf20Sopenharmony_ci 40188c2ecf20Sopenharmony_ci /* Activate SCU to enable SCU commands */ 40198c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 40208c2ecf20Sopenharmony_ci if (status < 0) 40218c2ecf20Sopenharmony_ci goto error; 40228c2ecf20Sopenharmony_ci 40238c2ecf20Sopenharmony_ci /* Enable SC after setting all other parameters */ 40248c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_COMM_STATE__A, 0); 40258c2ecf20Sopenharmony_ci if (status < 0) 40268c2ecf20Sopenharmony_ci goto error; 40278c2ecf20Sopenharmony_ci status = write16(state, OFDM_SC_COMM_EXEC__A, 1); 40288c2ecf20Sopenharmony_ci if (status < 0) 40298c2ecf20Sopenharmony_ci goto error; 40308c2ecf20Sopenharmony_ci 40318c2ecf20Sopenharmony_ci 40328c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM 40338c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_START, 40348c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 40358c2ecf20Sopenharmony_ci if (status < 0) 40368c2ecf20Sopenharmony_ci goto error; 40378c2ecf20Sopenharmony_ci 40388c2ecf20Sopenharmony_ci /* Write SC parameter registers, set all AUTO flags in operation mode */ 40398c2ecf20Sopenharmony_ci param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M | 40408c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_OP_AUTO_GUARD__M | 40418c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_OP_AUTO_CONST__M | 40428c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_OP_AUTO_HIER__M | 40438c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_OP_AUTO_RATE__M); 40448c2ecf20Sopenharmony_ci status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, 40458c2ecf20Sopenharmony_ci 0, transmission_params, param1, 0, 0, 0); 40468c2ecf20Sopenharmony_ci if (status < 0) 40478c2ecf20Sopenharmony_ci goto error; 40488c2ecf20Sopenharmony_ci 40498c2ecf20Sopenharmony_ci if (!state->m_drxk_a3_rom_code) 40508c2ecf20Sopenharmony_ci status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed); 40518c2ecf20Sopenharmony_cierror: 40528c2ecf20Sopenharmony_ci if (status < 0) 40538c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 40548c2ecf20Sopenharmony_ci 40558c2ecf20Sopenharmony_ci return status; 40568c2ecf20Sopenharmony_ci} 40578c2ecf20Sopenharmony_ci 40588c2ecf20Sopenharmony_ci 40598c2ecf20Sopenharmony_ci/*============================================================================*/ 40608c2ecf20Sopenharmony_ci 40618c2ecf20Sopenharmony_ci/* 40628c2ecf20Sopenharmony_ci* \brief Retrieve lock status . 40638c2ecf20Sopenharmony_ci* \param demod Pointer to demodulator instance. 40648c2ecf20Sopenharmony_ci* \param lockStat Pointer to lock status structure. 40658c2ecf20Sopenharmony_ci* \return DRXStatus_t. 40668c2ecf20Sopenharmony_ci* 40678c2ecf20Sopenharmony_ci*/ 40688c2ecf20Sopenharmony_cistatic int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) 40698c2ecf20Sopenharmony_ci{ 40708c2ecf20Sopenharmony_ci int status; 40718c2ecf20Sopenharmony_ci const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M | 40728c2ecf20Sopenharmony_ci OFDM_SC_RA_RAM_LOCK_FEC__M); 40738c2ecf20Sopenharmony_ci const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M); 40748c2ecf20Sopenharmony_ci const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M; 40758c2ecf20Sopenharmony_ci 40768c2ecf20Sopenharmony_ci u16 sc_ra_ram_lock = 0; 40778c2ecf20Sopenharmony_ci u16 sc_comm_exec = 0; 40788c2ecf20Sopenharmony_ci 40798c2ecf20Sopenharmony_ci dprintk(1, "\n"); 40808c2ecf20Sopenharmony_ci 40818c2ecf20Sopenharmony_ci *p_lock_status = NOT_LOCKED; 40828c2ecf20Sopenharmony_ci /* driver 0.9.0 */ 40838c2ecf20Sopenharmony_ci /* Check if SC is running */ 40848c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec); 40858c2ecf20Sopenharmony_ci if (status < 0) 40868c2ecf20Sopenharmony_ci goto end; 40878c2ecf20Sopenharmony_ci if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP) 40888c2ecf20Sopenharmony_ci goto end; 40898c2ecf20Sopenharmony_ci 40908c2ecf20Sopenharmony_ci status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock); 40918c2ecf20Sopenharmony_ci if (status < 0) 40928c2ecf20Sopenharmony_ci goto end; 40938c2ecf20Sopenharmony_ci 40948c2ecf20Sopenharmony_ci if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask) 40958c2ecf20Sopenharmony_ci *p_lock_status = MPEG_LOCK; 40968c2ecf20Sopenharmony_ci else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask) 40978c2ecf20Sopenharmony_ci *p_lock_status = FEC_LOCK; 40988c2ecf20Sopenharmony_ci else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask) 40998c2ecf20Sopenharmony_ci *p_lock_status = DEMOD_LOCK; 41008c2ecf20Sopenharmony_ci else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) 41018c2ecf20Sopenharmony_ci *p_lock_status = NEVER_LOCK; 41028c2ecf20Sopenharmony_ciend: 41038c2ecf20Sopenharmony_ci if (status < 0) 41048c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 41058c2ecf20Sopenharmony_ci 41068c2ecf20Sopenharmony_ci return status; 41078c2ecf20Sopenharmony_ci} 41088c2ecf20Sopenharmony_ci 41098c2ecf20Sopenharmony_cistatic int power_up_qam(struct drxk_state *state) 41108c2ecf20Sopenharmony_ci{ 41118c2ecf20Sopenharmony_ci enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 41128c2ecf20Sopenharmony_ci int status; 41138c2ecf20Sopenharmony_ci 41148c2ecf20Sopenharmony_ci dprintk(1, "\n"); 41158c2ecf20Sopenharmony_ci status = ctrl_power_mode(state, &power_mode); 41168c2ecf20Sopenharmony_ci if (status < 0) 41178c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 41188c2ecf20Sopenharmony_ci 41198c2ecf20Sopenharmony_ci return status; 41208c2ecf20Sopenharmony_ci} 41218c2ecf20Sopenharmony_ci 41228c2ecf20Sopenharmony_ci 41238c2ecf20Sopenharmony_ci/* Power Down QAM */ 41248c2ecf20Sopenharmony_cistatic int power_down_qam(struct drxk_state *state) 41258c2ecf20Sopenharmony_ci{ 41268c2ecf20Sopenharmony_ci u16 data = 0; 41278c2ecf20Sopenharmony_ci u16 cmd_result; 41288c2ecf20Sopenharmony_ci int status = 0; 41298c2ecf20Sopenharmony_ci 41308c2ecf20Sopenharmony_ci dprintk(1, "\n"); 41318c2ecf20Sopenharmony_ci status = read16(state, SCU_COMM_EXEC__A, &data); 41328c2ecf20Sopenharmony_ci if (status < 0) 41338c2ecf20Sopenharmony_ci goto error; 41348c2ecf20Sopenharmony_ci if (data == SCU_COMM_EXEC_ACTIVE) { 41358c2ecf20Sopenharmony_ci /* 41368c2ecf20Sopenharmony_ci STOP demodulator 41378c2ecf20Sopenharmony_ci QAM and HW blocks 41388c2ecf20Sopenharmony_ci */ 41398c2ecf20Sopenharmony_ci /* stop all comstate->m_exec */ 41408c2ecf20Sopenharmony_ci status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 41418c2ecf20Sopenharmony_ci if (status < 0) 41428c2ecf20Sopenharmony_ci goto error; 41438c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 41448c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 41458c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 41468c2ecf20Sopenharmony_ci if (status < 0) 41478c2ecf20Sopenharmony_ci goto error; 41488c2ecf20Sopenharmony_ci } 41498c2ecf20Sopenharmony_ci /* powerdown AFE */ 41508c2ecf20Sopenharmony_ci status = set_iqm_af(state, false); 41518c2ecf20Sopenharmony_ci 41528c2ecf20Sopenharmony_cierror: 41538c2ecf20Sopenharmony_ci if (status < 0) 41548c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 41558c2ecf20Sopenharmony_ci 41568c2ecf20Sopenharmony_ci return status; 41578c2ecf20Sopenharmony_ci} 41588c2ecf20Sopenharmony_ci 41598c2ecf20Sopenharmony_ci/*============================================================================*/ 41608c2ecf20Sopenharmony_ci 41618c2ecf20Sopenharmony_ci/* 41628c2ecf20Sopenharmony_ci* \brief Setup of the QAM Measurement intervals for signal quality 41638c2ecf20Sopenharmony_ci* \param demod instance of demod. 41648c2ecf20Sopenharmony_ci* \param modulation current modulation. 41658c2ecf20Sopenharmony_ci* \return DRXStatus_t. 41668c2ecf20Sopenharmony_ci* 41678c2ecf20Sopenharmony_ci* NOTE: 41688c2ecf20Sopenharmony_ci* Take into account that for certain settings the errorcounters can overflow. 41698c2ecf20Sopenharmony_ci* The implementation does not check this. 41708c2ecf20Sopenharmony_ci* 41718c2ecf20Sopenharmony_ci*/ 41728c2ecf20Sopenharmony_cistatic int set_qam_measurement(struct drxk_state *state, 41738c2ecf20Sopenharmony_ci enum e_drxk_constellation modulation, 41748c2ecf20Sopenharmony_ci u32 symbol_rate) 41758c2ecf20Sopenharmony_ci{ 41768c2ecf20Sopenharmony_ci u32 fec_bits_desired = 0; /* BER accounting period */ 41778c2ecf20Sopenharmony_ci u32 fec_rs_period_total = 0; /* Total period */ 41788c2ecf20Sopenharmony_ci u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */ 41798c2ecf20Sopenharmony_ci u16 fec_rs_period = 0; /* Value for corresponding I2C register */ 41808c2ecf20Sopenharmony_ci int status = 0; 41818c2ecf20Sopenharmony_ci 41828c2ecf20Sopenharmony_ci dprintk(1, "\n"); 41838c2ecf20Sopenharmony_ci 41848c2ecf20Sopenharmony_ci fec_rs_prescale = 1; 41858c2ecf20Sopenharmony_ci /* fec_bits_desired = symbol_rate [kHz] * 41868c2ecf20Sopenharmony_ci FrameLenght [ms] * 41878c2ecf20Sopenharmony_ci (modulation + 1) * 41888c2ecf20Sopenharmony_ci SyncLoss (== 1) * 41898c2ecf20Sopenharmony_ci ViterbiLoss (==1) 41908c2ecf20Sopenharmony_ci */ 41918c2ecf20Sopenharmony_ci switch (modulation) { 41928c2ecf20Sopenharmony_ci case DRX_CONSTELLATION_QAM16: 41938c2ecf20Sopenharmony_ci fec_bits_desired = 4 * symbol_rate; 41948c2ecf20Sopenharmony_ci break; 41958c2ecf20Sopenharmony_ci case DRX_CONSTELLATION_QAM32: 41968c2ecf20Sopenharmony_ci fec_bits_desired = 5 * symbol_rate; 41978c2ecf20Sopenharmony_ci break; 41988c2ecf20Sopenharmony_ci case DRX_CONSTELLATION_QAM64: 41998c2ecf20Sopenharmony_ci fec_bits_desired = 6 * symbol_rate; 42008c2ecf20Sopenharmony_ci break; 42018c2ecf20Sopenharmony_ci case DRX_CONSTELLATION_QAM128: 42028c2ecf20Sopenharmony_ci fec_bits_desired = 7 * symbol_rate; 42038c2ecf20Sopenharmony_ci break; 42048c2ecf20Sopenharmony_ci case DRX_CONSTELLATION_QAM256: 42058c2ecf20Sopenharmony_ci fec_bits_desired = 8 * symbol_rate; 42068c2ecf20Sopenharmony_ci break; 42078c2ecf20Sopenharmony_ci default: 42088c2ecf20Sopenharmony_ci status = -EINVAL; 42098c2ecf20Sopenharmony_ci } 42108c2ecf20Sopenharmony_ci if (status < 0) 42118c2ecf20Sopenharmony_ci goto error; 42128c2ecf20Sopenharmony_ci 42138c2ecf20Sopenharmony_ci fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */ 42148c2ecf20Sopenharmony_ci fec_bits_desired *= 500; /* meas. period [ms] */ 42158c2ecf20Sopenharmony_ci 42168c2ecf20Sopenharmony_ci /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */ 42178c2ecf20Sopenharmony_ci /* fec_rs_period_total = fec_bits_desired / 1632 */ 42188c2ecf20Sopenharmony_ci fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */ 42198c2ecf20Sopenharmony_ci 42208c2ecf20Sopenharmony_ci /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */ 42218c2ecf20Sopenharmony_ci fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16); 42228c2ecf20Sopenharmony_ci if (fec_rs_prescale == 0) { 42238c2ecf20Sopenharmony_ci /* Divide by zero (though impossible) */ 42248c2ecf20Sopenharmony_ci status = -EINVAL; 42258c2ecf20Sopenharmony_ci if (status < 0) 42268c2ecf20Sopenharmony_ci goto error; 42278c2ecf20Sopenharmony_ci } 42288c2ecf20Sopenharmony_ci fec_rs_period = 42298c2ecf20Sopenharmony_ci ((u16) fec_rs_period_total + 42308c2ecf20Sopenharmony_ci (fec_rs_prescale >> 1)) / fec_rs_prescale; 42318c2ecf20Sopenharmony_ci 42328c2ecf20Sopenharmony_ci /* write corresponding registers */ 42338c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period); 42348c2ecf20Sopenharmony_ci if (status < 0) 42358c2ecf20Sopenharmony_ci goto error; 42368c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 42378c2ecf20Sopenharmony_ci fec_rs_prescale); 42388c2ecf20Sopenharmony_ci if (status < 0) 42398c2ecf20Sopenharmony_ci goto error; 42408c2ecf20Sopenharmony_ci status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period); 42418c2ecf20Sopenharmony_cierror: 42428c2ecf20Sopenharmony_ci if (status < 0) 42438c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 42448c2ecf20Sopenharmony_ci return status; 42458c2ecf20Sopenharmony_ci} 42468c2ecf20Sopenharmony_ci 42478c2ecf20Sopenharmony_cistatic int set_qam16(struct drxk_state *state) 42488c2ecf20Sopenharmony_ci{ 42498c2ecf20Sopenharmony_ci int status = 0; 42508c2ecf20Sopenharmony_ci 42518c2ecf20Sopenharmony_ci dprintk(1, "\n"); 42528c2ecf20Sopenharmony_ci /* QAM Equalizer Setup */ 42538c2ecf20Sopenharmony_ci /* Equalizer */ 42548c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517); 42558c2ecf20Sopenharmony_ci if (status < 0) 42568c2ecf20Sopenharmony_ci goto error; 42578c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517); 42588c2ecf20Sopenharmony_ci if (status < 0) 42598c2ecf20Sopenharmony_ci goto error; 42608c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517); 42618c2ecf20Sopenharmony_ci if (status < 0) 42628c2ecf20Sopenharmony_ci goto error; 42638c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517); 42648c2ecf20Sopenharmony_ci if (status < 0) 42658c2ecf20Sopenharmony_ci goto error; 42668c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517); 42678c2ecf20Sopenharmony_ci if (status < 0) 42688c2ecf20Sopenharmony_ci goto error; 42698c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517); 42708c2ecf20Sopenharmony_ci if (status < 0) 42718c2ecf20Sopenharmony_ci goto error; 42728c2ecf20Sopenharmony_ci /* Decision Feedback Equalizer */ 42738c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN0__A, 2); 42748c2ecf20Sopenharmony_ci if (status < 0) 42758c2ecf20Sopenharmony_ci goto error; 42768c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN1__A, 2); 42778c2ecf20Sopenharmony_ci if (status < 0) 42788c2ecf20Sopenharmony_ci goto error; 42798c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN2__A, 2); 42808c2ecf20Sopenharmony_ci if (status < 0) 42818c2ecf20Sopenharmony_ci goto error; 42828c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN3__A, 2); 42838c2ecf20Sopenharmony_ci if (status < 0) 42848c2ecf20Sopenharmony_ci goto error; 42858c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN4__A, 2); 42868c2ecf20Sopenharmony_ci if (status < 0) 42878c2ecf20Sopenharmony_ci goto error; 42888c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 42898c2ecf20Sopenharmony_ci if (status < 0) 42908c2ecf20Sopenharmony_ci goto error; 42918c2ecf20Sopenharmony_ci 42928c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_HWM__A, 5); 42938c2ecf20Sopenharmony_ci if (status < 0) 42948c2ecf20Sopenharmony_ci goto error; 42958c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_AWM__A, 4); 42968c2ecf20Sopenharmony_ci if (status < 0) 42978c2ecf20Sopenharmony_ci goto error; 42988c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_LWM__A, 3); 42998c2ecf20Sopenharmony_ci if (status < 0) 43008c2ecf20Sopenharmony_ci goto error; 43018c2ecf20Sopenharmony_ci 43028c2ecf20Sopenharmony_ci /* QAM Slicer Settings */ 43038c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 43048c2ecf20Sopenharmony_ci DRXK_QAM_SL_SIG_POWER_QAM16); 43058c2ecf20Sopenharmony_ci if (status < 0) 43068c2ecf20Sopenharmony_ci goto error; 43078c2ecf20Sopenharmony_ci 43088c2ecf20Sopenharmony_ci /* QAM Loop Controller Coeficients */ 43098c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 43108c2ecf20Sopenharmony_ci if (status < 0) 43118c2ecf20Sopenharmony_ci goto error; 43128c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 43138c2ecf20Sopenharmony_ci if (status < 0) 43148c2ecf20Sopenharmony_ci goto error; 43158c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 43168c2ecf20Sopenharmony_ci if (status < 0) 43178c2ecf20Sopenharmony_ci goto error; 43188c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 43198c2ecf20Sopenharmony_ci if (status < 0) 43208c2ecf20Sopenharmony_ci goto error; 43218c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 43228c2ecf20Sopenharmony_ci if (status < 0) 43238c2ecf20Sopenharmony_ci goto error; 43248c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 43258c2ecf20Sopenharmony_ci if (status < 0) 43268c2ecf20Sopenharmony_ci goto error; 43278c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 43288c2ecf20Sopenharmony_ci if (status < 0) 43298c2ecf20Sopenharmony_ci goto error; 43308c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 43318c2ecf20Sopenharmony_ci if (status < 0) 43328c2ecf20Sopenharmony_ci goto error; 43338c2ecf20Sopenharmony_ci 43348c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 43358c2ecf20Sopenharmony_ci if (status < 0) 43368c2ecf20Sopenharmony_ci goto error; 43378c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 43388c2ecf20Sopenharmony_ci if (status < 0) 43398c2ecf20Sopenharmony_ci goto error; 43408c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 43418c2ecf20Sopenharmony_ci if (status < 0) 43428c2ecf20Sopenharmony_ci goto error; 43438c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 43448c2ecf20Sopenharmony_ci if (status < 0) 43458c2ecf20Sopenharmony_ci goto error; 43468c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 43478c2ecf20Sopenharmony_ci if (status < 0) 43488c2ecf20Sopenharmony_ci goto error; 43498c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 43508c2ecf20Sopenharmony_ci if (status < 0) 43518c2ecf20Sopenharmony_ci goto error; 43528c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 43538c2ecf20Sopenharmony_ci if (status < 0) 43548c2ecf20Sopenharmony_ci goto error; 43558c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 43568c2ecf20Sopenharmony_ci if (status < 0) 43578c2ecf20Sopenharmony_ci goto error; 43588c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32); 43598c2ecf20Sopenharmony_ci if (status < 0) 43608c2ecf20Sopenharmony_ci goto error; 43618c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 43628c2ecf20Sopenharmony_ci if (status < 0) 43638c2ecf20Sopenharmony_ci goto error; 43648c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 43658c2ecf20Sopenharmony_ci if (status < 0) 43668c2ecf20Sopenharmony_ci goto error; 43678c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 43688c2ecf20Sopenharmony_ci if (status < 0) 43698c2ecf20Sopenharmony_ci goto error; 43708c2ecf20Sopenharmony_ci 43718c2ecf20Sopenharmony_ci 43728c2ecf20Sopenharmony_ci /* QAM State Machine (FSM) Thresholds */ 43738c2ecf20Sopenharmony_ci 43748c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140); 43758c2ecf20Sopenharmony_ci if (status < 0) 43768c2ecf20Sopenharmony_ci goto error; 43778c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 43788c2ecf20Sopenharmony_ci if (status < 0) 43798c2ecf20Sopenharmony_ci goto error; 43808c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95); 43818c2ecf20Sopenharmony_ci if (status < 0) 43828c2ecf20Sopenharmony_ci goto error; 43838c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120); 43848c2ecf20Sopenharmony_ci if (status < 0) 43858c2ecf20Sopenharmony_ci goto error; 43868c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230); 43878c2ecf20Sopenharmony_ci if (status < 0) 43888c2ecf20Sopenharmony_ci goto error; 43898c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105); 43908c2ecf20Sopenharmony_ci if (status < 0) 43918c2ecf20Sopenharmony_ci goto error; 43928c2ecf20Sopenharmony_ci 43938c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 43948c2ecf20Sopenharmony_ci if (status < 0) 43958c2ecf20Sopenharmony_ci goto error; 43968c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 43978c2ecf20Sopenharmony_ci if (status < 0) 43988c2ecf20Sopenharmony_ci goto error; 43998c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24); 44008c2ecf20Sopenharmony_ci if (status < 0) 44018c2ecf20Sopenharmony_ci goto error; 44028c2ecf20Sopenharmony_ci 44038c2ecf20Sopenharmony_ci 44048c2ecf20Sopenharmony_ci /* QAM FSM Tracking Parameters */ 44058c2ecf20Sopenharmony_ci 44068c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16); 44078c2ecf20Sopenharmony_ci if (status < 0) 44088c2ecf20Sopenharmony_ci goto error; 44098c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220); 44108c2ecf20Sopenharmony_ci if (status < 0) 44118c2ecf20Sopenharmony_ci goto error; 44128c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25); 44138c2ecf20Sopenharmony_ci if (status < 0) 44148c2ecf20Sopenharmony_ci goto error; 44158c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6); 44168c2ecf20Sopenharmony_ci if (status < 0) 44178c2ecf20Sopenharmony_ci goto error; 44188c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24); 44198c2ecf20Sopenharmony_ci if (status < 0) 44208c2ecf20Sopenharmony_ci goto error; 44218c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65); 44228c2ecf20Sopenharmony_ci if (status < 0) 44238c2ecf20Sopenharmony_ci goto error; 44248c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127); 44258c2ecf20Sopenharmony_ci if (status < 0) 44268c2ecf20Sopenharmony_ci goto error; 44278c2ecf20Sopenharmony_ci 44288c2ecf20Sopenharmony_cierror: 44298c2ecf20Sopenharmony_ci if (status < 0) 44308c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 44318c2ecf20Sopenharmony_ci return status; 44328c2ecf20Sopenharmony_ci} 44338c2ecf20Sopenharmony_ci 44348c2ecf20Sopenharmony_ci/*============================================================================*/ 44358c2ecf20Sopenharmony_ci 44368c2ecf20Sopenharmony_ci/* 44378c2ecf20Sopenharmony_ci* \brief QAM32 specific setup 44388c2ecf20Sopenharmony_ci* \param demod instance of demod. 44398c2ecf20Sopenharmony_ci* \return DRXStatus_t. 44408c2ecf20Sopenharmony_ci*/ 44418c2ecf20Sopenharmony_cistatic int set_qam32(struct drxk_state *state) 44428c2ecf20Sopenharmony_ci{ 44438c2ecf20Sopenharmony_ci int status = 0; 44448c2ecf20Sopenharmony_ci 44458c2ecf20Sopenharmony_ci dprintk(1, "\n"); 44468c2ecf20Sopenharmony_ci 44478c2ecf20Sopenharmony_ci /* QAM Equalizer Setup */ 44488c2ecf20Sopenharmony_ci /* Equalizer */ 44498c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707); 44508c2ecf20Sopenharmony_ci if (status < 0) 44518c2ecf20Sopenharmony_ci goto error; 44528c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707); 44538c2ecf20Sopenharmony_ci if (status < 0) 44548c2ecf20Sopenharmony_ci goto error; 44558c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707); 44568c2ecf20Sopenharmony_ci if (status < 0) 44578c2ecf20Sopenharmony_ci goto error; 44588c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707); 44598c2ecf20Sopenharmony_ci if (status < 0) 44608c2ecf20Sopenharmony_ci goto error; 44618c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707); 44628c2ecf20Sopenharmony_ci if (status < 0) 44638c2ecf20Sopenharmony_ci goto error; 44648c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707); 44658c2ecf20Sopenharmony_ci if (status < 0) 44668c2ecf20Sopenharmony_ci goto error; 44678c2ecf20Sopenharmony_ci 44688c2ecf20Sopenharmony_ci /* Decision Feedback Equalizer */ 44698c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN0__A, 3); 44708c2ecf20Sopenharmony_ci if (status < 0) 44718c2ecf20Sopenharmony_ci goto error; 44728c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN1__A, 3); 44738c2ecf20Sopenharmony_ci if (status < 0) 44748c2ecf20Sopenharmony_ci goto error; 44758c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN2__A, 3); 44768c2ecf20Sopenharmony_ci if (status < 0) 44778c2ecf20Sopenharmony_ci goto error; 44788c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN3__A, 3); 44798c2ecf20Sopenharmony_ci if (status < 0) 44808c2ecf20Sopenharmony_ci goto error; 44818c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 44828c2ecf20Sopenharmony_ci if (status < 0) 44838c2ecf20Sopenharmony_ci goto error; 44848c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 44858c2ecf20Sopenharmony_ci if (status < 0) 44868c2ecf20Sopenharmony_ci goto error; 44878c2ecf20Sopenharmony_ci 44888c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_HWM__A, 6); 44898c2ecf20Sopenharmony_ci if (status < 0) 44908c2ecf20Sopenharmony_ci goto error; 44918c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_AWM__A, 5); 44928c2ecf20Sopenharmony_ci if (status < 0) 44938c2ecf20Sopenharmony_ci goto error; 44948c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_LWM__A, 3); 44958c2ecf20Sopenharmony_ci if (status < 0) 44968c2ecf20Sopenharmony_ci goto error; 44978c2ecf20Sopenharmony_ci 44988c2ecf20Sopenharmony_ci /* QAM Slicer Settings */ 44998c2ecf20Sopenharmony_ci 45008c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 45018c2ecf20Sopenharmony_ci DRXK_QAM_SL_SIG_POWER_QAM32); 45028c2ecf20Sopenharmony_ci if (status < 0) 45038c2ecf20Sopenharmony_ci goto error; 45048c2ecf20Sopenharmony_ci 45058c2ecf20Sopenharmony_ci 45068c2ecf20Sopenharmony_ci /* QAM Loop Controller Coeficients */ 45078c2ecf20Sopenharmony_ci 45088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 45098c2ecf20Sopenharmony_ci if (status < 0) 45108c2ecf20Sopenharmony_ci goto error; 45118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 45128c2ecf20Sopenharmony_ci if (status < 0) 45138c2ecf20Sopenharmony_ci goto error; 45148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 45158c2ecf20Sopenharmony_ci if (status < 0) 45168c2ecf20Sopenharmony_ci goto error; 45178c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 45188c2ecf20Sopenharmony_ci if (status < 0) 45198c2ecf20Sopenharmony_ci goto error; 45208c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 45218c2ecf20Sopenharmony_ci if (status < 0) 45228c2ecf20Sopenharmony_ci goto error; 45238c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 45248c2ecf20Sopenharmony_ci if (status < 0) 45258c2ecf20Sopenharmony_ci goto error; 45268c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 45278c2ecf20Sopenharmony_ci if (status < 0) 45288c2ecf20Sopenharmony_ci goto error; 45298c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 45308c2ecf20Sopenharmony_ci if (status < 0) 45318c2ecf20Sopenharmony_ci goto error; 45328c2ecf20Sopenharmony_ci 45338c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 45348c2ecf20Sopenharmony_ci if (status < 0) 45358c2ecf20Sopenharmony_ci goto error; 45368c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20); 45378c2ecf20Sopenharmony_ci if (status < 0) 45388c2ecf20Sopenharmony_ci goto error; 45398c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80); 45408c2ecf20Sopenharmony_ci if (status < 0) 45418c2ecf20Sopenharmony_ci goto error; 45428c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 45438c2ecf20Sopenharmony_ci if (status < 0) 45448c2ecf20Sopenharmony_ci goto error; 45458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20); 45468c2ecf20Sopenharmony_ci if (status < 0) 45478c2ecf20Sopenharmony_ci goto error; 45488c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 45498c2ecf20Sopenharmony_ci if (status < 0) 45508c2ecf20Sopenharmony_ci goto error; 45518c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 45528c2ecf20Sopenharmony_ci if (status < 0) 45538c2ecf20Sopenharmony_ci goto error; 45548c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16); 45558c2ecf20Sopenharmony_ci if (status < 0) 45568c2ecf20Sopenharmony_ci goto error; 45578c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16); 45588c2ecf20Sopenharmony_ci if (status < 0) 45598c2ecf20Sopenharmony_ci goto error; 45608c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 45618c2ecf20Sopenharmony_ci if (status < 0) 45628c2ecf20Sopenharmony_ci goto error; 45638c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 45648c2ecf20Sopenharmony_ci if (status < 0) 45658c2ecf20Sopenharmony_ci goto error; 45668c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 45678c2ecf20Sopenharmony_ci if (status < 0) 45688c2ecf20Sopenharmony_ci goto error; 45698c2ecf20Sopenharmony_ci 45708c2ecf20Sopenharmony_ci 45718c2ecf20Sopenharmony_ci /* QAM State Machine (FSM) Thresholds */ 45728c2ecf20Sopenharmony_ci 45738c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90); 45748c2ecf20Sopenharmony_ci if (status < 0) 45758c2ecf20Sopenharmony_ci goto error; 45768c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50); 45778c2ecf20Sopenharmony_ci if (status < 0) 45788c2ecf20Sopenharmony_ci goto error; 45798c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 45808c2ecf20Sopenharmony_ci if (status < 0) 45818c2ecf20Sopenharmony_ci goto error; 45828c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 45838c2ecf20Sopenharmony_ci if (status < 0) 45848c2ecf20Sopenharmony_ci goto error; 45858c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170); 45868c2ecf20Sopenharmony_ci if (status < 0) 45878c2ecf20Sopenharmony_ci goto error; 45888c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 45898c2ecf20Sopenharmony_ci if (status < 0) 45908c2ecf20Sopenharmony_ci goto error; 45918c2ecf20Sopenharmony_ci 45928c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 45938c2ecf20Sopenharmony_ci if (status < 0) 45948c2ecf20Sopenharmony_ci goto error; 45958c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 45968c2ecf20Sopenharmony_ci if (status < 0) 45978c2ecf20Sopenharmony_ci goto error; 45988c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10); 45998c2ecf20Sopenharmony_ci if (status < 0) 46008c2ecf20Sopenharmony_ci goto error; 46018c2ecf20Sopenharmony_ci 46028c2ecf20Sopenharmony_ci 46038c2ecf20Sopenharmony_ci /* QAM FSM Tracking Parameters */ 46048c2ecf20Sopenharmony_ci 46058c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 46068c2ecf20Sopenharmony_ci if (status < 0) 46078c2ecf20Sopenharmony_ci goto error; 46088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140); 46098c2ecf20Sopenharmony_ci if (status < 0) 46108c2ecf20Sopenharmony_ci goto error; 46118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8); 46128c2ecf20Sopenharmony_ci if (status < 0) 46138c2ecf20Sopenharmony_ci goto error; 46148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16); 46158c2ecf20Sopenharmony_ci if (status < 0) 46168c2ecf20Sopenharmony_ci goto error; 46178c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26); 46188c2ecf20Sopenharmony_ci if (status < 0) 46198c2ecf20Sopenharmony_ci goto error; 46208c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56); 46218c2ecf20Sopenharmony_ci if (status < 0) 46228c2ecf20Sopenharmony_ci goto error; 46238c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86); 46248c2ecf20Sopenharmony_cierror: 46258c2ecf20Sopenharmony_ci if (status < 0) 46268c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 46278c2ecf20Sopenharmony_ci return status; 46288c2ecf20Sopenharmony_ci} 46298c2ecf20Sopenharmony_ci 46308c2ecf20Sopenharmony_ci/*============================================================================*/ 46318c2ecf20Sopenharmony_ci 46328c2ecf20Sopenharmony_ci/* 46338c2ecf20Sopenharmony_ci* \brief QAM64 specific setup 46348c2ecf20Sopenharmony_ci* \param demod instance of demod. 46358c2ecf20Sopenharmony_ci* \return DRXStatus_t. 46368c2ecf20Sopenharmony_ci*/ 46378c2ecf20Sopenharmony_cistatic int set_qam64(struct drxk_state *state) 46388c2ecf20Sopenharmony_ci{ 46398c2ecf20Sopenharmony_ci int status = 0; 46408c2ecf20Sopenharmony_ci 46418c2ecf20Sopenharmony_ci dprintk(1, "\n"); 46428c2ecf20Sopenharmony_ci /* QAM Equalizer Setup */ 46438c2ecf20Sopenharmony_ci /* Equalizer */ 46448c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336); 46458c2ecf20Sopenharmony_ci if (status < 0) 46468c2ecf20Sopenharmony_ci goto error; 46478c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618); 46488c2ecf20Sopenharmony_ci if (status < 0) 46498c2ecf20Sopenharmony_ci goto error; 46508c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988); 46518c2ecf20Sopenharmony_ci if (status < 0) 46528c2ecf20Sopenharmony_ci goto error; 46538c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809); 46548c2ecf20Sopenharmony_ci if (status < 0) 46558c2ecf20Sopenharmony_ci goto error; 46568c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809); 46578c2ecf20Sopenharmony_ci if (status < 0) 46588c2ecf20Sopenharmony_ci goto error; 46598c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609); 46608c2ecf20Sopenharmony_ci if (status < 0) 46618c2ecf20Sopenharmony_ci goto error; 46628c2ecf20Sopenharmony_ci 46638c2ecf20Sopenharmony_ci /* Decision Feedback Equalizer */ 46648c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN0__A, 4); 46658c2ecf20Sopenharmony_ci if (status < 0) 46668c2ecf20Sopenharmony_ci goto error; 46678c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN1__A, 4); 46688c2ecf20Sopenharmony_ci if (status < 0) 46698c2ecf20Sopenharmony_ci goto error; 46708c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN2__A, 4); 46718c2ecf20Sopenharmony_ci if (status < 0) 46728c2ecf20Sopenharmony_ci goto error; 46738c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN3__A, 4); 46748c2ecf20Sopenharmony_ci if (status < 0) 46758c2ecf20Sopenharmony_ci goto error; 46768c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN4__A, 3); 46778c2ecf20Sopenharmony_ci if (status < 0) 46788c2ecf20Sopenharmony_ci goto error; 46798c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 46808c2ecf20Sopenharmony_ci if (status < 0) 46818c2ecf20Sopenharmony_ci goto error; 46828c2ecf20Sopenharmony_ci 46838c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_HWM__A, 5); 46848c2ecf20Sopenharmony_ci if (status < 0) 46858c2ecf20Sopenharmony_ci goto error; 46868c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_AWM__A, 4); 46878c2ecf20Sopenharmony_ci if (status < 0) 46888c2ecf20Sopenharmony_ci goto error; 46898c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_LWM__A, 3); 46908c2ecf20Sopenharmony_ci if (status < 0) 46918c2ecf20Sopenharmony_ci goto error; 46928c2ecf20Sopenharmony_ci 46938c2ecf20Sopenharmony_ci /* QAM Slicer Settings */ 46948c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 46958c2ecf20Sopenharmony_ci DRXK_QAM_SL_SIG_POWER_QAM64); 46968c2ecf20Sopenharmony_ci if (status < 0) 46978c2ecf20Sopenharmony_ci goto error; 46988c2ecf20Sopenharmony_ci 46998c2ecf20Sopenharmony_ci 47008c2ecf20Sopenharmony_ci /* QAM Loop Controller Coeficients */ 47018c2ecf20Sopenharmony_ci 47028c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 47038c2ecf20Sopenharmony_ci if (status < 0) 47048c2ecf20Sopenharmony_ci goto error; 47058c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 47068c2ecf20Sopenharmony_ci if (status < 0) 47078c2ecf20Sopenharmony_ci goto error; 47088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 47098c2ecf20Sopenharmony_ci if (status < 0) 47108c2ecf20Sopenharmony_ci goto error; 47118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 47128c2ecf20Sopenharmony_ci if (status < 0) 47138c2ecf20Sopenharmony_ci goto error; 47148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 47158c2ecf20Sopenharmony_ci if (status < 0) 47168c2ecf20Sopenharmony_ci goto error; 47178c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 47188c2ecf20Sopenharmony_ci if (status < 0) 47198c2ecf20Sopenharmony_ci goto error; 47208c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 47218c2ecf20Sopenharmony_ci if (status < 0) 47228c2ecf20Sopenharmony_ci goto error; 47238c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 47248c2ecf20Sopenharmony_ci if (status < 0) 47258c2ecf20Sopenharmony_ci goto error; 47268c2ecf20Sopenharmony_ci 47278c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 47288c2ecf20Sopenharmony_ci if (status < 0) 47298c2ecf20Sopenharmony_ci goto error; 47308c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30); 47318c2ecf20Sopenharmony_ci if (status < 0) 47328c2ecf20Sopenharmony_ci goto error; 47338c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100); 47348c2ecf20Sopenharmony_ci if (status < 0) 47358c2ecf20Sopenharmony_ci goto error; 47368c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 47378c2ecf20Sopenharmony_ci if (status < 0) 47388c2ecf20Sopenharmony_ci goto error; 47398c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30); 47408c2ecf20Sopenharmony_ci if (status < 0) 47418c2ecf20Sopenharmony_ci goto error; 47428c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50); 47438c2ecf20Sopenharmony_ci if (status < 0) 47448c2ecf20Sopenharmony_ci goto error; 47458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 47468c2ecf20Sopenharmony_ci if (status < 0) 47478c2ecf20Sopenharmony_ci goto error; 47488c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 47498c2ecf20Sopenharmony_ci if (status < 0) 47508c2ecf20Sopenharmony_ci goto error; 47518c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 47528c2ecf20Sopenharmony_ci if (status < 0) 47538c2ecf20Sopenharmony_ci goto error; 47548c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 47558c2ecf20Sopenharmony_ci if (status < 0) 47568c2ecf20Sopenharmony_ci goto error; 47578c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 47588c2ecf20Sopenharmony_ci if (status < 0) 47598c2ecf20Sopenharmony_ci goto error; 47608c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 47618c2ecf20Sopenharmony_ci if (status < 0) 47628c2ecf20Sopenharmony_ci goto error; 47638c2ecf20Sopenharmony_ci 47648c2ecf20Sopenharmony_ci 47658c2ecf20Sopenharmony_ci /* QAM State Machine (FSM) Thresholds */ 47668c2ecf20Sopenharmony_ci 47678c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100); 47688c2ecf20Sopenharmony_ci if (status < 0) 47698c2ecf20Sopenharmony_ci goto error; 47708c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 47718c2ecf20Sopenharmony_ci if (status < 0) 47728c2ecf20Sopenharmony_ci goto error; 47738c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 47748c2ecf20Sopenharmony_ci if (status < 0) 47758c2ecf20Sopenharmony_ci goto error; 47768c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110); 47778c2ecf20Sopenharmony_ci if (status < 0) 47788c2ecf20Sopenharmony_ci goto error; 47798c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200); 47808c2ecf20Sopenharmony_ci if (status < 0) 47818c2ecf20Sopenharmony_ci goto error; 47828c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95); 47838c2ecf20Sopenharmony_ci if (status < 0) 47848c2ecf20Sopenharmony_ci goto error; 47858c2ecf20Sopenharmony_ci 47868c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 47878c2ecf20Sopenharmony_ci if (status < 0) 47888c2ecf20Sopenharmony_ci goto error; 47898c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 47908c2ecf20Sopenharmony_ci if (status < 0) 47918c2ecf20Sopenharmony_ci goto error; 47928c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15); 47938c2ecf20Sopenharmony_ci if (status < 0) 47948c2ecf20Sopenharmony_ci goto error; 47958c2ecf20Sopenharmony_ci 47968c2ecf20Sopenharmony_ci 47978c2ecf20Sopenharmony_ci /* QAM FSM Tracking Parameters */ 47988c2ecf20Sopenharmony_ci 47998c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12); 48008c2ecf20Sopenharmony_ci if (status < 0) 48018c2ecf20Sopenharmony_ci goto error; 48028c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141); 48038c2ecf20Sopenharmony_ci if (status < 0) 48048c2ecf20Sopenharmony_ci goto error; 48058c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7); 48068c2ecf20Sopenharmony_ci if (status < 0) 48078c2ecf20Sopenharmony_ci goto error; 48088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0); 48098c2ecf20Sopenharmony_ci if (status < 0) 48108c2ecf20Sopenharmony_ci goto error; 48118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15); 48128c2ecf20Sopenharmony_ci if (status < 0) 48138c2ecf20Sopenharmony_ci goto error; 48148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45); 48158c2ecf20Sopenharmony_ci if (status < 0) 48168c2ecf20Sopenharmony_ci goto error; 48178c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80); 48188c2ecf20Sopenharmony_cierror: 48198c2ecf20Sopenharmony_ci if (status < 0) 48208c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 48218c2ecf20Sopenharmony_ci 48228c2ecf20Sopenharmony_ci return status; 48238c2ecf20Sopenharmony_ci} 48248c2ecf20Sopenharmony_ci 48258c2ecf20Sopenharmony_ci/*============================================================================*/ 48268c2ecf20Sopenharmony_ci 48278c2ecf20Sopenharmony_ci/* 48288c2ecf20Sopenharmony_ci* \brief QAM128 specific setup 48298c2ecf20Sopenharmony_ci* \param demod: instance of demod. 48308c2ecf20Sopenharmony_ci* \return DRXStatus_t. 48318c2ecf20Sopenharmony_ci*/ 48328c2ecf20Sopenharmony_cistatic int set_qam128(struct drxk_state *state) 48338c2ecf20Sopenharmony_ci{ 48348c2ecf20Sopenharmony_ci int status = 0; 48358c2ecf20Sopenharmony_ci 48368c2ecf20Sopenharmony_ci dprintk(1, "\n"); 48378c2ecf20Sopenharmony_ci /* QAM Equalizer Setup */ 48388c2ecf20Sopenharmony_ci /* Equalizer */ 48398c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564); 48408c2ecf20Sopenharmony_ci if (status < 0) 48418c2ecf20Sopenharmony_ci goto error; 48428c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598); 48438c2ecf20Sopenharmony_ci if (status < 0) 48448c2ecf20Sopenharmony_ci goto error; 48458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394); 48468c2ecf20Sopenharmony_ci if (status < 0) 48478c2ecf20Sopenharmony_ci goto error; 48488c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409); 48498c2ecf20Sopenharmony_ci if (status < 0) 48508c2ecf20Sopenharmony_ci goto error; 48518c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656); 48528c2ecf20Sopenharmony_ci if (status < 0) 48538c2ecf20Sopenharmony_ci goto error; 48548c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238); 48558c2ecf20Sopenharmony_ci if (status < 0) 48568c2ecf20Sopenharmony_ci goto error; 48578c2ecf20Sopenharmony_ci 48588c2ecf20Sopenharmony_ci /* Decision Feedback Equalizer */ 48598c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN0__A, 6); 48608c2ecf20Sopenharmony_ci if (status < 0) 48618c2ecf20Sopenharmony_ci goto error; 48628c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN1__A, 6); 48638c2ecf20Sopenharmony_ci if (status < 0) 48648c2ecf20Sopenharmony_ci goto error; 48658c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN2__A, 6); 48668c2ecf20Sopenharmony_ci if (status < 0) 48678c2ecf20Sopenharmony_ci goto error; 48688c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN3__A, 6); 48698c2ecf20Sopenharmony_ci if (status < 0) 48708c2ecf20Sopenharmony_ci goto error; 48718c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN4__A, 5); 48728c2ecf20Sopenharmony_ci if (status < 0) 48738c2ecf20Sopenharmony_ci goto error; 48748c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 48758c2ecf20Sopenharmony_ci if (status < 0) 48768c2ecf20Sopenharmony_ci goto error; 48778c2ecf20Sopenharmony_ci 48788c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_HWM__A, 6); 48798c2ecf20Sopenharmony_ci if (status < 0) 48808c2ecf20Sopenharmony_ci goto error; 48818c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_AWM__A, 5); 48828c2ecf20Sopenharmony_ci if (status < 0) 48838c2ecf20Sopenharmony_ci goto error; 48848c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_LWM__A, 3); 48858c2ecf20Sopenharmony_ci if (status < 0) 48868c2ecf20Sopenharmony_ci goto error; 48878c2ecf20Sopenharmony_ci 48888c2ecf20Sopenharmony_ci 48898c2ecf20Sopenharmony_ci /* QAM Slicer Settings */ 48908c2ecf20Sopenharmony_ci 48918c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 48928c2ecf20Sopenharmony_ci DRXK_QAM_SL_SIG_POWER_QAM128); 48938c2ecf20Sopenharmony_ci if (status < 0) 48948c2ecf20Sopenharmony_ci goto error; 48958c2ecf20Sopenharmony_ci 48968c2ecf20Sopenharmony_ci 48978c2ecf20Sopenharmony_ci /* QAM Loop Controller Coeficients */ 48988c2ecf20Sopenharmony_ci 48998c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 49008c2ecf20Sopenharmony_ci if (status < 0) 49018c2ecf20Sopenharmony_ci goto error; 49028c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 49038c2ecf20Sopenharmony_ci if (status < 0) 49048c2ecf20Sopenharmony_ci goto error; 49058c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 49068c2ecf20Sopenharmony_ci if (status < 0) 49078c2ecf20Sopenharmony_ci goto error; 49088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 49098c2ecf20Sopenharmony_ci if (status < 0) 49108c2ecf20Sopenharmony_ci goto error; 49118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 49128c2ecf20Sopenharmony_ci if (status < 0) 49138c2ecf20Sopenharmony_ci goto error; 49148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 49158c2ecf20Sopenharmony_ci if (status < 0) 49168c2ecf20Sopenharmony_ci goto error; 49178c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 49188c2ecf20Sopenharmony_ci if (status < 0) 49198c2ecf20Sopenharmony_ci goto error; 49208c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 49218c2ecf20Sopenharmony_ci if (status < 0) 49228c2ecf20Sopenharmony_ci goto error; 49238c2ecf20Sopenharmony_ci 49248c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 49258c2ecf20Sopenharmony_ci if (status < 0) 49268c2ecf20Sopenharmony_ci goto error; 49278c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40); 49288c2ecf20Sopenharmony_ci if (status < 0) 49298c2ecf20Sopenharmony_ci goto error; 49308c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120); 49318c2ecf20Sopenharmony_ci if (status < 0) 49328c2ecf20Sopenharmony_ci goto error; 49338c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 49348c2ecf20Sopenharmony_ci if (status < 0) 49358c2ecf20Sopenharmony_ci goto error; 49368c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40); 49378c2ecf20Sopenharmony_ci if (status < 0) 49388c2ecf20Sopenharmony_ci goto error; 49398c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60); 49408c2ecf20Sopenharmony_ci if (status < 0) 49418c2ecf20Sopenharmony_ci goto error; 49428c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 49438c2ecf20Sopenharmony_ci if (status < 0) 49448c2ecf20Sopenharmony_ci goto error; 49458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 49468c2ecf20Sopenharmony_ci if (status < 0) 49478c2ecf20Sopenharmony_ci goto error; 49488c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64); 49498c2ecf20Sopenharmony_ci if (status < 0) 49508c2ecf20Sopenharmony_ci goto error; 49518c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 49528c2ecf20Sopenharmony_ci if (status < 0) 49538c2ecf20Sopenharmony_ci goto error; 49548c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 49558c2ecf20Sopenharmony_ci if (status < 0) 49568c2ecf20Sopenharmony_ci goto error; 49578c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0); 49588c2ecf20Sopenharmony_ci if (status < 0) 49598c2ecf20Sopenharmony_ci goto error; 49608c2ecf20Sopenharmony_ci 49618c2ecf20Sopenharmony_ci 49628c2ecf20Sopenharmony_ci /* QAM State Machine (FSM) Thresholds */ 49638c2ecf20Sopenharmony_ci 49648c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 49658c2ecf20Sopenharmony_ci if (status < 0) 49668c2ecf20Sopenharmony_ci goto error; 49678c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 49688c2ecf20Sopenharmony_ci if (status < 0) 49698c2ecf20Sopenharmony_ci goto error; 49708c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 49718c2ecf20Sopenharmony_ci if (status < 0) 49728c2ecf20Sopenharmony_ci goto error; 49738c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 49748c2ecf20Sopenharmony_ci if (status < 0) 49758c2ecf20Sopenharmony_ci goto error; 49768c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140); 49778c2ecf20Sopenharmony_ci if (status < 0) 49788c2ecf20Sopenharmony_ci goto error; 49798c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100); 49808c2ecf20Sopenharmony_ci if (status < 0) 49818c2ecf20Sopenharmony_ci goto error; 49828c2ecf20Sopenharmony_ci 49838c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 49848c2ecf20Sopenharmony_ci if (status < 0) 49858c2ecf20Sopenharmony_ci goto error; 49868c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5); 49878c2ecf20Sopenharmony_ci if (status < 0) 49888c2ecf20Sopenharmony_ci goto error; 49898c2ecf20Sopenharmony_ci 49908c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 49918c2ecf20Sopenharmony_ci if (status < 0) 49928c2ecf20Sopenharmony_ci goto error; 49938c2ecf20Sopenharmony_ci 49948c2ecf20Sopenharmony_ci /* QAM FSM Tracking Parameters */ 49958c2ecf20Sopenharmony_ci 49968c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 49978c2ecf20Sopenharmony_ci if (status < 0) 49988c2ecf20Sopenharmony_ci goto error; 49998c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65); 50008c2ecf20Sopenharmony_ci if (status < 0) 50018c2ecf20Sopenharmony_ci goto error; 50028c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5); 50038c2ecf20Sopenharmony_ci if (status < 0) 50048c2ecf20Sopenharmony_ci goto error; 50058c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3); 50068c2ecf20Sopenharmony_ci if (status < 0) 50078c2ecf20Sopenharmony_ci goto error; 50088c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1); 50098c2ecf20Sopenharmony_ci if (status < 0) 50108c2ecf20Sopenharmony_ci goto error; 50118c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12); 50128c2ecf20Sopenharmony_ci if (status < 0) 50138c2ecf20Sopenharmony_ci goto error; 50148c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23); 50158c2ecf20Sopenharmony_cierror: 50168c2ecf20Sopenharmony_ci if (status < 0) 50178c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 50188c2ecf20Sopenharmony_ci 50198c2ecf20Sopenharmony_ci return status; 50208c2ecf20Sopenharmony_ci} 50218c2ecf20Sopenharmony_ci 50228c2ecf20Sopenharmony_ci/*============================================================================*/ 50238c2ecf20Sopenharmony_ci 50248c2ecf20Sopenharmony_ci/* 50258c2ecf20Sopenharmony_ci* \brief QAM256 specific setup 50268c2ecf20Sopenharmony_ci* \param demod: instance of demod. 50278c2ecf20Sopenharmony_ci* \return DRXStatus_t. 50288c2ecf20Sopenharmony_ci*/ 50298c2ecf20Sopenharmony_cistatic int set_qam256(struct drxk_state *state) 50308c2ecf20Sopenharmony_ci{ 50318c2ecf20Sopenharmony_ci int status = 0; 50328c2ecf20Sopenharmony_ci 50338c2ecf20Sopenharmony_ci dprintk(1, "\n"); 50348c2ecf20Sopenharmony_ci /* QAM Equalizer Setup */ 50358c2ecf20Sopenharmony_ci /* Equalizer */ 50368c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502); 50378c2ecf20Sopenharmony_ci if (status < 0) 50388c2ecf20Sopenharmony_ci goto error; 50398c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084); 50408c2ecf20Sopenharmony_ci if (status < 0) 50418c2ecf20Sopenharmony_ci goto error; 50428c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543); 50438c2ecf20Sopenharmony_ci if (status < 0) 50448c2ecf20Sopenharmony_ci goto error; 50458c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931); 50468c2ecf20Sopenharmony_ci if (status < 0) 50478c2ecf20Sopenharmony_ci goto error; 50488c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629); 50498c2ecf20Sopenharmony_ci if (status < 0) 50508c2ecf20Sopenharmony_ci goto error; 50518c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385); 50528c2ecf20Sopenharmony_ci if (status < 0) 50538c2ecf20Sopenharmony_ci goto error; 50548c2ecf20Sopenharmony_ci 50558c2ecf20Sopenharmony_ci /* Decision Feedback Equalizer */ 50568c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN0__A, 8); 50578c2ecf20Sopenharmony_ci if (status < 0) 50588c2ecf20Sopenharmony_ci goto error; 50598c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN1__A, 8); 50608c2ecf20Sopenharmony_ci if (status < 0) 50618c2ecf20Sopenharmony_ci goto error; 50628c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN2__A, 8); 50638c2ecf20Sopenharmony_ci if (status < 0) 50648c2ecf20Sopenharmony_ci goto error; 50658c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN3__A, 8); 50668c2ecf20Sopenharmony_ci if (status < 0) 50678c2ecf20Sopenharmony_ci goto error; 50688c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN4__A, 6); 50698c2ecf20Sopenharmony_ci if (status < 0) 50708c2ecf20Sopenharmony_ci goto error; 50718c2ecf20Sopenharmony_ci status = write16(state, QAM_DQ_QUAL_FUN5__A, 0); 50728c2ecf20Sopenharmony_ci if (status < 0) 50738c2ecf20Sopenharmony_ci goto error; 50748c2ecf20Sopenharmony_ci 50758c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_HWM__A, 5); 50768c2ecf20Sopenharmony_ci if (status < 0) 50778c2ecf20Sopenharmony_ci goto error; 50788c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_AWM__A, 4); 50798c2ecf20Sopenharmony_ci if (status < 0) 50808c2ecf20Sopenharmony_ci goto error; 50818c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SYNC_LWM__A, 3); 50828c2ecf20Sopenharmony_ci if (status < 0) 50838c2ecf20Sopenharmony_ci goto error; 50848c2ecf20Sopenharmony_ci 50858c2ecf20Sopenharmony_ci /* QAM Slicer Settings */ 50868c2ecf20Sopenharmony_ci 50878c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, 50888c2ecf20Sopenharmony_ci DRXK_QAM_SL_SIG_POWER_QAM256); 50898c2ecf20Sopenharmony_ci if (status < 0) 50908c2ecf20Sopenharmony_ci goto error; 50918c2ecf20Sopenharmony_ci 50928c2ecf20Sopenharmony_ci 50938c2ecf20Sopenharmony_ci /* QAM Loop Controller Coeficients */ 50948c2ecf20Sopenharmony_ci 50958c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15); 50968c2ecf20Sopenharmony_ci if (status < 0) 50978c2ecf20Sopenharmony_ci goto error; 50988c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40); 50998c2ecf20Sopenharmony_ci if (status < 0) 51008c2ecf20Sopenharmony_ci goto error; 51018c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12); 51028c2ecf20Sopenharmony_ci if (status < 0) 51038c2ecf20Sopenharmony_ci goto error; 51048c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24); 51058c2ecf20Sopenharmony_ci if (status < 0) 51068c2ecf20Sopenharmony_ci goto error; 51078c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24); 51088c2ecf20Sopenharmony_ci if (status < 0) 51098c2ecf20Sopenharmony_ci goto error; 51108c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12); 51118c2ecf20Sopenharmony_ci if (status < 0) 51128c2ecf20Sopenharmony_ci goto error; 51138c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16); 51148c2ecf20Sopenharmony_ci if (status < 0) 51158c2ecf20Sopenharmony_ci goto error; 51168c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16); 51178c2ecf20Sopenharmony_ci if (status < 0) 51188c2ecf20Sopenharmony_ci goto error; 51198c2ecf20Sopenharmony_ci 51208c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5); 51218c2ecf20Sopenharmony_ci if (status < 0) 51228c2ecf20Sopenharmony_ci goto error; 51238c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50); 51248c2ecf20Sopenharmony_ci if (status < 0) 51258c2ecf20Sopenharmony_ci goto error; 51268c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250); 51278c2ecf20Sopenharmony_ci if (status < 0) 51288c2ecf20Sopenharmony_ci goto error; 51298c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5); 51308c2ecf20Sopenharmony_ci if (status < 0) 51318c2ecf20Sopenharmony_ci goto error; 51328c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50); 51338c2ecf20Sopenharmony_ci if (status < 0) 51348c2ecf20Sopenharmony_ci goto error; 51358c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125); 51368c2ecf20Sopenharmony_ci if (status < 0) 51378c2ecf20Sopenharmony_ci goto error; 51388c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16); 51398c2ecf20Sopenharmony_ci if (status < 0) 51408c2ecf20Sopenharmony_ci goto error; 51418c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25); 51428c2ecf20Sopenharmony_ci if (status < 0) 51438c2ecf20Sopenharmony_ci goto error; 51448c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48); 51458c2ecf20Sopenharmony_ci if (status < 0) 51468c2ecf20Sopenharmony_ci goto error; 51478c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5); 51488c2ecf20Sopenharmony_ci if (status < 0) 51498c2ecf20Sopenharmony_ci goto error; 51508c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10); 51518c2ecf20Sopenharmony_ci if (status < 0) 51528c2ecf20Sopenharmony_ci goto error; 51538c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10); 51548c2ecf20Sopenharmony_ci if (status < 0) 51558c2ecf20Sopenharmony_ci goto error; 51568c2ecf20Sopenharmony_ci 51578c2ecf20Sopenharmony_ci 51588c2ecf20Sopenharmony_ci /* QAM State Machine (FSM) Thresholds */ 51598c2ecf20Sopenharmony_ci 51608c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50); 51618c2ecf20Sopenharmony_ci if (status < 0) 51628c2ecf20Sopenharmony_ci goto error; 51638c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60); 51648c2ecf20Sopenharmony_ci if (status < 0) 51658c2ecf20Sopenharmony_ci goto error; 51668c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80); 51678c2ecf20Sopenharmony_ci if (status < 0) 51688c2ecf20Sopenharmony_ci goto error; 51698c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100); 51708c2ecf20Sopenharmony_ci if (status < 0) 51718c2ecf20Sopenharmony_ci goto error; 51728c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150); 51738c2ecf20Sopenharmony_ci if (status < 0) 51748c2ecf20Sopenharmony_ci goto error; 51758c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110); 51768c2ecf20Sopenharmony_ci if (status < 0) 51778c2ecf20Sopenharmony_ci goto error; 51788c2ecf20Sopenharmony_ci 51798c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40); 51808c2ecf20Sopenharmony_ci if (status < 0) 51818c2ecf20Sopenharmony_ci goto error; 51828c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4); 51838c2ecf20Sopenharmony_ci if (status < 0) 51848c2ecf20Sopenharmony_ci goto error; 51858c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12); 51868c2ecf20Sopenharmony_ci if (status < 0) 51878c2ecf20Sopenharmony_ci goto error; 51888c2ecf20Sopenharmony_ci 51898c2ecf20Sopenharmony_ci 51908c2ecf20Sopenharmony_ci /* QAM FSM Tracking Parameters */ 51918c2ecf20Sopenharmony_ci 51928c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8); 51938c2ecf20Sopenharmony_ci if (status < 0) 51948c2ecf20Sopenharmony_ci goto error; 51958c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74); 51968c2ecf20Sopenharmony_ci if (status < 0) 51978c2ecf20Sopenharmony_ci goto error; 51988c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18); 51998c2ecf20Sopenharmony_ci if (status < 0) 52008c2ecf20Sopenharmony_ci goto error; 52018c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13); 52028c2ecf20Sopenharmony_ci if (status < 0) 52038c2ecf20Sopenharmony_ci goto error; 52048c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7); 52058c2ecf20Sopenharmony_ci if (status < 0) 52068c2ecf20Sopenharmony_ci goto error; 52078c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0); 52088c2ecf20Sopenharmony_ci if (status < 0) 52098c2ecf20Sopenharmony_ci goto error; 52108c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8); 52118c2ecf20Sopenharmony_cierror: 52128c2ecf20Sopenharmony_ci if (status < 0) 52138c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 52148c2ecf20Sopenharmony_ci return status; 52158c2ecf20Sopenharmony_ci} 52168c2ecf20Sopenharmony_ci 52178c2ecf20Sopenharmony_ci 52188c2ecf20Sopenharmony_ci/*============================================================================*/ 52198c2ecf20Sopenharmony_ci/* 52208c2ecf20Sopenharmony_ci* \brief Reset QAM block. 52218c2ecf20Sopenharmony_ci* \param demod: instance of demod. 52228c2ecf20Sopenharmony_ci* \param channel: pointer to channel data. 52238c2ecf20Sopenharmony_ci* \return DRXStatus_t. 52248c2ecf20Sopenharmony_ci*/ 52258c2ecf20Sopenharmony_cistatic int qam_reset_qam(struct drxk_state *state) 52268c2ecf20Sopenharmony_ci{ 52278c2ecf20Sopenharmony_ci int status; 52288c2ecf20Sopenharmony_ci u16 cmd_result; 52298c2ecf20Sopenharmony_ci 52308c2ecf20Sopenharmony_ci dprintk(1, "\n"); 52318c2ecf20Sopenharmony_ci /* Stop QAM comstate->m_exec */ 52328c2ecf20Sopenharmony_ci status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); 52338c2ecf20Sopenharmony_ci if (status < 0) 52348c2ecf20Sopenharmony_ci goto error; 52358c2ecf20Sopenharmony_ci 52368c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 52378c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 52388c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 52398c2ecf20Sopenharmony_cierror: 52408c2ecf20Sopenharmony_ci if (status < 0) 52418c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 52428c2ecf20Sopenharmony_ci return status; 52438c2ecf20Sopenharmony_ci} 52448c2ecf20Sopenharmony_ci 52458c2ecf20Sopenharmony_ci/*============================================================================*/ 52468c2ecf20Sopenharmony_ci 52478c2ecf20Sopenharmony_ci/* 52488c2ecf20Sopenharmony_ci* \brief Set QAM symbolrate. 52498c2ecf20Sopenharmony_ci* \param demod: instance of demod. 52508c2ecf20Sopenharmony_ci* \param channel: pointer to channel data. 52518c2ecf20Sopenharmony_ci* \return DRXStatus_t. 52528c2ecf20Sopenharmony_ci*/ 52538c2ecf20Sopenharmony_cistatic int qam_set_symbolrate(struct drxk_state *state) 52548c2ecf20Sopenharmony_ci{ 52558c2ecf20Sopenharmony_ci u32 adc_frequency = 0; 52568c2ecf20Sopenharmony_ci u32 symb_freq = 0; 52578c2ecf20Sopenharmony_ci u32 iqm_rc_rate = 0; 52588c2ecf20Sopenharmony_ci u16 ratesel = 0; 52598c2ecf20Sopenharmony_ci u32 lc_symb_rate = 0; 52608c2ecf20Sopenharmony_ci int status; 52618c2ecf20Sopenharmony_ci 52628c2ecf20Sopenharmony_ci dprintk(1, "\n"); 52638c2ecf20Sopenharmony_ci /* Select & calculate correct IQM rate */ 52648c2ecf20Sopenharmony_ci adc_frequency = (state->m_sys_clock_freq * 1000) / 3; 52658c2ecf20Sopenharmony_ci ratesel = 0; 52668c2ecf20Sopenharmony_ci if (state->props.symbol_rate <= 1188750) 52678c2ecf20Sopenharmony_ci ratesel = 3; 52688c2ecf20Sopenharmony_ci else if (state->props.symbol_rate <= 2377500) 52698c2ecf20Sopenharmony_ci ratesel = 2; 52708c2ecf20Sopenharmony_ci else if (state->props.symbol_rate <= 4755000) 52718c2ecf20Sopenharmony_ci ratesel = 1; 52728c2ecf20Sopenharmony_ci status = write16(state, IQM_FD_RATESEL__A, ratesel); 52738c2ecf20Sopenharmony_ci if (status < 0) 52748c2ecf20Sopenharmony_ci goto error; 52758c2ecf20Sopenharmony_ci 52768c2ecf20Sopenharmony_ci /* 52778c2ecf20Sopenharmony_ci IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23) 52788c2ecf20Sopenharmony_ci */ 52798c2ecf20Sopenharmony_ci symb_freq = state->props.symbol_rate * (1 << ratesel); 52808c2ecf20Sopenharmony_ci if (symb_freq == 0) { 52818c2ecf20Sopenharmony_ci /* Divide by zero */ 52828c2ecf20Sopenharmony_ci status = -EINVAL; 52838c2ecf20Sopenharmony_ci goto error; 52848c2ecf20Sopenharmony_ci } 52858c2ecf20Sopenharmony_ci iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) + 52868c2ecf20Sopenharmony_ci (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) - 52878c2ecf20Sopenharmony_ci (1 << 23); 52888c2ecf20Sopenharmony_ci status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate); 52898c2ecf20Sopenharmony_ci if (status < 0) 52908c2ecf20Sopenharmony_ci goto error; 52918c2ecf20Sopenharmony_ci state->m_iqm_rc_rate = iqm_rc_rate; 52928c2ecf20Sopenharmony_ci /* 52938c2ecf20Sopenharmony_ci LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15)) 52948c2ecf20Sopenharmony_ci */ 52958c2ecf20Sopenharmony_ci symb_freq = state->props.symbol_rate; 52968c2ecf20Sopenharmony_ci if (adc_frequency == 0) { 52978c2ecf20Sopenharmony_ci /* Divide by zero */ 52988c2ecf20Sopenharmony_ci status = -EINVAL; 52998c2ecf20Sopenharmony_ci goto error; 53008c2ecf20Sopenharmony_ci } 53018c2ecf20Sopenharmony_ci lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) + 53028c2ecf20Sopenharmony_ci (Frac28a((symb_freq % adc_frequency), adc_frequency) >> 53038c2ecf20Sopenharmony_ci 16); 53048c2ecf20Sopenharmony_ci if (lc_symb_rate > 511) 53058c2ecf20Sopenharmony_ci lc_symb_rate = 511; 53068c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate); 53078c2ecf20Sopenharmony_ci 53088c2ecf20Sopenharmony_cierror: 53098c2ecf20Sopenharmony_ci if (status < 0) 53108c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 53118c2ecf20Sopenharmony_ci return status; 53128c2ecf20Sopenharmony_ci} 53138c2ecf20Sopenharmony_ci 53148c2ecf20Sopenharmony_ci/*============================================================================*/ 53158c2ecf20Sopenharmony_ci 53168c2ecf20Sopenharmony_ci/* 53178c2ecf20Sopenharmony_ci* \brief Get QAM lock status. 53188c2ecf20Sopenharmony_ci* \param demod: instance of demod. 53198c2ecf20Sopenharmony_ci* \param channel: pointer to channel data. 53208c2ecf20Sopenharmony_ci* \return DRXStatus_t. 53218c2ecf20Sopenharmony_ci*/ 53228c2ecf20Sopenharmony_ci 53238c2ecf20Sopenharmony_cistatic int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) 53248c2ecf20Sopenharmony_ci{ 53258c2ecf20Sopenharmony_ci int status; 53268c2ecf20Sopenharmony_ci u16 result[2] = { 0, 0 }; 53278c2ecf20Sopenharmony_ci 53288c2ecf20Sopenharmony_ci dprintk(1, "\n"); 53298c2ecf20Sopenharmony_ci *p_lock_status = NOT_LOCKED; 53308c2ecf20Sopenharmony_ci status = scu_command(state, 53318c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_QAM | 53328c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, 53338c2ecf20Sopenharmony_ci result); 53348c2ecf20Sopenharmony_ci if (status < 0) 53358c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 53368c2ecf20Sopenharmony_ci 53378c2ecf20Sopenharmony_ci if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { 53388c2ecf20Sopenharmony_ci /* 0x0000 NOT LOCKED */ 53398c2ecf20Sopenharmony_ci } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { 53408c2ecf20Sopenharmony_ci /* 0x4000 DEMOD LOCKED */ 53418c2ecf20Sopenharmony_ci *p_lock_status = DEMOD_LOCK; 53428c2ecf20Sopenharmony_ci } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { 53438c2ecf20Sopenharmony_ci /* 0x8000 DEMOD + FEC LOCKED (system lock) */ 53448c2ecf20Sopenharmony_ci *p_lock_status = MPEG_LOCK; 53458c2ecf20Sopenharmony_ci } else { 53468c2ecf20Sopenharmony_ci /* 0xC000 NEVER LOCKED */ 53478c2ecf20Sopenharmony_ci /* (system will never be able to lock to the signal) */ 53488c2ecf20Sopenharmony_ci /* 53498c2ecf20Sopenharmony_ci * TODO: check this, intermediate & standard specific lock 53508c2ecf20Sopenharmony_ci * states are not taken into account here 53518c2ecf20Sopenharmony_ci */ 53528c2ecf20Sopenharmony_ci *p_lock_status = NEVER_LOCK; 53538c2ecf20Sopenharmony_ci } 53548c2ecf20Sopenharmony_ci return status; 53558c2ecf20Sopenharmony_ci} 53568c2ecf20Sopenharmony_ci 53578c2ecf20Sopenharmony_ci#define QAM_MIRROR__M 0x03 53588c2ecf20Sopenharmony_ci#define QAM_MIRROR_NORMAL 0x00 53598c2ecf20Sopenharmony_ci#define QAM_MIRRORED 0x01 53608c2ecf20Sopenharmony_ci#define QAM_MIRROR_AUTO_ON 0x02 53618c2ecf20Sopenharmony_ci#define QAM_LOCKRANGE__M 0x10 53628c2ecf20Sopenharmony_ci#define QAM_LOCKRANGE_NORMAL 0x10 53638c2ecf20Sopenharmony_ci 53648c2ecf20Sopenharmony_cistatic int qam_demodulator_command(struct drxk_state *state, 53658c2ecf20Sopenharmony_ci int number_of_parameters) 53668c2ecf20Sopenharmony_ci{ 53678c2ecf20Sopenharmony_ci int status; 53688c2ecf20Sopenharmony_ci u16 cmd_result; 53698c2ecf20Sopenharmony_ci u16 set_param_parameters[4] = { 0, 0, 0, 0 }; 53708c2ecf20Sopenharmony_ci 53718c2ecf20Sopenharmony_ci set_param_parameters[0] = state->m_constellation; /* modulation */ 53728c2ecf20Sopenharmony_ci set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ 53738c2ecf20Sopenharmony_ci 53748c2ecf20Sopenharmony_ci if (number_of_parameters == 2) { 53758c2ecf20Sopenharmony_ci u16 set_env_parameters[1] = { 0 }; 53768c2ecf20Sopenharmony_ci 53778c2ecf20Sopenharmony_ci if (state->m_operation_mode == OM_QAM_ITU_C) 53788c2ecf20Sopenharmony_ci set_env_parameters[0] = QAM_TOP_ANNEX_C; 53798c2ecf20Sopenharmony_ci else 53808c2ecf20Sopenharmony_ci set_env_parameters[0] = QAM_TOP_ANNEX_A; 53818c2ecf20Sopenharmony_ci 53828c2ecf20Sopenharmony_ci status = scu_command(state, 53838c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_QAM 53848c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 53858c2ecf20Sopenharmony_ci 1, set_env_parameters, 1, &cmd_result); 53868c2ecf20Sopenharmony_ci if (status < 0) 53878c2ecf20Sopenharmony_ci goto error; 53888c2ecf20Sopenharmony_ci 53898c2ecf20Sopenharmony_ci status = scu_command(state, 53908c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_QAM 53918c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 53928c2ecf20Sopenharmony_ci number_of_parameters, set_param_parameters, 53938c2ecf20Sopenharmony_ci 1, &cmd_result); 53948c2ecf20Sopenharmony_ci } else if (number_of_parameters == 4) { 53958c2ecf20Sopenharmony_ci if (state->m_operation_mode == OM_QAM_ITU_C) 53968c2ecf20Sopenharmony_ci set_param_parameters[2] = QAM_TOP_ANNEX_C; 53978c2ecf20Sopenharmony_ci else 53988c2ecf20Sopenharmony_ci set_param_parameters[2] = QAM_TOP_ANNEX_A; 53998c2ecf20Sopenharmony_ci 54008c2ecf20Sopenharmony_ci set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON); 54018c2ecf20Sopenharmony_ci /* Env parameters */ 54028c2ecf20Sopenharmony_ci /* check for LOCKRANGE Extended */ 54038c2ecf20Sopenharmony_ci /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */ 54048c2ecf20Sopenharmony_ci 54058c2ecf20Sopenharmony_ci status = scu_command(state, 54068c2ecf20Sopenharmony_ci SCU_RAM_COMMAND_STANDARD_QAM 54078c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 54088c2ecf20Sopenharmony_ci number_of_parameters, set_param_parameters, 54098c2ecf20Sopenharmony_ci 1, &cmd_result); 54108c2ecf20Sopenharmony_ci } else { 54118c2ecf20Sopenharmony_ci pr_warn("Unknown QAM demodulator parameter count %d\n", 54128c2ecf20Sopenharmony_ci number_of_parameters); 54138c2ecf20Sopenharmony_ci status = -EINVAL; 54148c2ecf20Sopenharmony_ci } 54158c2ecf20Sopenharmony_ci 54168c2ecf20Sopenharmony_cierror: 54178c2ecf20Sopenharmony_ci if (status < 0) 54188c2ecf20Sopenharmony_ci pr_warn("Warning %d on %s\n", status, __func__); 54198c2ecf20Sopenharmony_ci return status; 54208c2ecf20Sopenharmony_ci} 54218c2ecf20Sopenharmony_ci 54228c2ecf20Sopenharmony_cistatic int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, 54238c2ecf20Sopenharmony_ci s32 tuner_freq_offset) 54248c2ecf20Sopenharmony_ci{ 54258c2ecf20Sopenharmony_ci int status; 54268c2ecf20Sopenharmony_ci u16 cmd_result; 54278c2ecf20Sopenharmony_ci int qam_demod_param_count = state->qam_demod_parameter_count; 54288c2ecf20Sopenharmony_ci 54298c2ecf20Sopenharmony_ci dprintk(1, "\n"); 54308c2ecf20Sopenharmony_ci /* 54318c2ecf20Sopenharmony_ci * STEP 1: reset demodulator 54328c2ecf20Sopenharmony_ci * resets FEC DI and FEC RS 54338c2ecf20Sopenharmony_ci * resets QAM block 54348c2ecf20Sopenharmony_ci * resets SCU variables 54358c2ecf20Sopenharmony_ci */ 54368c2ecf20Sopenharmony_ci status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP); 54378c2ecf20Sopenharmony_ci if (status < 0) 54388c2ecf20Sopenharmony_ci goto error; 54398c2ecf20Sopenharmony_ci status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP); 54408c2ecf20Sopenharmony_ci if (status < 0) 54418c2ecf20Sopenharmony_ci goto error; 54428c2ecf20Sopenharmony_ci status = qam_reset_qam(state); 54438c2ecf20Sopenharmony_ci if (status < 0) 54448c2ecf20Sopenharmony_ci goto error; 54458c2ecf20Sopenharmony_ci 54468c2ecf20Sopenharmony_ci /* 54478c2ecf20Sopenharmony_ci * STEP 2: configure demodulator 54488c2ecf20Sopenharmony_ci * -set params; resets IQM,QAM,FEC HW; initializes some 54498c2ecf20Sopenharmony_ci * SCU variables 54508c2ecf20Sopenharmony_ci */ 54518c2ecf20Sopenharmony_ci status = qam_set_symbolrate(state); 54528c2ecf20Sopenharmony_ci if (status < 0) 54538c2ecf20Sopenharmony_ci goto error; 54548c2ecf20Sopenharmony_ci 54558c2ecf20Sopenharmony_ci /* Set params */ 54568c2ecf20Sopenharmony_ci switch (state->props.modulation) { 54578c2ecf20Sopenharmony_ci case QAM_256: 54588c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_QAM256; 54598c2ecf20Sopenharmony_ci break; 54608c2ecf20Sopenharmony_ci case QAM_AUTO: 54618c2ecf20Sopenharmony_ci case QAM_64: 54628c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_QAM64; 54638c2ecf20Sopenharmony_ci break; 54648c2ecf20Sopenharmony_ci case QAM_16: 54658c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_QAM16; 54668c2ecf20Sopenharmony_ci break; 54678c2ecf20Sopenharmony_ci case QAM_32: 54688c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_QAM32; 54698c2ecf20Sopenharmony_ci break; 54708c2ecf20Sopenharmony_ci case QAM_128: 54718c2ecf20Sopenharmony_ci state->m_constellation = DRX_CONSTELLATION_QAM128; 54728c2ecf20Sopenharmony_ci break; 54738c2ecf20Sopenharmony_ci default: 54748c2ecf20Sopenharmony_ci status = -EINVAL; 54758c2ecf20Sopenharmony_ci break; 54768c2ecf20Sopenharmony_ci } 54778c2ecf20Sopenharmony_ci if (status < 0) 54788c2ecf20Sopenharmony_ci goto error; 54798c2ecf20Sopenharmony_ci 54808c2ecf20Sopenharmony_ci /* Use the 4-parameter if it's requested or we're probing for 54818c2ecf20Sopenharmony_ci * the correct command. */ 54828c2ecf20Sopenharmony_ci if (state->qam_demod_parameter_count == 4 54838c2ecf20Sopenharmony_ci || !state->qam_demod_parameter_count) { 54848c2ecf20Sopenharmony_ci qam_demod_param_count = 4; 54858c2ecf20Sopenharmony_ci status = qam_demodulator_command(state, qam_demod_param_count); 54868c2ecf20Sopenharmony_ci } 54878c2ecf20Sopenharmony_ci 54888c2ecf20Sopenharmony_ci /* Use the 2-parameter command if it was requested or if we're 54898c2ecf20Sopenharmony_ci * probing for the correct command and the 4-parameter command 54908c2ecf20Sopenharmony_ci * failed. */ 54918c2ecf20Sopenharmony_ci if (state->qam_demod_parameter_count == 2 54928c2ecf20Sopenharmony_ci || (!state->qam_demod_parameter_count && status < 0)) { 54938c2ecf20Sopenharmony_ci qam_demod_param_count = 2; 54948c2ecf20Sopenharmony_ci status = qam_demodulator_command(state, qam_demod_param_count); 54958c2ecf20Sopenharmony_ci } 54968c2ecf20Sopenharmony_ci 54978c2ecf20Sopenharmony_ci if (status < 0) { 54988c2ecf20Sopenharmony_ci dprintk(1, "Could not set demodulator parameters.\n"); 54998c2ecf20Sopenharmony_ci dprintk(1, 55008c2ecf20Sopenharmony_ci "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n", 55018c2ecf20Sopenharmony_ci state->qam_demod_parameter_count, 55028c2ecf20Sopenharmony_ci state->microcode_name); 55038c2ecf20Sopenharmony_ci goto error; 55048c2ecf20Sopenharmony_ci } else if (!state->qam_demod_parameter_count) { 55058c2ecf20Sopenharmony_ci dprintk(1, 55068c2ecf20Sopenharmony_ci "Auto-probing the QAM command parameters was successful - using %d parameters.\n", 55078c2ecf20Sopenharmony_ci qam_demod_param_count); 55088c2ecf20Sopenharmony_ci 55098c2ecf20Sopenharmony_ci /* 55108c2ecf20Sopenharmony_ci * One of our commands was successful. We don't need to 55118c2ecf20Sopenharmony_ci * auto-probe anymore, now that we got the correct command. 55128c2ecf20Sopenharmony_ci */ 55138c2ecf20Sopenharmony_ci state->qam_demod_parameter_count = qam_demod_param_count; 55148c2ecf20Sopenharmony_ci } 55158c2ecf20Sopenharmony_ci 55168c2ecf20Sopenharmony_ci /* 55178c2ecf20Sopenharmony_ci * STEP 3: enable the system in a mode where the ADC provides valid 55188c2ecf20Sopenharmony_ci * signal setup modulation independent registers 55198c2ecf20Sopenharmony_ci */ 55208c2ecf20Sopenharmony_ci#if 0 55218c2ecf20Sopenharmony_ci status = set_frequency(channel, tuner_freq_offset)); 55228c2ecf20Sopenharmony_ci if (status < 0) 55238c2ecf20Sopenharmony_ci goto error; 55248c2ecf20Sopenharmony_ci#endif 55258c2ecf20Sopenharmony_ci status = set_frequency_shifter(state, intermediate_freqk_hz, 55268c2ecf20Sopenharmony_ci tuner_freq_offset, true); 55278c2ecf20Sopenharmony_ci if (status < 0) 55288c2ecf20Sopenharmony_ci goto error; 55298c2ecf20Sopenharmony_ci 55308c2ecf20Sopenharmony_ci /* Setup BER measurement */ 55318c2ecf20Sopenharmony_ci status = set_qam_measurement(state, state->m_constellation, 55328c2ecf20Sopenharmony_ci state->props.symbol_rate); 55338c2ecf20Sopenharmony_ci if (status < 0) 55348c2ecf20Sopenharmony_ci goto error; 55358c2ecf20Sopenharmony_ci 55368c2ecf20Sopenharmony_ci /* Reset default values */ 55378c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); 55388c2ecf20Sopenharmony_ci if (status < 0) 55398c2ecf20Sopenharmony_ci goto error; 55408c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); 55418c2ecf20Sopenharmony_ci if (status < 0) 55428c2ecf20Sopenharmony_ci goto error; 55438c2ecf20Sopenharmony_ci 55448c2ecf20Sopenharmony_ci /* Reset default LC values */ 55458c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_RATE_LIMIT__A, 3); 55468c2ecf20Sopenharmony_ci if (status < 0) 55478c2ecf20Sopenharmony_ci goto error; 55488c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_LPF_FACTORP__A, 4); 55498c2ecf20Sopenharmony_ci if (status < 0) 55508c2ecf20Sopenharmony_ci goto error; 55518c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_LPF_FACTORI__A, 4); 55528c2ecf20Sopenharmony_ci if (status < 0) 55538c2ecf20Sopenharmony_ci goto error; 55548c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_MODE__A, 7); 55558c2ecf20Sopenharmony_ci if (status < 0) 55568c2ecf20Sopenharmony_ci goto error; 55578c2ecf20Sopenharmony_ci 55588c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB0__A, 1); 55598c2ecf20Sopenharmony_ci if (status < 0) 55608c2ecf20Sopenharmony_ci goto error; 55618c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB1__A, 1); 55628c2ecf20Sopenharmony_ci if (status < 0) 55638c2ecf20Sopenharmony_ci goto error; 55648c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB2__A, 1); 55658c2ecf20Sopenharmony_ci if (status < 0) 55668c2ecf20Sopenharmony_ci goto error; 55678c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB3__A, 1); 55688c2ecf20Sopenharmony_ci if (status < 0) 55698c2ecf20Sopenharmony_ci goto error; 55708c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB4__A, 2); 55718c2ecf20Sopenharmony_ci if (status < 0) 55728c2ecf20Sopenharmony_ci goto error; 55738c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB5__A, 2); 55748c2ecf20Sopenharmony_ci if (status < 0) 55758c2ecf20Sopenharmony_ci goto error; 55768c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB6__A, 2); 55778c2ecf20Sopenharmony_ci if (status < 0) 55788c2ecf20Sopenharmony_ci goto error; 55798c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB8__A, 2); 55808c2ecf20Sopenharmony_ci if (status < 0) 55818c2ecf20Sopenharmony_ci goto error; 55828c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB9__A, 2); 55838c2ecf20Sopenharmony_ci if (status < 0) 55848c2ecf20Sopenharmony_ci goto error; 55858c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB10__A, 2); 55868c2ecf20Sopenharmony_ci if (status < 0) 55878c2ecf20Sopenharmony_ci goto error; 55888c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB12__A, 2); 55898c2ecf20Sopenharmony_ci if (status < 0) 55908c2ecf20Sopenharmony_ci goto error; 55918c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB15__A, 3); 55928c2ecf20Sopenharmony_ci if (status < 0) 55938c2ecf20Sopenharmony_ci goto error; 55948c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB16__A, 3); 55958c2ecf20Sopenharmony_ci if (status < 0) 55968c2ecf20Sopenharmony_ci goto error; 55978c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB20__A, 4); 55988c2ecf20Sopenharmony_ci if (status < 0) 55998c2ecf20Sopenharmony_ci goto error; 56008c2ecf20Sopenharmony_ci status = write16(state, QAM_LC_QUAL_TAB25__A, 4); 56018c2ecf20Sopenharmony_ci if (status < 0) 56028c2ecf20Sopenharmony_ci goto error; 56038c2ecf20Sopenharmony_ci 56048c2ecf20Sopenharmony_ci /* Mirroring, QAM-block starting point not inverted */ 56058c2ecf20Sopenharmony_ci status = write16(state, QAM_SY_SP_INV__A, 56068c2ecf20Sopenharmony_ci QAM_SY_SP_INV_SPECTRUM_INV_DIS); 56078c2ecf20Sopenharmony_ci if (status < 0) 56088c2ecf20Sopenharmony_ci goto error; 56098c2ecf20Sopenharmony_ci 56108c2ecf20Sopenharmony_ci /* Halt SCU to enable safe non-atomic accesses */ 56118c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 56128c2ecf20Sopenharmony_ci if (status < 0) 56138c2ecf20Sopenharmony_ci goto error; 56148c2ecf20Sopenharmony_ci 56158c2ecf20Sopenharmony_ci /* STEP 4: modulation specific setup */ 56168c2ecf20Sopenharmony_ci switch (state->props.modulation) { 56178c2ecf20Sopenharmony_ci case QAM_16: 56188c2ecf20Sopenharmony_ci status = set_qam16(state); 56198c2ecf20Sopenharmony_ci break; 56208c2ecf20Sopenharmony_ci case QAM_32: 56218c2ecf20Sopenharmony_ci status = set_qam32(state); 56228c2ecf20Sopenharmony_ci break; 56238c2ecf20Sopenharmony_ci case QAM_AUTO: 56248c2ecf20Sopenharmony_ci case QAM_64: 56258c2ecf20Sopenharmony_ci status = set_qam64(state); 56268c2ecf20Sopenharmony_ci break; 56278c2ecf20Sopenharmony_ci case QAM_128: 56288c2ecf20Sopenharmony_ci status = set_qam128(state); 56298c2ecf20Sopenharmony_ci break; 56308c2ecf20Sopenharmony_ci case QAM_256: 56318c2ecf20Sopenharmony_ci status = set_qam256(state); 56328c2ecf20Sopenharmony_ci break; 56338c2ecf20Sopenharmony_ci default: 56348c2ecf20Sopenharmony_ci status = -EINVAL; 56358c2ecf20Sopenharmony_ci break; 56368c2ecf20Sopenharmony_ci } 56378c2ecf20Sopenharmony_ci if (status < 0) 56388c2ecf20Sopenharmony_ci goto error; 56398c2ecf20Sopenharmony_ci 56408c2ecf20Sopenharmony_ci /* Activate SCU to enable SCU commands */ 56418c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 56428c2ecf20Sopenharmony_ci if (status < 0) 56438c2ecf20Sopenharmony_ci goto error; 56448c2ecf20Sopenharmony_ci 56458c2ecf20Sopenharmony_ci /* Re-configure MPEG output, requires knowledge of channel bitrate */ 56468c2ecf20Sopenharmony_ci /* extAttr->currentChannel.modulation = channel->modulation; */ 56478c2ecf20Sopenharmony_ci /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ 56488c2ecf20Sopenharmony_ci status = mpegts_dto_setup(state, state->m_operation_mode); 56498c2ecf20Sopenharmony_ci if (status < 0) 56508c2ecf20Sopenharmony_ci goto error; 56518c2ecf20Sopenharmony_ci 56528c2ecf20Sopenharmony_ci /* start processes */ 56538c2ecf20Sopenharmony_ci status = mpegts_start(state); 56548c2ecf20Sopenharmony_ci if (status < 0) 56558c2ecf20Sopenharmony_ci goto error; 56568c2ecf20Sopenharmony_ci status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); 56578c2ecf20Sopenharmony_ci if (status < 0) 56588c2ecf20Sopenharmony_ci goto error; 56598c2ecf20Sopenharmony_ci status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE); 56608c2ecf20Sopenharmony_ci if (status < 0) 56618c2ecf20Sopenharmony_ci goto error; 56628c2ecf20Sopenharmony_ci status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE); 56638c2ecf20Sopenharmony_ci if (status < 0) 56648c2ecf20Sopenharmony_ci goto error; 56658c2ecf20Sopenharmony_ci 56668c2ecf20Sopenharmony_ci /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */ 56678c2ecf20Sopenharmony_ci status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM 56688c2ecf20Sopenharmony_ci | SCU_RAM_COMMAND_CMD_DEMOD_START, 56698c2ecf20Sopenharmony_ci 0, NULL, 1, &cmd_result); 56708c2ecf20Sopenharmony_ci if (status < 0) 56718c2ecf20Sopenharmony_ci goto error; 56728c2ecf20Sopenharmony_ci 56738c2ecf20Sopenharmony_ci /* update global DRXK data container */ 56748c2ecf20Sopenharmony_ci/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */ 56758c2ecf20Sopenharmony_ci 56768c2ecf20Sopenharmony_cierror: 56778c2ecf20Sopenharmony_ci if (status < 0) 56788c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 56798c2ecf20Sopenharmony_ci return status; 56808c2ecf20Sopenharmony_ci} 56818c2ecf20Sopenharmony_ci 56828c2ecf20Sopenharmony_cistatic int set_qam_standard(struct drxk_state *state, 56838c2ecf20Sopenharmony_ci enum operation_mode o_mode) 56848c2ecf20Sopenharmony_ci{ 56858c2ecf20Sopenharmony_ci int status; 56868c2ecf20Sopenharmony_ci#ifdef DRXK_QAM_TAPS 56878c2ecf20Sopenharmony_ci#define DRXK_QAMA_TAPS_SELECT 56888c2ecf20Sopenharmony_ci#include "drxk_filters.h" 56898c2ecf20Sopenharmony_ci#undef DRXK_QAMA_TAPS_SELECT 56908c2ecf20Sopenharmony_ci#endif 56918c2ecf20Sopenharmony_ci 56928c2ecf20Sopenharmony_ci dprintk(1, "\n"); 56938c2ecf20Sopenharmony_ci 56948c2ecf20Sopenharmony_ci /* added antenna switch */ 56958c2ecf20Sopenharmony_ci switch_antenna_to_qam(state); 56968c2ecf20Sopenharmony_ci 56978c2ecf20Sopenharmony_ci /* Ensure correct power-up mode */ 56988c2ecf20Sopenharmony_ci status = power_up_qam(state); 56998c2ecf20Sopenharmony_ci if (status < 0) 57008c2ecf20Sopenharmony_ci goto error; 57018c2ecf20Sopenharmony_ci /* Reset QAM block */ 57028c2ecf20Sopenharmony_ci status = qam_reset_qam(state); 57038c2ecf20Sopenharmony_ci if (status < 0) 57048c2ecf20Sopenharmony_ci goto error; 57058c2ecf20Sopenharmony_ci 57068c2ecf20Sopenharmony_ci /* Setup IQM */ 57078c2ecf20Sopenharmony_ci 57088c2ecf20Sopenharmony_ci status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP); 57098c2ecf20Sopenharmony_ci if (status < 0) 57108c2ecf20Sopenharmony_ci goto error; 57118c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); 57128c2ecf20Sopenharmony_ci if (status < 0) 57138c2ecf20Sopenharmony_ci goto error; 57148c2ecf20Sopenharmony_ci 57158c2ecf20Sopenharmony_ci /* Upload IQM Channel Filter settings by 57168c2ecf20Sopenharmony_ci boot loader from ROM table */ 57178c2ecf20Sopenharmony_ci switch (o_mode) { 57188c2ecf20Sopenharmony_ci case OM_QAM_ITU_A: 57198c2ecf20Sopenharmony_ci status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, 57208c2ecf20Sopenharmony_ci DRXK_BLCC_NR_ELEMENTS_TAPS, 57218c2ecf20Sopenharmony_ci DRXK_BLC_TIMEOUT); 57228c2ecf20Sopenharmony_ci break; 57238c2ecf20Sopenharmony_ci case OM_QAM_ITU_C: 57248c2ecf20Sopenharmony_ci status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, 57258c2ecf20Sopenharmony_ci DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 57268c2ecf20Sopenharmony_ci DRXK_BLDC_NR_ELEMENTS_TAPS, 57278c2ecf20Sopenharmony_ci DRXK_BLC_TIMEOUT); 57288c2ecf20Sopenharmony_ci if (status < 0) 57298c2ecf20Sopenharmony_ci goto error; 57308c2ecf20Sopenharmony_ci status = bl_direct_cmd(state, 57318c2ecf20Sopenharmony_ci IQM_CF_TAP_IM0__A, 57328c2ecf20Sopenharmony_ci DRXK_BL_ROM_OFFSET_TAPS_ITU_C, 57338c2ecf20Sopenharmony_ci DRXK_BLDC_NR_ELEMENTS_TAPS, 57348c2ecf20Sopenharmony_ci DRXK_BLC_TIMEOUT); 57358c2ecf20Sopenharmony_ci break; 57368c2ecf20Sopenharmony_ci default: 57378c2ecf20Sopenharmony_ci status = -EINVAL; 57388c2ecf20Sopenharmony_ci } 57398c2ecf20Sopenharmony_ci if (status < 0) 57408c2ecf20Sopenharmony_ci goto error; 57418c2ecf20Sopenharmony_ci 57428c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B); 57438c2ecf20Sopenharmony_ci if (status < 0) 57448c2ecf20Sopenharmony_ci goto error; 57458c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_SYMMETRIC__A, 0); 57468c2ecf20Sopenharmony_ci if (status < 0) 57478c2ecf20Sopenharmony_ci goto error; 57488c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_MIDTAP__A, 57498c2ecf20Sopenharmony_ci ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); 57508c2ecf20Sopenharmony_ci if (status < 0) 57518c2ecf20Sopenharmony_ci goto error; 57528c2ecf20Sopenharmony_ci 57538c2ecf20Sopenharmony_ci status = write16(state, IQM_RC_STRETCH__A, 21); 57548c2ecf20Sopenharmony_ci if (status < 0) 57558c2ecf20Sopenharmony_ci goto error; 57568c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_CLP_LEN__A, 0); 57578c2ecf20Sopenharmony_ci if (status < 0) 57588c2ecf20Sopenharmony_ci goto error; 57598c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_CLP_TH__A, 448); 57608c2ecf20Sopenharmony_ci if (status < 0) 57618c2ecf20Sopenharmony_ci goto error; 57628c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_SNS_LEN__A, 0); 57638c2ecf20Sopenharmony_ci if (status < 0) 57648c2ecf20Sopenharmony_ci goto error; 57658c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0); 57668c2ecf20Sopenharmony_ci if (status < 0) 57678c2ecf20Sopenharmony_ci goto error; 57688c2ecf20Sopenharmony_ci 57698c2ecf20Sopenharmony_ci status = write16(state, IQM_FS_ADJ_SEL__A, 1); 57708c2ecf20Sopenharmony_ci if (status < 0) 57718c2ecf20Sopenharmony_ci goto error; 57728c2ecf20Sopenharmony_ci status = write16(state, IQM_RC_ADJ_SEL__A, 1); 57738c2ecf20Sopenharmony_ci if (status < 0) 57748c2ecf20Sopenharmony_ci goto error; 57758c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_ADJ_SEL__A, 1); 57768c2ecf20Sopenharmony_ci if (status < 0) 57778c2ecf20Sopenharmony_ci goto error; 57788c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_UPD_SEL__A, 0); 57798c2ecf20Sopenharmony_ci if (status < 0) 57808c2ecf20Sopenharmony_ci goto error; 57818c2ecf20Sopenharmony_ci 57828c2ecf20Sopenharmony_ci /* IQM Impulse Noise Processing Unit */ 57838c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_CLP_VAL__A, 500); 57848c2ecf20Sopenharmony_ci if (status < 0) 57858c2ecf20Sopenharmony_ci goto error; 57868c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_DATATH__A, 1000); 57878c2ecf20Sopenharmony_ci if (status < 0) 57888c2ecf20Sopenharmony_ci goto error; 57898c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_BYPASSDET__A, 1); 57908c2ecf20Sopenharmony_ci if (status < 0) 57918c2ecf20Sopenharmony_ci goto error; 57928c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_DET_LCT__A, 0); 57938c2ecf20Sopenharmony_ci if (status < 0) 57948c2ecf20Sopenharmony_ci goto error; 57958c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_WND_LEN__A, 1); 57968c2ecf20Sopenharmony_ci if (status < 0) 57978c2ecf20Sopenharmony_ci goto error; 57988c2ecf20Sopenharmony_ci status = write16(state, IQM_CF_PKDTH__A, 1); 57998c2ecf20Sopenharmony_ci if (status < 0) 58008c2ecf20Sopenharmony_ci goto error; 58018c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_INC_BYPASS__A, 1); 58028c2ecf20Sopenharmony_ci if (status < 0) 58038c2ecf20Sopenharmony_ci goto error; 58048c2ecf20Sopenharmony_ci 58058c2ecf20Sopenharmony_ci /* turn on IQMAF. Must be done before setAgc**() */ 58068c2ecf20Sopenharmony_ci status = set_iqm_af(state, true); 58078c2ecf20Sopenharmony_ci if (status < 0) 58088c2ecf20Sopenharmony_ci goto error; 58098c2ecf20Sopenharmony_ci status = write16(state, IQM_AF_START_LOCK__A, 0x01); 58108c2ecf20Sopenharmony_ci if (status < 0) 58118c2ecf20Sopenharmony_ci goto error; 58128c2ecf20Sopenharmony_ci 58138c2ecf20Sopenharmony_ci /* IQM will not be reset from here, sync ADC and update/init AGC */ 58148c2ecf20Sopenharmony_ci status = adc_synchronization(state); 58158c2ecf20Sopenharmony_ci if (status < 0) 58168c2ecf20Sopenharmony_ci goto error; 58178c2ecf20Sopenharmony_ci 58188c2ecf20Sopenharmony_ci /* Set the FSM step period */ 58198c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000); 58208c2ecf20Sopenharmony_ci if (status < 0) 58218c2ecf20Sopenharmony_ci goto error; 58228c2ecf20Sopenharmony_ci 58238c2ecf20Sopenharmony_ci /* Halt SCU to enable safe non-atomic accesses */ 58248c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD); 58258c2ecf20Sopenharmony_ci if (status < 0) 58268c2ecf20Sopenharmony_ci goto error; 58278c2ecf20Sopenharmony_ci 58288c2ecf20Sopenharmony_ci /* No more resets of the IQM, current standard correctly set => 58298c2ecf20Sopenharmony_ci now AGCs can be configured. */ 58308c2ecf20Sopenharmony_ci 58318c2ecf20Sopenharmony_ci status = init_agc(state, true); 58328c2ecf20Sopenharmony_ci if (status < 0) 58338c2ecf20Sopenharmony_ci goto error; 58348c2ecf20Sopenharmony_ci status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg)); 58358c2ecf20Sopenharmony_ci if (status < 0) 58368c2ecf20Sopenharmony_ci goto error; 58378c2ecf20Sopenharmony_ci 58388c2ecf20Sopenharmony_ci /* Configure AGC's */ 58398c2ecf20Sopenharmony_ci status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true); 58408c2ecf20Sopenharmony_ci if (status < 0) 58418c2ecf20Sopenharmony_ci goto error; 58428c2ecf20Sopenharmony_ci status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true); 58438c2ecf20Sopenharmony_ci if (status < 0) 58448c2ecf20Sopenharmony_ci goto error; 58458c2ecf20Sopenharmony_ci 58468c2ecf20Sopenharmony_ci /* Activate SCU to enable SCU commands */ 58478c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 58488c2ecf20Sopenharmony_cierror: 58498c2ecf20Sopenharmony_ci if (status < 0) 58508c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 58518c2ecf20Sopenharmony_ci return status; 58528c2ecf20Sopenharmony_ci} 58538c2ecf20Sopenharmony_ci 58548c2ecf20Sopenharmony_cistatic int write_gpio(struct drxk_state *state) 58558c2ecf20Sopenharmony_ci{ 58568c2ecf20Sopenharmony_ci int status; 58578c2ecf20Sopenharmony_ci u16 value = 0; 58588c2ecf20Sopenharmony_ci 58598c2ecf20Sopenharmony_ci dprintk(1, "\n"); 58608c2ecf20Sopenharmony_ci /* stop lock indicator process */ 58618c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 58628c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 58638c2ecf20Sopenharmony_ci if (status < 0) 58648c2ecf20Sopenharmony_ci goto error; 58658c2ecf20Sopenharmony_ci 58668c2ecf20Sopenharmony_ci /* Write magic word to enable pdr reg write */ 58678c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); 58688c2ecf20Sopenharmony_ci if (status < 0) 58698c2ecf20Sopenharmony_ci goto error; 58708c2ecf20Sopenharmony_ci 58718c2ecf20Sopenharmony_ci if (state->m_has_sawsw) { 58728c2ecf20Sopenharmony_ci if (state->uio_mask & 0x0001) { /* UIO-1 */ 58738c2ecf20Sopenharmony_ci /* write to io pad configuration register - output mode */ 58748c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_SMA_TX_CFG__A, 58758c2ecf20Sopenharmony_ci state->m_gpio_cfg); 58768c2ecf20Sopenharmony_ci if (status < 0) 58778c2ecf20Sopenharmony_ci goto error; 58788c2ecf20Sopenharmony_ci 58798c2ecf20Sopenharmony_ci /* use corresponding bit in io data output registar */ 58808c2ecf20Sopenharmony_ci status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 58818c2ecf20Sopenharmony_ci if (status < 0) 58828c2ecf20Sopenharmony_ci goto error; 58838c2ecf20Sopenharmony_ci if ((state->m_gpio & 0x0001) == 0) 58848c2ecf20Sopenharmony_ci value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ 58858c2ecf20Sopenharmony_ci else 58868c2ecf20Sopenharmony_ci value |= 0x8000; /* write one to 15th bit - 1st UIO */ 58878c2ecf20Sopenharmony_ci /* write back to io data output register */ 58888c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 58898c2ecf20Sopenharmony_ci if (status < 0) 58908c2ecf20Sopenharmony_ci goto error; 58918c2ecf20Sopenharmony_ci } 58928c2ecf20Sopenharmony_ci if (state->uio_mask & 0x0002) { /* UIO-2 */ 58938c2ecf20Sopenharmony_ci /* write to io pad configuration register - output mode */ 58948c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_SMA_RX_CFG__A, 58958c2ecf20Sopenharmony_ci state->m_gpio_cfg); 58968c2ecf20Sopenharmony_ci if (status < 0) 58978c2ecf20Sopenharmony_ci goto error; 58988c2ecf20Sopenharmony_ci 58998c2ecf20Sopenharmony_ci /* use corresponding bit in io data output registar */ 59008c2ecf20Sopenharmony_ci status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59018c2ecf20Sopenharmony_ci if (status < 0) 59028c2ecf20Sopenharmony_ci goto error; 59038c2ecf20Sopenharmony_ci if ((state->m_gpio & 0x0002) == 0) 59048c2ecf20Sopenharmony_ci value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ 59058c2ecf20Sopenharmony_ci else 59068c2ecf20Sopenharmony_ci value |= 0x4000; /* write one to 14th bit - 2st UIO */ 59078c2ecf20Sopenharmony_ci /* write back to io data output register */ 59088c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59098c2ecf20Sopenharmony_ci if (status < 0) 59108c2ecf20Sopenharmony_ci goto error; 59118c2ecf20Sopenharmony_ci } 59128c2ecf20Sopenharmony_ci if (state->uio_mask & 0x0004) { /* UIO-3 */ 59138c2ecf20Sopenharmony_ci /* write to io pad configuration register - output mode */ 59148c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_GPIO_CFG__A, 59158c2ecf20Sopenharmony_ci state->m_gpio_cfg); 59168c2ecf20Sopenharmony_ci if (status < 0) 59178c2ecf20Sopenharmony_ci goto error; 59188c2ecf20Sopenharmony_ci 59198c2ecf20Sopenharmony_ci /* use corresponding bit in io data output registar */ 59208c2ecf20Sopenharmony_ci status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 59218c2ecf20Sopenharmony_ci if (status < 0) 59228c2ecf20Sopenharmony_ci goto error; 59238c2ecf20Sopenharmony_ci if ((state->m_gpio & 0x0004) == 0) 59248c2ecf20Sopenharmony_ci value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ 59258c2ecf20Sopenharmony_ci else 59268c2ecf20Sopenharmony_ci value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ 59278c2ecf20Sopenharmony_ci /* write back to io data output register */ 59288c2ecf20Sopenharmony_ci status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 59298c2ecf20Sopenharmony_ci if (status < 0) 59308c2ecf20Sopenharmony_ci goto error; 59318c2ecf20Sopenharmony_ci } 59328c2ecf20Sopenharmony_ci } 59338c2ecf20Sopenharmony_ci /* Write magic word to disable pdr reg write */ 59348c2ecf20Sopenharmony_ci status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 59358c2ecf20Sopenharmony_cierror: 59368c2ecf20Sopenharmony_ci if (status < 0) 59378c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 59388c2ecf20Sopenharmony_ci return status; 59398c2ecf20Sopenharmony_ci} 59408c2ecf20Sopenharmony_ci 59418c2ecf20Sopenharmony_cistatic int switch_antenna_to_qam(struct drxk_state *state) 59428c2ecf20Sopenharmony_ci{ 59438c2ecf20Sopenharmony_ci int status = 0; 59448c2ecf20Sopenharmony_ci bool gpio_state; 59458c2ecf20Sopenharmony_ci 59468c2ecf20Sopenharmony_ci dprintk(1, "\n"); 59478c2ecf20Sopenharmony_ci 59488c2ecf20Sopenharmony_ci if (!state->antenna_gpio) 59498c2ecf20Sopenharmony_ci return 0; 59508c2ecf20Sopenharmony_ci 59518c2ecf20Sopenharmony_ci gpio_state = state->m_gpio & state->antenna_gpio; 59528c2ecf20Sopenharmony_ci 59538c2ecf20Sopenharmony_ci if (state->antenna_dvbt ^ gpio_state) { 59548c2ecf20Sopenharmony_ci /* Antenna is on DVB-T mode. Switch */ 59558c2ecf20Sopenharmony_ci if (state->antenna_dvbt) 59568c2ecf20Sopenharmony_ci state->m_gpio &= ~state->antenna_gpio; 59578c2ecf20Sopenharmony_ci else 59588c2ecf20Sopenharmony_ci state->m_gpio |= state->antenna_gpio; 59598c2ecf20Sopenharmony_ci status = write_gpio(state); 59608c2ecf20Sopenharmony_ci } 59618c2ecf20Sopenharmony_ci if (status < 0) 59628c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 59638c2ecf20Sopenharmony_ci return status; 59648c2ecf20Sopenharmony_ci} 59658c2ecf20Sopenharmony_ci 59668c2ecf20Sopenharmony_cistatic int switch_antenna_to_dvbt(struct drxk_state *state) 59678c2ecf20Sopenharmony_ci{ 59688c2ecf20Sopenharmony_ci int status = 0; 59698c2ecf20Sopenharmony_ci bool gpio_state; 59708c2ecf20Sopenharmony_ci 59718c2ecf20Sopenharmony_ci dprintk(1, "\n"); 59728c2ecf20Sopenharmony_ci 59738c2ecf20Sopenharmony_ci if (!state->antenna_gpio) 59748c2ecf20Sopenharmony_ci return 0; 59758c2ecf20Sopenharmony_ci 59768c2ecf20Sopenharmony_ci gpio_state = state->m_gpio & state->antenna_gpio; 59778c2ecf20Sopenharmony_ci 59788c2ecf20Sopenharmony_ci if (!(state->antenna_dvbt ^ gpio_state)) { 59798c2ecf20Sopenharmony_ci /* Antenna is on DVB-C mode. Switch */ 59808c2ecf20Sopenharmony_ci if (state->antenna_dvbt) 59818c2ecf20Sopenharmony_ci state->m_gpio |= state->antenna_gpio; 59828c2ecf20Sopenharmony_ci else 59838c2ecf20Sopenharmony_ci state->m_gpio &= ~state->antenna_gpio; 59848c2ecf20Sopenharmony_ci status = write_gpio(state); 59858c2ecf20Sopenharmony_ci } 59868c2ecf20Sopenharmony_ci if (status < 0) 59878c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 59888c2ecf20Sopenharmony_ci return status; 59898c2ecf20Sopenharmony_ci} 59908c2ecf20Sopenharmony_ci 59918c2ecf20Sopenharmony_ci 59928c2ecf20Sopenharmony_cistatic int power_down_device(struct drxk_state *state) 59938c2ecf20Sopenharmony_ci{ 59948c2ecf20Sopenharmony_ci /* Power down to requested mode */ 59958c2ecf20Sopenharmony_ci /* Backup some register settings */ 59968c2ecf20Sopenharmony_ci /* Set pins with possible pull-ups connected to them in input mode */ 59978c2ecf20Sopenharmony_ci /* Analog power down */ 59988c2ecf20Sopenharmony_ci /* ADC power down */ 59998c2ecf20Sopenharmony_ci /* Power down device */ 60008c2ecf20Sopenharmony_ci int status; 60018c2ecf20Sopenharmony_ci 60028c2ecf20Sopenharmony_ci dprintk(1, "\n"); 60038c2ecf20Sopenharmony_ci if (state->m_b_p_down_open_bridge) { 60048c2ecf20Sopenharmony_ci /* Open I2C bridge before power down of DRXK */ 60058c2ecf20Sopenharmony_ci status = ConfigureI2CBridge(state, true); 60068c2ecf20Sopenharmony_ci if (status < 0) 60078c2ecf20Sopenharmony_ci goto error; 60088c2ecf20Sopenharmony_ci } 60098c2ecf20Sopenharmony_ci /* driver 0.9.0 */ 60108c2ecf20Sopenharmony_ci status = dvbt_enable_ofdm_token_ring(state, false); 60118c2ecf20Sopenharmony_ci if (status < 0) 60128c2ecf20Sopenharmony_ci goto error; 60138c2ecf20Sopenharmony_ci 60148c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_PWD_MODE__A, 60158c2ecf20Sopenharmony_ci SIO_CC_PWD_MODE_LEVEL_CLOCK); 60168c2ecf20Sopenharmony_ci if (status < 0) 60178c2ecf20Sopenharmony_ci goto error; 60188c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60198c2ecf20Sopenharmony_ci if (status < 0) 60208c2ecf20Sopenharmony_ci goto error; 60218c2ecf20Sopenharmony_ci state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; 60228c2ecf20Sopenharmony_ci status = hi_cfg_command(state); 60238c2ecf20Sopenharmony_cierror: 60248c2ecf20Sopenharmony_ci if (status < 0) 60258c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 60268c2ecf20Sopenharmony_ci 60278c2ecf20Sopenharmony_ci return status; 60288c2ecf20Sopenharmony_ci} 60298c2ecf20Sopenharmony_ci 60308c2ecf20Sopenharmony_cistatic int init_drxk(struct drxk_state *state) 60318c2ecf20Sopenharmony_ci{ 60328c2ecf20Sopenharmony_ci int status = 0, n = 0; 60338c2ecf20Sopenharmony_ci enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; 60348c2ecf20Sopenharmony_ci u16 driver_version; 60358c2ecf20Sopenharmony_ci 60368c2ecf20Sopenharmony_ci dprintk(1, "\n"); 60378c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) { 60388c2ecf20Sopenharmony_ci drxk_i2c_lock(state); 60398c2ecf20Sopenharmony_ci status = power_up_device(state); 60408c2ecf20Sopenharmony_ci if (status < 0) 60418c2ecf20Sopenharmony_ci goto error; 60428c2ecf20Sopenharmony_ci status = drxx_open(state); 60438c2ecf20Sopenharmony_ci if (status < 0) 60448c2ecf20Sopenharmony_ci goto error; 60458c2ecf20Sopenharmony_ci /* Soft reset of OFDM-, sys- and osc-clockdomain */ 60468c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_SOFT_RST__A, 60478c2ecf20Sopenharmony_ci SIO_CC_SOFT_RST_OFDM__M 60488c2ecf20Sopenharmony_ci | SIO_CC_SOFT_RST_SYS__M 60498c2ecf20Sopenharmony_ci | SIO_CC_SOFT_RST_OSC__M); 60508c2ecf20Sopenharmony_ci if (status < 0) 60518c2ecf20Sopenharmony_ci goto error; 60528c2ecf20Sopenharmony_ci status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); 60538c2ecf20Sopenharmony_ci if (status < 0) 60548c2ecf20Sopenharmony_ci goto error; 60558c2ecf20Sopenharmony_ci /* 60568c2ecf20Sopenharmony_ci * TODO is this needed? If yes, how much delay in 60578c2ecf20Sopenharmony_ci * worst case scenario 60588c2ecf20Sopenharmony_ci */ 60598c2ecf20Sopenharmony_ci usleep_range(1000, 2000); 60608c2ecf20Sopenharmony_ci state->m_drxk_a3_patch_code = true; 60618c2ecf20Sopenharmony_ci status = get_device_capabilities(state); 60628c2ecf20Sopenharmony_ci if (status < 0) 60638c2ecf20Sopenharmony_ci goto error; 60648c2ecf20Sopenharmony_ci 60658c2ecf20Sopenharmony_ci /* Bridge delay, uses oscilator clock */ 60668c2ecf20Sopenharmony_ci /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */ 60678c2ecf20Sopenharmony_ci /* SDA brdige delay */ 60688c2ecf20Sopenharmony_ci state->m_hi_cfg_bridge_delay = 60698c2ecf20Sopenharmony_ci (u16) ((state->m_osc_clock_freq / 1000) * 60708c2ecf20Sopenharmony_ci HI_I2C_BRIDGE_DELAY) / 1000; 60718c2ecf20Sopenharmony_ci /* Clipping */ 60728c2ecf20Sopenharmony_ci if (state->m_hi_cfg_bridge_delay > 60738c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) { 60748c2ecf20Sopenharmony_ci state->m_hi_cfg_bridge_delay = 60758c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M; 60768c2ecf20Sopenharmony_ci } 60778c2ecf20Sopenharmony_ci /* SCL bridge delay, same as SDA for now */ 60788c2ecf20Sopenharmony_ci state->m_hi_cfg_bridge_delay += 60798c2ecf20Sopenharmony_ci state->m_hi_cfg_bridge_delay << 60808c2ecf20Sopenharmony_ci SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B; 60818c2ecf20Sopenharmony_ci 60828c2ecf20Sopenharmony_ci status = init_hi(state); 60838c2ecf20Sopenharmony_ci if (status < 0) 60848c2ecf20Sopenharmony_ci goto error; 60858c2ecf20Sopenharmony_ci /* disable various processes */ 60868c2ecf20Sopenharmony_ci#if NOA1ROM 60878c2ecf20Sopenharmony_ci if (!(state->m_DRXK_A1_ROM_CODE) 60888c2ecf20Sopenharmony_ci && !(state->m_DRXK_A2_ROM_CODE)) 60898c2ecf20Sopenharmony_ci#endif 60908c2ecf20Sopenharmony_ci { 60918c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_GPIO__A, 60928c2ecf20Sopenharmony_ci SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); 60938c2ecf20Sopenharmony_ci if (status < 0) 60948c2ecf20Sopenharmony_ci goto error; 60958c2ecf20Sopenharmony_ci } 60968c2ecf20Sopenharmony_ci 60978c2ecf20Sopenharmony_ci /* disable MPEG port */ 60988c2ecf20Sopenharmony_ci status = mpegts_disable(state); 60998c2ecf20Sopenharmony_ci if (status < 0) 61008c2ecf20Sopenharmony_ci goto error; 61018c2ecf20Sopenharmony_ci 61028c2ecf20Sopenharmony_ci /* Stop AUD and SCU */ 61038c2ecf20Sopenharmony_ci status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP); 61048c2ecf20Sopenharmony_ci if (status < 0) 61058c2ecf20Sopenharmony_ci goto error; 61068c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP); 61078c2ecf20Sopenharmony_ci if (status < 0) 61088c2ecf20Sopenharmony_ci goto error; 61098c2ecf20Sopenharmony_ci 61108c2ecf20Sopenharmony_ci /* enable token-ring bus through OFDM block for possible ucode upload */ 61118c2ecf20Sopenharmony_ci status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 61128c2ecf20Sopenharmony_ci SIO_OFDM_SH_OFDM_RING_ENABLE_ON); 61138c2ecf20Sopenharmony_ci if (status < 0) 61148c2ecf20Sopenharmony_ci goto error; 61158c2ecf20Sopenharmony_ci 61168c2ecf20Sopenharmony_ci /* include boot loader section */ 61178c2ecf20Sopenharmony_ci status = write16(state, SIO_BL_COMM_EXEC__A, 61188c2ecf20Sopenharmony_ci SIO_BL_COMM_EXEC_ACTIVE); 61198c2ecf20Sopenharmony_ci if (status < 0) 61208c2ecf20Sopenharmony_ci goto error; 61218c2ecf20Sopenharmony_ci status = bl_chain_cmd(state, 0, 6, 100); 61228c2ecf20Sopenharmony_ci if (status < 0) 61238c2ecf20Sopenharmony_ci goto error; 61248c2ecf20Sopenharmony_ci 61258c2ecf20Sopenharmony_ci if (state->fw) { 61268c2ecf20Sopenharmony_ci status = download_microcode(state, state->fw->data, 61278c2ecf20Sopenharmony_ci state->fw->size); 61288c2ecf20Sopenharmony_ci if (status < 0) 61298c2ecf20Sopenharmony_ci goto error; 61308c2ecf20Sopenharmony_ci } 61318c2ecf20Sopenharmony_ci 61328c2ecf20Sopenharmony_ci /* disable token-ring bus through OFDM block for possible ucode upload */ 61338c2ecf20Sopenharmony_ci status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, 61348c2ecf20Sopenharmony_ci SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); 61358c2ecf20Sopenharmony_ci if (status < 0) 61368c2ecf20Sopenharmony_ci goto error; 61378c2ecf20Sopenharmony_ci 61388c2ecf20Sopenharmony_ci /* Run SCU for a little while to initialize microcode version numbers */ 61398c2ecf20Sopenharmony_ci status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); 61408c2ecf20Sopenharmony_ci if (status < 0) 61418c2ecf20Sopenharmony_ci goto error; 61428c2ecf20Sopenharmony_ci status = drxx_open(state); 61438c2ecf20Sopenharmony_ci if (status < 0) 61448c2ecf20Sopenharmony_ci goto error; 61458c2ecf20Sopenharmony_ci /* added for test */ 61468c2ecf20Sopenharmony_ci msleep(30); 61478c2ecf20Sopenharmony_ci 61488c2ecf20Sopenharmony_ci power_mode = DRXK_POWER_DOWN_OFDM; 61498c2ecf20Sopenharmony_ci status = ctrl_power_mode(state, &power_mode); 61508c2ecf20Sopenharmony_ci if (status < 0) 61518c2ecf20Sopenharmony_ci goto error; 61528c2ecf20Sopenharmony_ci 61538c2ecf20Sopenharmony_ci /* Stamp driver version number in SCU data RAM in BCD code 61548c2ecf20Sopenharmony_ci Done to enable field application engineers to retrieve drxdriver version 61558c2ecf20Sopenharmony_ci via I2C from SCU RAM. 61568c2ecf20Sopenharmony_ci Not using SCU command interface for SCU register access since no 61578c2ecf20Sopenharmony_ci microcode may be present. 61588c2ecf20Sopenharmony_ci */ 61598c2ecf20Sopenharmony_ci driver_version = 61608c2ecf20Sopenharmony_ci (((DRXK_VERSION_MAJOR / 100) % 10) << 12) + 61618c2ecf20Sopenharmony_ci (((DRXK_VERSION_MAJOR / 10) % 10) << 8) + 61628c2ecf20Sopenharmony_ci ((DRXK_VERSION_MAJOR % 10) << 4) + 61638c2ecf20Sopenharmony_ci (DRXK_VERSION_MINOR % 10); 61648c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_DRIVER_VER_HI__A, 61658c2ecf20Sopenharmony_ci driver_version); 61668c2ecf20Sopenharmony_ci if (status < 0) 61678c2ecf20Sopenharmony_ci goto error; 61688c2ecf20Sopenharmony_ci driver_version = 61698c2ecf20Sopenharmony_ci (((DRXK_VERSION_PATCH / 1000) % 10) << 12) + 61708c2ecf20Sopenharmony_ci (((DRXK_VERSION_PATCH / 100) % 10) << 8) + 61718c2ecf20Sopenharmony_ci (((DRXK_VERSION_PATCH / 10) % 10) << 4) + 61728c2ecf20Sopenharmony_ci (DRXK_VERSION_PATCH % 10); 61738c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_DRIVER_VER_LO__A, 61748c2ecf20Sopenharmony_ci driver_version); 61758c2ecf20Sopenharmony_ci if (status < 0) 61768c2ecf20Sopenharmony_ci goto error; 61778c2ecf20Sopenharmony_ci 61788c2ecf20Sopenharmony_ci pr_info("DRXK driver version %d.%d.%d\n", 61798c2ecf20Sopenharmony_ci DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR, 61808c2ecf20Sopenharmony_ci DRXK_VERSION_PATCH); 61818c2ecf20Sopenharmony_ci 61828c2ecf20Sopenharmony_ci /* 61838c2ecf20Sopenharmony_ci * Dirty fix of default values for ROM/PATCH microcode 61848c2ecf20Sopenharmony_ci * Dirty because this fix makes it impossible to setup 61858c2ecf20Sopenharmony_ci * suitable values before calling DRX_Open. This solution 61868c2ecf20Sopenharmony_ci * requires changes to RF AGC speed to be done via the CTRL 61878c2ecf20Sopenharmony_ci * function after calling DRX_Open 61888c2ecf20Sopenharmony_ci */ 61898c2ecf20Sopenharmony_ci 61908c2ecf20Sopenharmony_ci /* m_dvbt_rf_agc_cfg.speed = 3; */ 61918c2ecf20Sopenharmony_ci 61928c2ecf20Sopenharmony_ci /* Reset driver debug flags to 0 */ 61938c2ecf20Sopenharmony_ci status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0); 61948c2ecf20Sopenharmony_ci if (status < 0) 61958c2ecf20Sopenharmony_ci goto error; 61968c2ecf20Sopenharmony_ci /* driver 0.9.0 */ 61978c2ecf20Sopenharmony_ci /* Setup FEC OC: 61988c2ecf20Sopenharmony_ci NOTE: No more full FEC resets allowed afterwards!! */ 61998c2ecf20Sopenharmony_ci status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP); 62008c2ecf20Sopenharmony_ci if (status < 0) 62018c2ecf20Sopenharmony_ci goto error; 62028c2ecf20Sopenharmony_ci /* MPEGTS functions are still the same */ 62038c2ecf20Sopenharmony_ci status = mpegts_dto_init(state); 62048c2ecf20Sopenharmony_ci if (status < 0) 62058c2ecf20Sopenharmony_ci goto error; 62068c2ecf20Sopenharmony_ci status = mpegts_stop(state); 62078c2ecf20Sopenharmony_ci if (status < 0) 62088c2ecf20Sopenharmony_ci goto error; 62098c2ecf20Sopenharmony_ci status = mpegts_configure_polarity(state); 62108c2ecf20Sopenharmony_ci if (status < 0) 62118c2ecf20Sopenharmony_ci goto error; 62128c2ecf20Sopenharmony_ci status = mpegts_configure_pins(state, state->m_enable_mpeg_output); 62138c2ecf20Sopenharmony_ci if (status < 0) 62148c2ecf20Sopenharmony_ci goto error; 62158c2ecf20Sopenharmony_ci /* added: configure GPIO */ 62168c2ecf20Sopenharmony_ci status = write_gpio(state); 62178c2ecf20Sopenharmony_ci if (status < 0) 62188c2ecf20Sopenharmony_ci goto error; 62198c2ecf20Sopenharmony_ci 62208c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_STOPPED; 62218c2ecf20Sopenharmony_ci 62228c2ecf20Sopenharmony_ci if (state->m_b_power_down) { 62238c2ecf20Sopenharmony_ci status = power_down_device(state); 62248c2ecf20Sopenharmony_ci if (status < 0) 62258c2ecf20Sopenharmony_ci goto error; 62268c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_POWERED_DOWN; 62278c2ecf20Sopenharmony_ci } else 62288c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_STOPPED; 62298c2ecf20Sopenharmony_ci 62308c2ecf20Sopenharmony_ci /* Initialize the supported delivery systems */ 62318c2ecf20Sopenharmony_ci n = 0; 62328c2ecf20Sopenharmony_ci if (state->m_has_dvbc) { 62338c2ecf20Sopenharmony_ci state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; 62348c2ecf20Sopenharmony_ci state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; 62358c2ecf20Sopenharmony_ci strlcat(state->frontend.ops.info.name, " DVB-C", 62368c2ecf20Sopenharmony_ci sizeof(state->frontend.ops.info.name)); 62378c2ecf20Sopenharmony_ci } 62388c2ecf20Sopenharmony_ci if (state->m_has_dvbt) { 62398c2ecf20Sopenharmony_ci state->frontend.ops.delsys[n++] = SYS_DVBT; 62408c2ecf20Sopenharmony_ci strlcat(state->frontend.ops.info.name, " DVB-T", 62418c2ecf20Sopenharmony_ci sizeof(state->frontend.ops.info.name)); 62428c2ecf20Sopenharmony_ci } 62438c2ecf20Sopenharmony_ci drxk_i2c_unlock(state); 62448c2ecf20Sopenharmony_ci } 62458c2ecf20Sopenharmony_cierror: 62468c2ecf20Sopenharmony_ci if (status < 0) { 62478c2ecf20Sopenharmony_ci state->m_drxk_state = DRXK_NO_DEV; 62488c2ecf20Sopenharmony_ci drxk_i2c_unlock(state); 62498c2ecf20Sopenharmony_ci pr_err("Error %d on %s\n", status, __func__); 62508c2ecf20Sopenharmony_ci } 62518c2ecf20Sopenharmony_ci 62528c2ecf20Sopenharmony_ci return status; 62538c2ecf20Sopenharmony_ci} 62548c2ecf20Sopenharmony_ci 62558c2ecf20Sopenharmony_cistatic void load_firmware_cb(const struct firmware *fw, 62568c2ecf20Sopenharmony_ci void *context) 62578c2ecf20Sopenharmony_ci{ 62588c2ecf20Sopenharmony_ci struct drxk_state *state = context; 62598c2ecf20Sopenharmony_ci 62608c2ecf20Sopenharmony_ci dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); 62618c2ecf20Sopenharmony_ci if (!fw) { 62628c2ecf20Sopenharmony_ci pr_err("Could not load firmware file %s.\n", 62638c2ecf20Sopenharmony_ci state->microcode_name); 62648c2ecf20Sopenharmony_ci pr_info("Copy %s to your hotplug directory!\n", 62658c2ecf20Sopenharmony_ci state->microcode_name); 62668c2ecf20Sopenharmony_ci state->microcode_name = NULL; 62678c2ecf20Sopenharmony_ci 62688c2ecf20Sopenharmony_ci /* 62698c2ecf20Sopenharmony_ci * As firmware is now load asynchronous, it is not possible 62708c2ecf20Sopenharmony_ci * anymore to fail at frontend attach. We might silently 62718c2ecf20Sopenharmony_ci * return here, and hope that the driver won't crash. 62728c2ecf20Sopenharmony_ci * We might also change all DVB callbacks to return -ENODEV 62738c2ecf20Sopenharmony_ci * if the device is not initialized. 62748c2ecf20Sopenharmony_ci * As the DRX-K devices have their own internal firmware, 62758c2ecf20Sopenharmony_ci * let's just hope that it will match a firmware revision 62768c2ecf20Sopenharmony_ci * compatible with this driver and proceed. 62778c2ecf20Sopenharmony_ci */ 62788c2ecf20Sopenharmony_ci } 62798c2ecf20Sopenharmony_ci state->fw = fw; 62808c2ecf20Sopenharmony_ci 62818c2ecf20Sopenharmony_ci init_drxk(state); 62828c2ecf20Sopenharmony_ci} 62838c2ecf20Sopenharmony_ci 62848c2ecf20Sopenharmony_cistatic void drxk_release(struct dvb_frontend *fe) 62858c2ecf20Sopenharmony_ci{ 62868c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 62878c2ecf20Sopenharmony_ci 62888c2ecf20Sopenharmony_ci dprintk(1, "\n"); 62898c2ecf20Sopenharmony_ci release_firmware(state->fw); 62908c2ecf20Sopenharmony_ci 62918c2ecf20Sopenharmony_ci kfree(state); 62928c2ecf20Sopenharmony_ci} 62938c2ecf20Sopenharmony_ci 62948c2ecf20Sopenharmony_cistatic int drxk_sleep(struct dvb_frontend *fe) 62958c2ecf20Sopenharmony_ci{ 62968c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 62978c2ecf20Sopenharmony_ci 62988c2ecf20Sopenharmony_ci dprintk(1, "\n"); 62998c2ecf20Sopenharmony_ci 63008c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 63018c2ecf20Sopenharmony_ci return -ENODEV; 63028c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 63038c2ecf20Sopenharmony_ci return 0; 63048c2ecf20Sopenharmony_ci 63058c2ecf20Sopenharmony_ci shut_down(state); 63068c2ecf20Sopenharmony_ci return 0; 63078c2ecf20Sopenharmony_ci} 63088c2ecf20Sopenharmony_ci 63098c2ecf20Sopenharmony_cistatic int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 63108c2ecf20Sopenharmony_ci{ 63118c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 63128c2ecf20Sopenharmony_ci 63138c2ecf20Sopenharmony_ci dprintk(1, ": %s\n", enable ? "enable" : "disable"); 63148c2ecf20Sopenharmony_ci 63158c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 63168c2ecf20Sopenharmony_ci return -ENODEV; 63178c2ecf20Sopenharmony_ci 63188c2ecf20Sopenharmony_ci return ConfigureI2CBridge(state, enable ? true : false); 63198c2ecf20Sopenharmony_ci} 63208c2ecf20Sopenharmony_ci 63218c2ecf20Sopenharmony_cistatic int drxk_set_parameters(struct dvb_frontend *fe) 63228c2ecf20Sopenharmony_ci{ 63238c2ecf20Sopenharmony_ci struct dtv_frontend_properties *p = &fe->dtv_property_cache; 63248c2ecf20Sopenharmony_ci u32 delsys = p->delivery_system, old_delsys; 63258c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 63268c2ecf20Sopenharmony_ci u32 IF; 63278c2ecf20Sopenharmony_ci 63288c2ecf20Sopenharmony_ci dprintk(1, "\n"); 63298c2ecf20Sopenharmony_ci 63308c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 63318c2ecf20Sopenharmony_ci return -ENODEV; 63328c2ecf20Sopenharmony_ci 63338c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 63348c2ecf20Sopenharmony_ci return -EAGAIN; 63358c2ecf20Sopenharmony_ci 63368c2ecf20Sopenharmony_ci if (!fe->ops.tuner_ops.get_if_frequency) { 63378c2ecf20Sopenharmony_ci pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); 63388c2ecf20Sopenharmony_ci return -EINVAL; 63398c2ecf20Sopenharmony_ci } 63408c2ecf20Sopenharmony_ci 63418c2ecf20Sopenharmony_ci if (fe->ops.i2c_gate_ctrl) 63428c2ecf20Sopenharmony_ci fe->ops.i2c_gate_ctrl(fe, 1); 63438c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.set_params) 63448c2ecf20Sopenharmony_ci fe->ops.tuner_ops.set_params(fe); 63458c2ecf20Sopenharmony_ci if (fe->ops.i2c_gate_ctrl) 63468c2ecf20Sopenharmony_ci fe->ops.i2c_gate_ctrl(fe, 0); 63478c2ecf20Sopenharmony_ci 63488c2ecf20Sopenharmony_ci old_delsys = state->props.delivery_system; 63498c2ecf20Sopenharmony_ci state->props = *p; 63508c2ecf20Sopenharmony_ci 63518c2ecf20Sopenharmony_ci if (old_delsys != delsys) { 63528c2ecf20Sopenharmony_ci shut_down(state); 63538c2ecf20Sopenharmony_ci switch (delsys) { 63548c2ecf20Sopenharmony_ci case SYS_DVBC_ANNEX_A: 63558c2ecf20Sopenharmony_ci case SYS_DVBC_ANNEX_C: 63568c2ecf20Sopenharmony_ci if (!state->m_has_dvbc) 63578c2ecf20Sopenharmony_ci return -EINVAL; 63588c2ecf20Sopenharmony_ci state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? 63598c2ecf20Sopenharmony_ci true : false; 63608c2ecf20Sopenharmony_ci if (state->m_itut_annex_c) 63618c2ecf20Sopenharmony_ci setoperation_mode(state, OM_QAM_ITU_C); 63628c2ecf20Sopenharmony_ci else 63638c2ecf20Sopenharmony_ci setoperation_mode(state, OM_QAM_ITU_A); 63648c2ecf20Sopenharmony_ci break; 63658c2ecf20Sopenharmony_ci case SYS_DVBT: 63668c2ecf20Sopenharmony_ci if (!state->m_has_dvbt) 63678c2ecf20Sopenharmony_ci return -EINVAL; 63688c2ecf20Sopenharmony_ci setoperation_mode(state, OM_DVBT); 63698c2ecf20Sopenharmony_ci break; 63708c2ecf20Sopenharmony_ci default: 63718c2ecf20Sopenharmony_ci return -EINVAL; 63728c2ecf20Sopenharmony_ci } 63738c2ecf20Sopenharmony_ci } 63748c2ecf20Sopenharmony_ci 63758c2ecf20Sopenharmony_ci fe->ops.tuner_ops.get_if_frequency(fe, &IF); 63768c2ecf20Sopenharmony_ci start(state, 0, IF); 63778c2ecf20Sopenharmony_ci 63788c2ecf20Sopenharmony_ci /* After set_frontend, stats aren't available */ 63798c2ecf20Sopenharmony_ci p->strength.stat[0].scale = FE_SCALE_RELATIVE; 63808c2ecf20Sopenharmony_ci p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63818c2ecf20Sopenharmony_ci p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63828c2ecf20Sopenharmony_ci p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63838c2ecf20Sopenharmony_ci p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63848c2ecf20Sopenharmony_ci p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63858c2ecf20Sopenharmony_ci p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63868c2ecf20Sopenharmony_ci p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 63878c2ecf20Sopenharmony_ci 63888c2ecf20Sopenharmony_ci /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */ 63898c2ecf20Sopenharmony_ci 63908c2ecf20Sopenharmony_ci return 0; 63918c2ecf20Sopenharmony_ci} 63928c2ecf20Sopenharmony_ci 63938c2ecf20Sopenharmony_cistatic int get_strength(struct drxk_state *state, u64 *strength) 63948c2ecf20Sopenharmony_ci{ 63958c2ecf20Sopenharmony_ci int status; 63968c2ecf20Sopenharmony_ci struct s_cfg_agc rf_agc, if_agc; 63978c2ecf20Sopenharmony_ci u32 total_gain = 0; 63988c2ecf20Sopenharmony_ci u32 atten = 0; 63998c2ecf20Sopenharmony_ci u32 agc_range = 0; 64008c2ecf20Sopenharmony_ci u16 scu_lvl = 0; 64018c2ecf20Sopenharmony_ci u16 scu_coc = 0; 64028c2ecf20Sopenharmony_ci /* FIXME: those are part of the tuner presets */ 64038c2ecf20Sopenharmony_ci u16 tuner_rf_gain = 50; /* Default value on az6007 driver */ 64048c2ecf20Sopenharmony_ci u16 tuner_if_gain = 40; /* Default value on az6007 driver */ 64058c2ecf20Sopenharmony_ci 64068c2ecf20Sopenharmony_ci *strength = 0; 64078c2ecf20Sopenharmony_ci 64088c2ecf20Sopenharmony_ci if (is_dvbt(state)) { 64098c2ecf20Sopenharmony_ci rf_agc = state->m_dvbt_rf_agc_cfg; 64108c2ecf20Sopenharmony_ci if_agc = state->m_dvbt_if_agc_cfg; 64118c2ecf20Sopenharmony_ci } else if (is_qam(state)) { 64128c2ecf20Sopenharmony_ci rf_agc = state->m_qam_rf_agc_cfg; 64138c2ecf20Sopenharmony_ci if_agc = state->m_qam_if_agc_cfg; 64148c2ecf20Sopenharmony_ci } else { 64158c2ecf20Sopenharmony_ci rf_agc = state->m_atv_rf_agc_cfg; 64168c2ecf20Sopenharmony_ci if_agc = state->m_atv_if_agc_cfg; 64178c2ecf20Sopenharmony_ci } 64188c2ecf20Sopenharmony_ci 64198c2ecf20Sopenharmony_ci if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 64208c2ecf20Sopenharmony_ci /* SCU output_level */ 64218c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl); 64228c2ecf20Sopenharmony_ci if (status < 0) 64238c2ecf20Sopenharmony_ci return status; 64248c2ecf20Sopenharmony_ci 64258c2ecf20Sopenharmony_ci /* SCU c.o.c. */ 64268c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); 64278c2ecf20Sopenharmony_ci if (status < 0) 64288c2ecf20Sopenharmony_ci return status; 64298c2ecf20Sopenharmony_ci 64308c2ecf20Sopenharmony_ci if (((u32) scu_lvl + (u32) scu_coc) < 0xffff) 64318c2ecf20Sopenharmony_ci rf_agc.output_level = scu_lvl + scu_coc; 64328c2ecf20Sopenharmony_ci else 64338c2ecf20Sopenharmony_ci rf_agc.output_level = 0xffff; 64348c2ecf20Sopenharmony_ci 64358c2ecf20Sopenharmony_ci /* Take RF gain into account */ 64368c2ecf20Sopenharmony_ci total_gain += tuner_rf_gain; 64378c2ecf20Sopenharmony_ci 64388c2ecf20Sopenharmony_ci /* clip output value */ 64398c2ecf20Sopenharmony_ci if (rf_agc.output_level < rf_agc.min_output_level) 64408c2ecf20Sopenharmony_ci rf_agc.output_level = rf_agc.min_output_level; 64418c2ecf20Sopenharmony_ci if (rf_agc.output_level > rf_agc.max_output_level) 64428c2ecf20Sopenharmony_ci rf_agc.output_level = rf_agc.max_output_level; 64438c2ecf20Sopenharmony_ci 64448c2ecf20Sopenharmony_ci agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level); 64458c2ecf20Sopenharmony_ci if (agc_range > 0) { 64468c2ecf20Sopenharmony_ci atten += 100UL * 64478c2ecf20Sopenharmony_ci ((u32)(tuner_rf_gain)) * 64488c2ecf20Sopenharmony_ci ((u32)(rf_agc.output_level - rf_agc.min_output_level)) 64498c2ecf20Sopenharmony_ci / agc_range; 64508c2ecf20Sopenharmony_ci } 64518c2ecf20Sopenharmony_ci } 64528c2ecf20Sopenharmony_ci 64538c2ecf20Sopenharmony_ci if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { 64548c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 64558c2ecf20Sopenharmony_ci &if_agc.output_level); 64568c2ecf20Sopenharmony_ci if (status < 0) 64578c2ecf20Sopenharmony_ci return status; 64588c2ecf20Sopenharmony_ci 64598c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, 64608c2ecf20Sopenharmony_ci &if_agc.top); 64618c2ecf20Sopenharmony_ci if (status < 0) 64628c2ecf20Sopenharmony_ci return status; 64638c2ecf20Sopenharmony_ci 64648c2ecf20Sopenharmony_ci /* Take IF gain into account */ 64658c2ecf20Sopenharmony_ci total_gain += (u32) tuner_if_gain; 64668c2ecf20Sopenharmony_ci 64678c2ecf20Sopenharmony_ci /* clip output value */ 64688c2ecf20Sopenharmony_ci if (if_agc.output_level < if_agc.min_output_level) 64698c2ecf20Sopenharmony_ci if_agc.output_level = if_agc.min_output_level; 64708c2ecf20Sopenharmony_ci if (if_agc.output_level > if_agc.max_output_level) 64718c2ecf20Sopenharmony_ci if_agc.output_level = if_agc.max_output_level; 64728c2ecf20Sopenharmony_ci 64738c2ecf20Sopenharmony_ci agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level); 64748c2ecf20Sopenharmony_ci if (agc_range > 0) { 64758c2ecf20Sopenharmony_ci atten += 100UL * 64768c2ecf20Sopenharmony_ci ((u32)(tuner_if_gain)) * 64778c2ecf20Sopenharmony_ci ((u32)(if_agc.output_level - if_agc.min_output_level)) 64788c2ecf20Sopenharmony_ci / agc_range; 64798c2ecf20Sopenharmony_ci } 64808c2ecf20Sopenharmony_ci } 64818c2ecf20Sopenharmony_ci 64828c2ecf20Sopenharmony_ci /* 64838c2ecf20Sopenharmony_ci * Convert to 0..65535 scale. 64848c2ecf20Sopenharmony_ci * If it can't be measured (AGC is disabled), just show 100%. 64858c2ecf20Sopenharmony_ci */ 64868c2ecf20Sopenharmony_ci if (total_gain > 0) 64878c2ecf20Sopenharmony_ci *strength = (65535UL * atten / total_gain / 100); 64888c2ecf20Sopenharmony_ci else 64898c2ecf20Sopenharmony_ci *strength = 65535; 64908c2ecf20Sopenharmony_ci 64918c2ecf20Sopenharmony_ci return 0; 64928c2ecf20Sopenharmony_ci} 64938c2ecf20Sopenharmony_ci 64948c2ecf20Sopenharmony_cistatic int drxk_get_stats(struct dvb_frontend *fe) 64958c2ecf20Sopenharmony_ci{ 64968c2ecf20Sopenharmony_ci struct dtv_frontend_properties *c = &fe->dtv_property_cache; 64978c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 64988c2ecf20Sopenharmony_ci int status; 64998c2ecf20Sopenharmony_ci u32 stat; 65008c2ecf20Sopenharmony_ci u16 reg16; 65018c2ecf20Sopenharmony_ci u32 post_bit_count; 65028c2ecf20Sopenharmony_ci u32 post_bit_err_count; 65038c2ecf20Sopenharmony_ci u32 post_bit_error_scale; 65048c2ecf20Sopenharmony_ci u32 pre_bit_err_count; 65058c2ecf20Sopenharmony_ci u32 pre_bit_count; 65068c2ecf20Sopenharmony_ci u32 pkt_count; 65078c2ecf20Sopenharmony_ci u32 pkt_error_count; 65088c2ecf20Sopenharmony_ci s32 cnr; 65098c2ecf20Sopenharmony_ci 65108c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 65118c2ecf20Sopenharmony_ci return -ENODEV; 65128c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 65138c2ecf20Sopenharmony_ci return -EAGAIN; 65148c2ecf20Sopenharmony_ci 65158c2ecf20Sopenharmony_ci /* get status */ 65168c2ecf20Sopenharmony_ci state->fe_status = 0; 65178c2ecf20Sopenharmony_ci get_lock_status(state, &stat); 65188c2ecf20Sopenharmony_ci if (stat == MPEG_LOCK) 65198c2ecf20Sopenharmony_ci state->fe_status |= 0x1f; 65208c2ecf20Sopenharmony_ci if (stat == FEC_LOCK) 65218c2ecf20Sopenharmony_ci state->fe_status |= 0x0f; 65228c2ecf20Sopenharmony_ci if (stat == DEMOD_LOCK) 65238c2ecf20Sopenharmony_ci state->fe_status |= 0x07; 65248c2ecf20Sopenharmony_ci 65258c2ecf20Sopenharmony_ci /* 65268c2ecf20Sopenharmony_ci * Estimate signal strength from AGC 65278c2ecf20Sopenharmony_ci */ 65288c2ecf20Sopenharmony_ci get_strength(state, &c->strength.stat[0].uvalue); 65298c2ecf20Sopenharmony_ci c->strength.stat[0].scale = FE_SCALE_RELATIVE; 65308c2ecf20Sopenharmony_ci 65318c2ecf20Sopenharmony_ci 65328c2ecf20Sopenharmony_ci if (stat >= DEMOD_LOCK) { 65338c2ecf20Sopenharmony_ci get_signal_to_noise(state, &cnr); 65348c2ecf20Sopenharmony_ci c->cnr.stat[0].svalue = cnr * 100; 65358c2ecf20Sopenharmony_ci c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 65368c2ecf20Sopenharmony_ci } else { 65378c2ecf20Sopenharmony_ci c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65388c2ecf20Sopenharmony_ci } 65398c2ecf20Sopenharmony_ci 65408c2ecf20Sopenharmony_ci if (stat < FEC_LOCK) { 65418c2ecf20Sopenharmony_ci c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65428c2ecf20Sopenharmony_ci c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65438c2ecf20Sopenharmony_ci c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65448c2ecf20Sopenharmony_ci c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65458c2ecf20Sopenharmony_ci c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65468c2ecf20Sopenharmony_ci c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 65478c2ecf20Sopenharmony_ci return 0; 65488c2ecf20Sopenharmony_ci } 65498c2ecf20Sopenharmony_ci 65508c2ecf20Sopenharmony_ci /* Get post BER */ 65518c2ecf20Sopenharmony_ci 65528c2ecf20Sopenharmony_ci /* BER measurement is valid if at least FEC lock is achieved */ 65538c2ecf20Sopenharmony_ci 65548c2ecf20Sopenharmony_ci /* 65558c2ecf20Sopenharmony_ci * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be 65568c2ecf20Sopenharmony_ci * written to set nr of symbols or bits over which to measure 65578c2ecf20Sopenharmony_ci * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). 65588c2ecf20Sopenharmony_ci */ 65598c2ecf20Sopenharmony_ci 65608c2ecf20Sopenharmony_ci /* Read registers for post/preViterbi BER calculation */ 65618c2ecf20Sopenharmony_ci status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16); 65628c2ecf20Sopenharmony_ci if (status < 0) 65638c2ecf20Sopenharmony_ci goto error; 65648c2ecf20Sopenharmony_ci pre_bit_err_count = reg16; 65658c2ecf20Sopenharmony_ci 65668c2ecf20Sopenharmony_ci status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16); 65678c2ecf20Sopenharmony_ci if (status < 0) 65688c2ecf20Sopenharmony_ci goto error; 65698c2ecf20Sopenharmony_ci pre_bit_count = reg16; 65708c2ecf20Sopenharmony_ci 65718c2ecf20Sopenharmony_ci /* Number of bit-errors */ 65728c2ecf20Sopenharmony_ci status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16); 65738c2ecf20Sopenharmony_ci if (status < 0) 65748c2ecf20Sopenharmony_ci goto error; 65758c2ecf20Sopenharmony_ci post_bit_err_count = reg16; 65768c2ecf20Sopenharmony_ci 65778c2ecf20Sopenharmony_ci status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16); 65788c2ecf20Sopenharmony_ci if (status < 0) 65798c2ecf20Sopenharmony_ci goto error; 65808c2ecf20Sopenharmony_ci post_bit_error_scale = reg16; 65818c2ecf20Sopenharmony_ci 65828c2ecf20Sopenharmony_ci status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16); 65838c2ecf20Sopenharmony_ci if (status < 0) 65848c2ecf20Sopenharmony_ci goto error; 65858c2ecf20Sopenharmony_ci pkt_count = reg16; 65868c2ecf20Sopenharmony_ci 65878c2ecf20Sopenharmony_ci status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16); 65888c2ecf20Sopenharmony_ci if (status < 0) 65898c2ecf20Sopenharmony_ci goto error; 65908c2ecf20Sopenharmony_ci pkt_error_count = reg16; 65918c2ecf20Sopenharmony_ci write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); 65928c2ecf20Sopenharmony_ci 65938c2ecf20Sopenharmony_ci post_bit_err_count *= post_bit_error_scale; 65948c2ecf20Sopenharmony_ci 65958c2ecf20Sopenharmony_ci post_bit_count = pkt_count * 204 * 8; 65968c2ecf20Sopenharmony_ci 65978c2ecf20Sopenharmony_ci /* Store the results */ 65988c2ecf20Sopenharmony_ci c->block_error.stat[0].scale = FE_SCALE_COUNTER; 65998c2ecf20Sopenharmony_ci c->block_error.stat[0].uvalue += pkt_error_count; 66008c2ecf20Sopenharmony_ci c->block_count.stat[0].scale = FE_SCALE_COUNTER; 66018c2ecf20Sopenharmony_ci c->block_count.stat[0].uvalue += pkt_count; 66028c2ecf20Sopenharmony_ci 66038c2ecf20Sopenharmony_ci c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; 66048c2ecf20Sopenharmony_ci c->pre_bit_error.stat[0].uvalue += pre_bit_err_count; 66058c2ecf20Sopenharmony_ci c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; 66068c2ecf20Sopenharmony_ci c->pre_bit_count.stat[0].uvalue += pre_bit_count; 66078c2ecf20Sopenharmony_ci 66088c2ecf20Sopenharmony_ci c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 66098c2ecf20Sopenharmony_ci c->post_bit_error.stat[0].uvalue += post_bit_err_count; 66108c2ecf20Sopenharmony_ci c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 66118c2ecf20Sopenharmony_ci c->post_bit_count.stat[0].uvalue += post_bit_count; 66128c2ecf20Sopenharmony_ci 66138c2ecf20Sopenharmony_cierror: 66148c2ecf20Sopenharmony_ci return status; 66158c2ecf20Sopenharmony_ci} 66168c2ecf20Sopenharmony_ci 66178c2ecf20Sopenharmony_ci 66188c2ecf20Sopenharmony_cistatic int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status) 66198c2ecf20Sopenharmony_ci{ 66208c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 66218c2ecf20Sopenharmony_ci int rc; 66228c2ecf20Sopenharmony_ci 66238c2ecf20Sopenharmony_ci dprintk(1, "\n"); 66248c2ecf20Sopenharmony_ci 66258c2ecf20Sopenharmony_ci rc = drxk_get_stats(fe); 66268c2ecf20Sopenharmony_ci if (rc < 0) 66278c2ecf20Sopenharmony_ci return rc; 66288c2ecf20Sopenharmony_ci 66298c2ecf20Sopenharmony_ci *status = state->fe_status; 66308c2ecf20Sopenharmony_ci 66318c2ecf20Sopenharmony_ci return 0; 66328c2ecf20Sopenharmony_ci} 66338c2ecf20Sopenharmony_ci 66348c2ecf20Sopenharmony_cistatic int drxk_read_signal_strength(struct dvb_frontend *fe, 66358c2ecf20Sopenharmony_ci u16 *strength) 66368c2ecf20Sopenharmony_ci{ 66378c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 66388c2ecf20Sopenharmony_ci struct dtv_frontend_properties *c = &fe->dtv_property_cache; 66398c2ecf20Sopenharmony_ci 66408c2ecf20Sopenharmony_ci dprintk(1, "\n"); 66418c2ecf20Sopenharmony_ci 66428c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 66438c2ecf20Sopenharmony_ci return -ENODEV; 66448c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 66458c2ecf20Sopenharmony_ci return -EAGAIN; 66468c2ecf20Sopenharmony_ci 66478c2ecf20Sopenharmony_ci *strength = c->strength.stat[0].uvalue; 66488c2ecf20Sopenharmony_ci return 0; 66498c2ecf20Sopenharmony_ci} 66508c2ecf20Sopenharmony_ci 66518c2ecf20Sopenharmony_cistatic int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) 66528c2ecf20Sopenharmony_ci{ 66538c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 66548c2ecf20Sopenharmony_ci s32 snr2; 66558c2ecf20Sopenharmony_ci 66568c2ecf20Sopenharmony_ci dprintk(1, "\n"); 66578c2ecf20Sopenharmony_ci 66588c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 66598c2ecf20Sopenharmony_ci return -ENODEV; 66608c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 66618c2ecf20Sopenharmony_ci return -EAGAIN; 66628c2ecf20Sopenharmony_ci 66638c2ecf20Sopenharmony_ci get_signal_to_noise(state, &snr2); 66648c2ecf20Sopenharmony_ci 66658c2ecf20Sopenharmony_ci /* No negative SNR, clip to zero */ 66668c2ecf20Sopenharmony_ci if (snr2 < 0) 66678c2ecf20Sopenharmony_ci snr2 = 0; 66688c2ecf20Sopenharmony_ci *snr = snr2 & 0xffff; 66698c2ecf20Sopenharmony_ci return 0; 66708c2ecf20Sopenharmony_ci} 66718c2ecf20Sopenharmony_ci 66728c2ecf20Sopenharmony_cistatic int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 66738c2ecf20Sopenharmony_ci{ 66748c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 66758c2ecf20Sopenharmony_ci u16 err = 0; 66768c2ecf20Sopenharmony_ci 66778c2ecf20Sopenharmony_ci dprintk(1, "\n"); 66788c2ecf20Sopenharmony_ci 66798c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 66808c2ecf20Sopenharmony_ci return -ENODEV; 66818c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 66828c2ecf20Sopenharmony_ci return -EAGAIN; 66838c2ecf20Sopenharmony_ci 66848c2ecf20Sopenharmony_ci dvbtqam_get_acc_pkt_err(state, &err); 66858c2ecf20Sopenharmony_ci *ucblocks = (u32) err; 66868c2ecf20Sopenharmony_ci return 0; 66878c2ecf20Sopenharmony_ci} 66888c2ecf20Sopenharmony_ci 66898c2ecf20Sopenharmony_cistatic int drxk_get_tune_settings(struct dvb_frontend *fe, 66908c2ecf20Sopenharmony_ci struct dvb_frontend_tune_settings *sets) 66918c2ecf20Sopenharmony_ci{ 66928c2ecf20Sopenharmony_ci struct drxk_state *state = fe->demodulator_priv; 66938c2ecf20Sopenharmony_ci struct dtv_frontend_properties *p = &fe->dtv_property_cache; 66948c2ecf20Sopenharmony_ci 66958c2ecf20Sopenharmony_ci dprintk(1, "\n"); 66968c2ecf20Sopenharmony_ci 66978c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_NO_DEV) 66988c2ecf20Sopenharmony_ci return -ENODEV; 66998c2ecf20Sopenharmony_ci if (state->m_drxk_state == DRXK_UNINITIALIZED) 67008c2ecf20Sopenharmony_ci return -EAGAIN; 67018c2ecf20Sopenharmony_ci 67028c2ecf20Sopenharmony_ci switch (p->delivery_system) { 67038c2ecf20Sopenharmony_ci case SYS_DVBC_ANNEX_A: 67048c2ecf20Sopenharmony_ci case SYS_DVBC_ANNEX_C: 67058c2ecf20Sopenharmony_ci case SYS_DVBT: 67068c2ecf20Sopenharmony_ci sets->min_delay_ms = 3000; 67078c2ecf20Sopenharmony_ci sets->max_drift = 0; 67088c2ecf20Sopenharmony_ci sets->step_size = 0; 67098c2ecf20Sopenharmony_ci return 0; 67108c2ecf20Sopenharmony_ci default: 67118c2ecf20Sopenharmony_ci return -EINVAL; 67128c2ecf20Sopenharmony_ci } 67138c2ecf20Sopenharmony_ci} 67148c2ecf20Sopenharmony_ci 67158c2ecf20Sopenharmony_cistatic const struct dvb_frontend_ops drxk_ops = { 67168c2ecf20Sopenharmony_ci /* .delsys will be filled dynamically */ 67178c2ecf20Sopenharmony_ci .info = { 67188c2ecf20Sopenharmony_ci .name = "DRXK", 67198c2ecf20Sopenharmony_ci .frequency_min_hz = 47 * MHz, 67208c2ecf20Sopenharmony_ci .frequency_max_hz = 865 * MHz, 67218c2ecf20Sopenharmony_ci /* For DVB-C */ 67228c2ecf20Sopenharmony_ci .symbol_rate_min = 870000, 67238c2ecf20Sopenharmony_ci .symbol_rate_max = 11700000, 67248c2ecf20Sopenharmony_ci /* For DVB-T */ 67258c2ecf20Sopenharmony_ci .frequency_stepsize_hz = 166667, 67268c2ecf20Sopenharmony_ci 67278c2ecf20Sopenharmony_ci .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | 67288c2ecf20Sopenharmony_ci FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO | 67298c2ecf20Sopenharmony_ci FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 67308c2ecf20Sopenharmony_ci FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS | 67318c2ecf20Sopenharmony_ci FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER | 67328c2ecf20Sopenharmony_ci FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO 67338c2ecf20Sopenharmony_ci }, 67348c2ecf20Sopenharmony_ci 67358c2ecf20Sopenharmony_ci .release = drxk_release, 67368c2ecf20Sopenharmony_ci .sleep = drxk_sleep, 67378c2ecf20Sopenharmony_ci .i2c_gate_ctrl = drxk_gate_ctrl, 67388c2ecf20Sopenharmony_ci 67398c2ecf20Sopenharmony_ci .set_frontend = drxk_set_parameters, 67408c2ecf20Sopenharmony_ci .get_tune_settings = drxk_get_tune_settings, 67418c2ecf20Sopenharmony_ci 67428c2ecf20Sopenharmony_ci .read_status = drxk_read_status, 67438c2ecf20Sopenharmony_ci .read_signal_strength = drxk_read_signal_strength, 67448c2ecf20Sopenharmony_ci .read_snr = drxk_read_snr, 67458c2ecf20Sopenharmony_ci .read_ucblocks = drxk_read_ucblocks, 67468c2ecf20Sopenharmony_ci}; 67478c2ecf20Sopenharmony_ci 67488c2ecf20Sopenharmony_cistruct dvb_frontend *drxk_attach(const struct drxk_config *config, 67498c2ecf20Sopenharmony_ci struct i2c_adapter *i2c) 67508c2ecf20Sopenharmony_ci{ 67518c2ecf20Sopenharmony_ci struct dtv_frontend_properties *p; 67528c2ecf20Sopenharmony_ci struct drxk_state *state = NULL; 67538c2ecf20Sopenharmony_ci u8 adr = config->adr; 67548c2ecf20Sopenharmony_ci int status; 67558c2ecf20Sopenharmony_ci 67568c2ecf20Sopenharmony_ci dprintk(1, "\n"); 67578c2ecf20Sopenharmony_ci state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); 67588c2ecf20Sopenharmony_ci if (!state) 67598c2ecf20Sopenharmony_ci return NULL; 67608c2ecf20Sopenharmony_ci 67618c2ecf20Sopenharmony_ci state->i2c = i2c; 67628c2ecf20Sopenharmony_ci state->demod_address = adr; 67638c2ecf20Sopenharmony_ci state->single_master = config->single_master; 67648c2ecf20Sopenharmony_ci state->microcode_name = config->microcode_name; 67658c2ecf20Sopenharmony_ci state->qam_demod_parameter_count = config->qam_demod_parameter_count; 67668c2ecf20Sopenharmony_ci state->no_i2c_bridge = config->no_i2c_bridge; 67678c2ecf20Sopenharmony_ci state->antenna_gpio = config->antenna_gpio; 67688c2ecf20Sopenharmony_ci state->antenna_dvbt = config->antenna_dvbt; 67698c2ecf20Sopenharmony_ci state->m_chunk_size = config->chunk_size; 67708c2ecf20Sopenharmony_ci state->enable_merr_cfg = config->enable_merr_cfg; 67718c2ecf20Sopenharmony_ci 67728c2ecf20Sopenharmony_ci if (config->dynamic_clk) { 67738c2ecf20Sopenharmony_ci state->m_dvbt_static_clk = false; 67748c2ecf20Sopenharmony_ci state->m_dvbc_static_clk = false; 67758c2ecf20Sopenharmony_ci } else { 67768c2ecf20Sopenharmony_ci state->m_dvbt_static_clk = true; 67778c2ecf20Sopenharmony_ci state->m_dvbc_static_clk = true; 67788c2ecf20Sopenharmony_ci } 67798c2ecf20Sopenharmony_ci 67808c2ecf20Sopenharmony_ci 67818c2ecf20Sopenharmony_ci if (config->mpeg_out_clk_strength) 67828c2ecf20Sopenharmony_ci state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; 67838c2ecf20Sopenharmony_ci else 67848c2ecf20Sopenharmony_ci state->m_ts_clockk_strength = 0x06; 67858c2ecf20Sopenharmony_ci 67868c2ecf20Sopenharmony_ci if (config->parallel_ts) 67878c2ecf20Sopenharmony_ci state->m_enable_parallel = true; 67888c2ecf20Sopenharmony_ci else 67898c2ecf20Sopenharmony_ci state->m_enable_parallel = false; 67908c2ecf20Sopenharmony_ci 67918c2ecf20Sopenharmony_ci /* NOTE: as more UIO bits will be used, add them to the mask */ 67928c2ecf20Sopenharmony_ci state->uio_mask = config->antenna_gpio; 67938c2ecf20Sopenharmony_ci 67948c2ecf20Sopenharmony_ci /* Default gpio to DVB-C */ 67958c2ecf20Sopenharmony_ci if (!state->antenna_dvbt && state->antenna_gpio) 67968c2ecf20Sopenharmony_ci state->m_gpio |= state->antenna_gpio; 67978c2ecf20Sopenharmony_ci else 67988c2ecf20Sopenharmony_ci state->m_gpio &= ~state->antenna_gpio; 67998c2ecf20Sopenharmony_ci 68008c2ecf20Sopenharmony_ci mutex_init(&state->mutex); 68018c2ecf20Sopenharmony_ci 68028c2ecf20Sopenharmony_ci memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops)); 68038c2ecf20Sopenharmony_ci state->frontend.demodulator_priv = state; 68048c2ecf20Sopenharmony_ci 68058c2ecf20Sopenharmony_ci init_state(state); 68068c2ecf20Sopenharmony_ci 68078c2ecf20Sopenharmony_ci /* Load firmware and initialize DRX-K */ 68088c2ecf20Sopenharmony_ci if (state->microcode_name) { 68098c2ecf20Sopenharmony_ci const struct firmware *fw = NULL; 68108c2ecf20Sopenharmony_ci 68118c2ecf20Sopenharmony_ci status = request_firmware(&fw, state->microcode_name, 68128c2ecf20Sopenharmony_ci state->i2c->dev.parent); 68138c2ecf20Sopenharmony_ci if (status < 0) 68148c2ecf20Sopenharmony_ci fw = NULL; 68158c2ecf20Sopenharmony_ci load_firmware_cb(fw, state); 68168c2ecf20Sopenharmony_ci } else if (init_drxk(state) < 0) 68178c2ecf20Sopenharmony_ci goto error; 68188c2ecf20Sopenharmony_ci 68198c2ecf20Sopenharmony_ci 68208c2ecf20Sopenharmony_ci /* Initialize stats */ 68218c2ecf20Sopenharmony_ci p = &state->frontend.dtv_property_cache; 68228c2ecf20Sopenharmony_ci p->strength.len = 1; 68238c2ecf20Sopenharmony_ci p->cnr.len = 1; 68248c2ecf20Sopenharmony_ci p->block_error.len = 1; 68258c2ecf20Sopenharmony_ci p->block_count.len = 1; 68268c2ecf20Sopenharmony_ci p->pre_bit_error.len = 1; 68278c2ecf20Sopenharmony_ci p->pre_bit_count.len = 1; 68288c2ecf20Sopenharmony_ci p->post_bit_error.len = 1; 68298c2ecf20Sopenharmony_ci p->post_bit_count.len = 1; 68308c2ecf20Sopenharmony_ci 68318c2ecf20Sopenharmony_ci p->strength.stat[0].scale = FE_SCALE_RELATIVE; 68328c2ecf20Sopenharmony_ci p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68338c2ecf20Sopenharmony_ci p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68348c2ecf20Sopenharmony_ci p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68358c2ecf20Sopenharmony_ci p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68368c2ecf20Sopenharmony_ci p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68378c2ecf20Sopenharmony_ci p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68388c2ecf20Sopenharmony_ci p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 68398c2ecf20Sopenharmony_ci 68408c2ecf20Sopenharmony_ci pr_info("frontend initialized.\n"); 68418c2ecf20Sopenharmony_ci return &state->frontend; 68428c2ecf20Sopenharmony_ci 68438c2ecf20Sopenharmony_cierror: 68448c2ecf20Sopenharmony_ci pr_err("not found\n"); 68458c2ecf20Sopenharmony_ci kfree(state); 68468c2ecf20Sopenharmony_ci return NULL; 68478c2ecf20Sopenharmony_ci} 68488c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(drxk_attach); 68498c2ecf20Sopenharmony_ci 68508c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("DRX-K driver"); 68518c2ecf20Sopenharmony_ciMODULE_AUTHOR("Ralph Metzler"); 68528c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 6853