189ee7f4fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29a0bf528SMauro Carvalho Chehab /*
39a0bf528SMauro Carvalho Chehab * drxk_hard: DRX-K DVB-C/T demodulator driver
49a0bf528SMauro Carvalho Chehab *
59a0bf528SMauro Carvalho Chehab * Copyright (C) 2010-2011 Digital Devices GmbH
69a0bf528SMauro Carvalho Chehab */
79a0bf528SMauro Carvalho Chehab
83a4398f5SMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
93a4398f5SMauro Carvalho Chehab
109a0bf528SMauro Carvalho Chehab #include <linux/kernel.h>
119a0bf528SMauro Carvalho Chehab #include <linux/module.h>
129a0bf528SMauro Carvalho Chehab #include <linux/moduleparam.h>
139a0bf528SMauro Carvalho Chehab #include <linux/init.h>
149a0bf528SMauro Carvalho Chehab #include <linux/delay.h>
159a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
169a0bf528SMauro Carvalho Chehab #include <linux/i2c.h>
179a0bf528SMauro Carvalho Chehab #include <linux/hardirq.h>
189a0bf528SMauro Carvalho Chehab #include <asm/div64.h>
199a0bf528SMauro Carvalho Chehab
20fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
219a0bf528SMauro Carvalho Chehab #include "drxk.h"
229a0bf528SMauro Carvalho Chehab #include "drxk_hard.h"
23f97fa3dcSAndy Shevchenko #include <linux/int_log.h>
249a0bf528SMauro Carvalho Chehab
25cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
26cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state);
27cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
28cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode);
29cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
30cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode);
31cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
32cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset);
33cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
34cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode);
35cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state);
36cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
37cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset);
38cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
39cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
40cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state);
41cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state);
429a0bf528SMauro Carvalho Chehab
is_dvbt(struct drxk_state * state)43cd7a67a4SMauro Carvalho Chehab static bool is_dvbt(struct drxk_state *state)
449a0bf528SMauro Carvalho Chehab {
45cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_DVBT;
469a0bf528SMauro Carvalho Chehab }
479a0bf528SMauro Carvalho Chehab
is_qam(struct drxk_state * state)48cd7a67a4SMauro Carvalho Chehab static bool is_qam(struct drxk_state *state)
499a0bf528SMauro Carvalho Chehab {
50cd7a67a4SMauro Carvalho Chehab return state->m_operation_mode == OM_QAM_ITU_A ||
51cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_B ||
52cd7a67a4SMauro Carvalho Chehab state->m_operation_mode == OM_QAM_ITU_C;
539a0bf528SMauro Carvalho Chehab }
549a0bf528SMauro Carvalho Chehab
559a0bf528SMauro Carvalho Chehab #define NOA1ROM 0
569a0bf528SMauro Carvalho Chehab
579a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
589a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
599a0bf528SMauro Carvalho Chehab
609a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_83 165
619a0bf528SMauro Carvalho Chehab #define DEFAULT_MER_93 250
629a0bf528SMauro Carvalho Chehab
639a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
649a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
659a0bf528SMauro Carvalho Chehab #endif
669a0bf528SMauro Carvalho Chehab
679a0bf528SMauro Carvalho Chehab #ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
689a0bf528SMauro Carvalho Chehab #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
699a0bf528SMauro Carvalho Chehab #endif
709a0bf528SMauro Carvalho Chehab
719a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
729a0bf528SMauro Carvalho Chehab #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
739a0bf528SMauro Carvalho Chehab
749a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_ATV
759a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_ATV 4
769a0bf528SMauro Carvalho Chehab #endif
779a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_ATV
789a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_ATV 6
799a0bf528SMauro Carvalho Chehab #endif
809a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_ATV
819a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_ATV 7
829a0bf528SMauro Carvalho Chehab #endif
839a0bf528SMauro Carvalho Chehab
849a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_QAM
859a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_QAM 3
869a0bf528SMauro Carvalho Chehab #endif
879a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_QAM
889a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_QAM 4
899a0bf528SMauro Carvalho Chehab #endif
909a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_QAM
919a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_QAM 7
929a0bf528SMauro Carvalho Chehab #endif
939a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_RAGC_DVBT
949a0bf528SMauro Carvalho Chehab #define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
959a0bf528SMauro Carvalho Chehab #endif
969a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_IAGC_DVBT
979a0bf528SMauro Carvalho Chehab #define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
989a0bf528SMauro Carvalho Chehab #endif
999a0bf528SMauro Carvalho Chehab #ifndef DRXK_KI_DAGC_DVBT
1009a0bf528SMauro Carvalho Chehab #define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
1019a0bf528SMauro Carvalho Chehab #endif
1029a0bf528SMauro Carvalho Chehab
1039a0bf528SMauro Carvalho Chehab #ifndef DRXK_AGC_DAC_OFFSET
1049a0bf528SMauro Carvalho Chehab #define DRXK_AGC_DAC_OFFSET (0x800)
1059a0bf528SMauro Carvalho Chehab #endif
1069a0bf528SMauro Carvalho Chehab
1079a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
1089a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
1099a0bf528SMauro Carvalho Chehab #endif
1109a0bf528SMauro Carvalho Chehab
1119a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
1129a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
1139a0bf528SMauro Carvalho Chehab #endif
1149a0bf528SMauro Carvalho Chehab
1159a0bf528SMauro Carvalho Chehab #ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
1169a0bf528SMauro Carvalho Chehab #define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
1179a0bf528SMauro Carvalho Chehab #endif
1189a0bf528SMauro Carvalho Chehab
1199a0bf528SMauro Carvalho Chehab #ifndef DRXK_QAM_SYMBOLRATE_MAX
1209a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SYMBOLRATE_MAX (7233000)
1219a0bf528SMauro Carvalho Chehab #endif
1229a0bf528SMauro Carvalho Chehab
1239a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
1249a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
1259a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
1269a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_BG 24
1279a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
1289a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
1299a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_TAPS_FM 48
1309a0bf528SMauro Carvalho Chehab #define DRXK_BL_ROM_OFFSET_UCODE 0
1319a0bf528SMauro Carvalho Chehab
1329a0bf528SMauro Carvalho Chehab #define DRXK_BLC_TIMEOUT 100
1339a0bf528SMauro Carvalho Chehab
1349a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_TAPS 2
1359a0bf528SMauro Carvalho Chehab #define DRXK_BLCC_NR_ELEMENTS_UCODE 6
1369a0bf528SMauro Carvalho Chehab
1379a0bf528SMauro Carvalho Chehab #define DRXK_BLDC_NR_ELEMENTS_TAPS 28
1389a0bf528SMauro Carvalho Chehab
1399a0bf528SMauro Carvalho Chehab #ifndef DRXK_OFDM_NE_NOTCH_WIDTH
1409a0bf528SMauro Carvalho Chehab #define DRXK_OFDM_NE_NOTCH_WIDTH (4)
1419a0bf528SMauro Carvalho Chehab #endif
1429a0bf528SMauro Carvalho Chehab
1439a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
1449a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
1459a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
1469a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
1479a0bf528SMauro Carvalho Chehab #define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
1489a0bf528SMauro Carvalho Chehab
1499a0bf528SMauro Carvalho Chehab static unsigned int debug;
1509a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644);
1519a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "enable debug messages");
1529a0bf528SMauro Carvalho Chehab
1539a0bf528SMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do { \
1549a0bf528SMauro Carvalho Chehab if (debug >= level) \
15552ee29feSMauro Carvalho Chehab printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \
1569a0bf528SMauro Carvalho Chehab } while (0)
1579a0bf528SMauro Carvalho Chehab
Frac28a(u32 a,u32 c)158ff38c216SMauro Carvalho Chehab static inline u32 Frac28a(u32 a, u32 c)
1599a0bf528SMauro Carvalho Chehab {
1609a0bf528SMauro Carvalho Chehab int i = 0;
1619a0bf528SMauro Carvalho Chehab u32 Q1 = 0;
1629a0bf528SMauro Carvalho Chehab u32 R0 = 0;
1639a0bf528SMauro Carvalho Chehab
1649a0bf528SMauro Carvalho Chehab R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
165ab5060cdSMauro Carvalho Chehab Q1 = a / c; /*
166ab5060cdSMauro Carvalho Chehab * integer part, only the 4 least significant
167ab5060cdSMauro Carvalho Chehab * bits will be visible in the result
168ab5060cdSMauro Carvalho Chehab */
1699a0bf528SMauro Carvalho Chehab
1709a0bf528SMauro Carvalho Chehab /* division using radix 16, 7 nibbles in the result */
1719a0bf528SMauro Carvalho Chehab for (i = 0; i < 7; i++) {
1729a0bf528SMauro Carvalho Chehab Q1 = (Q1 << 4) | (R0 / c);
1739a0bf528SMauro Carvalho Chehab R0 = (R0 % c) << 4;
1749a0bf528SMauro Carvalho Chehab }
1759a0bf528SMauro Carvalho Chehab /* rounding */
1769a0bf528SMauro Carvalho Chehab if ((R0 >> 3) >= c)
1779a0bf528SMauro Carvalho Chehab Q1++;
1789a0bf528SMauro Carvalho Chehab
1799a0bf528SMauro Carvalho Chehab return Q1;
1809a0bf528SMauro Carvalho Chehab }
1819a0bf528SMauro Carvalho Chehab
log10times100(u32 value)182b5e9eb6fSMauro Carvalho Chehab static inline u32 log10times100(u32 value)
1839a0bf528SMauro Carvalho Chehab {
184b5e9eb6fSMauro Carvalho Chehab return (100L * intlog10(value)) >> 24;
1859a0bf528SMauro Carvalho Chehab }
1869a0bf528SMauro Carvalho Chehab
18734eb9751SMauro Carvalho Chehab /***************************************************************************/
1889a0bf528SMauro Carvalho Chehab /* I2C **********************************************************************/
18934eb9751SMauro Carvalho Chehab /***************************************************************************/
1909a0bf528SMauro Carvalho Chehab
drxk_i2c_lock(struct drxk_state * state)1919a0bf528SMauro Carvalho Chehab static int drxk_i2c_lock(struct drxk_state *state)
1929a0bf528SMauro Carvalho Chehab {
193c060a9feSPeter Rosin i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
1949a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = true;
1959a0bf528SMauro Carvalho Chehab
1969a0bf528SMauro Carvalho Chehab return 0;
1979a0bf528SMauro Carvalho Chehab }
1989a0bf528SMauro Carvalho Chehab
drxk_i2c_unlock(struct drxk_state * state)1999a0bf528SMauro Carvalho Chehab static void drxk_i2c_unlock(struct drxk_state *state)
2009a0bf528SMauro Carvalho Chehab {
2019a0bf528SMauro Carvalho Chehab if (!state->drxk_i2c_exclusive_lock)
2029a0bf528SMauro Carvalho Chehab return;
2039a0bf528SMauro Carvalho Chehab
204c060a9feSPeter Rosin i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
2059a0bf528SMauro Carvalho Chehab state->drxk_i2c_exclusive_lock = false;
2069a0bf528SMauro Carvalho Chehab }
2079a0bf528SMauro Carvalho Chehab
drxk_i2c_transfer(struct drxk_state * state,struct i2c_msg * msgs,unsigned len)2089a0bf528SMauro Carvalho Chehab static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
2099a0bf528SMauro Carvalho Chehab unsigned len)
2109a0bf528SMauro Carvalho Chehab {
2119a0bf528SMauro Carvalho Chehab if (state->drxk_i2c_exclusive_lock)
2129a0bf528SMauro Carvalho Chehab return __i2c_transfer(state->i2c, msgs, len);
2139a0bf528SMauro Carvalho Chehab else
2149a0bf528SMauro Carvalho Chehab return i2c_transfer(state->i2c, msgs, len);
2159a0bf528SMauro Carvalho Chehab }
2169a0bf528SMauro Carvalho Chehab
i2c_read1(struct drxk_state * state,u8 adr,u8 * val)2179a0bf528SMauro Carvalho Chehab static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
2189a0bf528SMauro Carvalho Chehab {
2199a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
2209a0bf528SMauro Carvalho Chehab .buf = val, .len = 1}
2219a0bf528SMauro Carvalho Chehab };
2229a0bf528SMauro Carvalho Chehab
2239a0bf528SMauro Carvalho Chehab return drxk_i2c_transfer(state, msgs, 1);
2249a0bf528SMauro Carvalho Chehab }
2259a0bf528SMauro Carvalho Chehab
i2c_write(struct drxk_state * state,u8 adr,u8 * data,int len)2269a0bf528SMauro Carvalho Chehab static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
2279a0bf528SMauro Carvalho Chehab {
2289a0bf528SMauro Carvalho Chehab int status;
2299a0bf528SMauro Carvalho Chehab struct i2c_msg msg = {
2309a0bf528SMauro Carvalho Chehab .addr = adr, .flags = 0, .buf = data, .len = len };
2319a0bf528SMauro Carvalho Chehab
23278e9ab0fSAndy Shevchenko dprintk(3, ": %*ph\n", len, data);
23378e9ab0fSAndy Shevchenko
2349a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, &msg, 1);
2359a0bf528SMauro Carvalho Chehab if (status >= 0 && status != 1)
2369a0bf528SMauro Carvalho Chehab status = -EIO;
2379a0bf528SMauro Carvalho Chehab
2389a0bf528SMauro Carvalho Chehab if (status < 0)
2393a4398f5SMauro Carvalho Chehab pr_err("i2c write error at addr 0x%02x\n", adr);
2409a0bf528SMauro Carvalho Chehab
2419a0bf528SMauro Carvalho Chehab return status;
2429a0bf528SMauro Carvalho Chehab }
2439a0bf528SMauro Carvalho Chehab
i2c_read(struct drxk_state * state,u8 adr,u8 * msg,int len,u8 * answ,int alen)2449a0bf528SMauro Carvalho Chehab static int i2c_read(struct drxk_state *state,
2459a0bf528SMauro Carvalho Chehab u8 adr, u8 *msg, int len, u8 *answ, int alen)
2469a0bf528SMauro Carvalho Chehab {
2479a0bf528SMauro Carvalho Chehab int status;
2489a0bf528SMauro Carvalho Chehab struct i2c_msg msgs[2] = {
2499a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = 0,
2509a0bf528SMauro Carvalho Chehab .buf = msg, .len = len},
2519a0bf528SMauro Carvalho Chehab {.addr = adr, .flags = I2C_M_RD,
2529a0bf528SMauro Carvalho Chehab .buf = answ, .len = alen}
2539a0bf528SMauro Carvalho Chehab };
2549a0bf528SMauro Carvalho Chehab
2559a0bf528SMauro Carvalho Chehab status = drxk_i2c_transfer(state, msgs, 2);
2569a0bf528SMauro Carvalho Chehab if (status != 2) {
2579a0bf528SMauro Carvalho Chehab if (debug > 2)
2580fb220f2SMauro Carvalho Chehab pr_cont(": ERROR!\n");
2599a0bf528SMauro Carvalho Chehab if (status >= 0)
2609a0bf528SMauro Carvalho Chehab status = -EIO;
2619a0bf528SMauro Carvalho Chehab
2623a4398f5SMauro Carvalho Chehab pr_err("i2c read error at addr 0x%02x\n", adr);
2639a0bf528SMauro Carvalho Chehab return status;
2649a0bf528SMauro Carvalho Chehab }
26578e9ab0fSAndy Shevchenko dprintk(3, ": read from %*ph, value = %*ph\n", len, msg, alen, answ);
2669a0bf528SMauro Carvalho Chehab return 0;
2679a0bf528SMauro Carvalho Chehab }
2689a0bf528SMauro Carvalho Chehab
read16_flags(struct drxk_state * state,u32 reg,u16 * data,u8 flags)2699a0bf528SMauro Carvalho Chehab static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
2709a0bf528SMauro Carvalho Chehab {
2719a0bf528SMauro Carvalho Chehab int status;
2729a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[2], len;
2739a0bf528SMauro Carvalho Chehab
2749a0bf528SMauro Carvalho Chehab if (state->single_master)
2759a0bf528SMauro Carvalho Chehab flags |= 0xC0;
2769a0bf528SMauro Carvalho Chehab
2779a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
2789a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01);
2799a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF);
2809a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags;
2819a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF);
2829a0bf528SMauro Carvalho Chehab len = 4;
2839a0bf528SMauro Carvalho Chehab } else {
2849a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF);
2859a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
2869a0bf528SMauro Carvalho Chehab len = 2;
2879a0bf528SMauro Carvalho Chehab }
2889a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
2899a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 2);
2909a0bf528SMauro Carvalho Chehab if (status < 0)
2919a0bf528SMauro Carvalho Chehab return status;
2929a0bf528SMauro Carvalho Chehab if (data)
2939a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8);
2949a0bf528SMauro Carvalho Chehab
2959a0bf528SMauro Carvalho Chehab return 0;
2969a0bf528SMauro Carvalho Chehab }
2979a0bf528SMauro Carvalho Chehab
read16(struct drxk_state * state,u32 reg,u16 * data)2989a0bf528SMauro Carvalho Chehab static int read16(struct drxk_state *state, u32 reg, u16 *data)
2999a0bf528SMauro Carvalho Chehab {
3009a0bf528SMauro Carvalho Chehab return read16_flags(state, reg, data, 0);
3019a0bf528SMauro Carvalho Chehab }
3029a0bf528SMauro Carvalho Chehab
read32_flags(struct drxk_state * state,u32 reg,u32 * data,u8 flags)3039a0bf528SMauro Carvalho Chehab static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
3049a0bf528SMauro Carvalho Chehab {
3059a0bf528SMauro Carvalho Chehab int status;
3069a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm1[4], mm2[4], len;
3079a0bf528SMauro Carvalho Chehab
3089a0bf528SMauro Carvalho Chehab if (state->single_master)
3099a0bf528SMauro Carvalho Chehab flags |= 0xC0;
3109a0bf528SMauro Carvalho Chehab
3119a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3129a0bf528SMauro Carvalho Chehab mm1[0] = (((reg << 1) & 0xFF) | 0x01);
3139a0bf528SMauro Carvalho Chehab mm1[1] = ((reg >> 16) & 0xFF);
3149a0bf528SMauro Carvalho Chehab mm1[2] = ((reg >> 24) & 0xFF) | flags;
3159a0bf528SMauro Carvalho Chehab mm1[3] = ((reg >> 7) & 0xFF);
3169a0bf528SMauro Carvalho Chehab len = 4;
3179a0bf528SMauro Carvalho Chehab } else {
3189a0bf528SMauro Carvalho Chehab mm1[0] = ((reg << 1) & 0xFF);
3199a0bf528SMauro Carvalho Chehab mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3209a0bf528SMauro Carvalho Chehab len = 2;
3219a0bf528SMauro Carvalho Chehab }
3229a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
3239a0bf528SMauro Carvalho Chehab status = i2c_read(state, adr, mm1, len, mm2, 4);
3249a0bf528SMauro Carvalho Chehab if (status < 0)
3259a0bf528SMauro Carvalho Chehab return status;
3269a0bf528SMauro Carvalho Chehab if (data)
3279a0bf528SMauro Carvalho Chehab *data = mm2[0] | (mm2[1] << 8) |
3289a0bf528SMauro Carvalho Chehab (mm2[2] << 16) | (mm2[3] << 24);
3299a0bf528SMauro Carvalho Chehab
3309a0bf528SMauro Carvalho Chehab return 0;
3319a0bf528SMauro Carvalho Chehab }
3329a0bf528SMauro Carvalho Chehab
read32(struct drxk_state * state,u32 reg,u32 * data)3339a0bf528SMauro Carvalho Chehab static int read32(struct drxk_state *state, u32 reg, u32 *data)
3349a0bf528SMauro Carvalho Chehab {
3359a0bf528SMauro Carvalho Chehab return read32_flags(state, reg, data, 0);
3369a0bf528SMauro Carvalho Chehab }
3379a0bf528SMauro Carvalho Chehab
write16_flags(struct drxk_state * state,u32 reg,u16 data,u8 flags)3389a0bf528SMauro Carvalho Chehab static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
3399a0bf528SMauro Carvalho Chehab {
3409a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[6], len;
3419a0bf528SMauro Carvalho Chehab
3429a0bf528SMauro Carvalho Chehab if (state->single_master)
3439a0bf528SMauro Carvalho Chehab flags |= 0xC0;
3449a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3459a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01);
3469a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF);
3479a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags;
3489a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF);
3499a0bf528SMauro Carvalho Chehab len = 4;
3509a0bf528SMauro Carvalho Chehab } else {
3519a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF);
3529a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3539a0bf528SMauro Carvalho Chehab len = 2;
3549a0bf528SMauro Carvalho Chehab }
3559a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff;
3569a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff;
3579a0bf528SMauro Carvalho Chehab
3589a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
3599a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 2);
3609a0bf528SMauro Carvalho Chehab }
3619a0bf528SMauro Carvalho Chehab
write16(struct drxk_state * state,u32 reg,u16 data)3629a0bf528SMauro Carvalho Chehab static int write16(struct drxk_state *state, u32 reg, u16 data)
3639a0bf528SMauro Carvalho Chehab {
3649a0bf528SMauro Carvalho Chehab return write16_flags(state, reg, data, 0);
3659a0bf528SMauro Carvalho Chehab }
3669a0bf528SMauro Carvalho Chehab
write32_flags(struct drxk_state * state,u32 reg,u32 data,u8 flags)3679a0bf528SMauro Carvalho Chehab static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
3689a0bf528SMauro Carvalho Chehab {
3699a0bf528SMauro Carvalho Chehab u8 adr = state->demod_address, mm[8], len;
3709a0bf528SMauro Carvalho Chehab
3719a0bf528SMauro Carvalho Chehab if (state->single_master)
3729a0bf528SMauro Carvalho Chehab flags |= 0xC0;
3739a0bf528SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
3749a0bf528SMauro Carvalho Chehab mm[0] = (((reg << 1) & 0xFF) | 0x01);
3759a0bf528SMauro Carvalho Chehab mm[1] = ((reg >> 16) & 0xFF);
3769a0bf528SMauro Carvalho Chehab mm[2] = ((reg >> 24) & 0xFF) | flags;
3779a0bf528SMauro Carvalho Chehab mm[3] = ((reg >> 7) & 0xFF);
3789a0bf528SMauro Carvalho Chehab len = 4;
3799a0bf528SMauro Carvalho Chehab } else {
3809a0bf528SMauro Carvalho Chehab mm[0] = ((reg << 1) & 0xFF);
3819a0bf528SMauro Carvalho Chehab mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
3829a0bf528SMauro Carvalho Chehab len = 2;
3839a0bf528SMauro Carvalho Chehab }
3849a0bf528SMauro Carvalho Chehab mm[len] = data & 0xff;
3859a0bf528SMauro Carvalho Chehab mm[len + 1] = (data >> 8) & 0xff;
3869a0bf528SMauro Carvalho Chehab mm[len + 2] = (data >> 16) & 0xff;
3879a0bf528SMauro Carvalho Chehab mm[len + 3] = (data >> 24) & 0xff;
3889a0bf528SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
3899a0bf528SMauro Carvalho Chehab
3909a0bf528SMauro Carvalho Chehab return i2c_write(state, adr, mm, len + 4);
3919a0bf528SMauro Carvalho Chehab }
3929a0bf528SMauro Carvalho Chehab
write32(struct drxk_state * state,u32 reg,u32 data)3939a0bf528SMauro Carvalho Chehab static int write32(struct drxk_state *state, u32 reg, u32 data)
3949a0bf528SMauro Carvalho Chehab {
3959a0bf528SMauro Carvalho Chehab return write32_flags(state, reg, data, 0);
3969a0bf528SMauro Carvalho Chehab }
3979a0bf528SMauro Carvalho Chehab
write_block(struct drxk_state * state,u32 address,const int block_size,const u8 p_block[])398cd7a67a4SMauro Carvalho Chehab static int write_block(struct drxk_state *state, u32 address,
399cd7a67a4SMauro Carvalho Chehab const int block_size, const u8 p_block[])
4009a0bf528SMauro Carvalho Chehab {
401cd7a67a4SMauro Carvalho Chehab int status = 0, blk_size = block_size;
402cd7a67a4SMauro Carvalho Chehab u8 flags = 0;
4039a0bf528SMauro Carvalho Chehab
4049a0bf528SMauro Carvalho Chehab if (state->single_master)
405cd7a67a4SMauro Carvalho Chehab flags |= 0xC0;
4069a0bf528SMauro Carvalho Chehab
407cd7a67a4SMauro Carvalho Chehab while (blk_size > 0) {
408cd7a67a4SMauro Carvalho Chehab int chunk = blk_size > state->m_chunk_size ?
409cd7a67a4SMauro Carvalho Chehab state->m_chunk_size : blk_size;
410cd7a67a4SMauro Carvalho Chehab u8 *adr_buf = &state->chunk[0];
411cd7a67a4SMauro Carvalho Chehab u32 adr_length = 0;
4129a0bf528SMauro Carvalho Chehab
413cd7a67a4SMauro Carvalho Chehab if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
414cd7a67a4SMauro Carvalho Chehab adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
415cd7a67a4SMauro Carvalho Chehab adr_buf[1] = ((address >> 16) & 0xFF);
416cd7a67a4SMauro Carvalho Chehab adr_buf[2] = ((address >> 24) & 0xFF);
417cd7a67a4SMauro Carvalho Chehab adr_buf[3] = ((address >> 7) & 0xFF);
418cd7a67a4SMauro Carvalho Chehab adr_buf[2] |= flags;
419cd7a67a4SMauro Carvalho Chehab adr_length = 4;
420cd7a67a4SMauro Carvalho Chehab if (chunk == state->m_chunk_size)
421cd7a67a4SMauro Carvalho Chehab chunk -= 2;
4229a0bf528SMauro Carvalho Chehab } else {
423cd7a67a4SMauro Carvalho Chehab adr_buf[0] = ((address << 1) & 0xFF);
424cd7a67a4SMauro Carvalho Chehab adr_buf[1] = (((address >> 16) & 0x0F) |
425cd7a67a4SMauro Carvalho Chehab ((address >> 18) & 0xF0));
426cd7a67a4SMauro Carvalho Chehab adr_length = 2;
4279a0bf528SMauro Carvalho Chehab }
428cd7a67a4SMauro Carvalho Chehab memcpy(&state->chunk[adr_length], p_block, chunk);
429cd7a67a4SMauro Carvalho Chehab dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
430cd7a67a4SMauro Carvalho Chehab if (p_block)
43178e9ab0fSAndy Shevchenko dprintk(2, "%*ph\n", chunk, p_block);
4329a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address,
433cd7a67a4SMauro Carvalho Chehab &state->chunk[0], chunk + adr_length);
4349a0bf528SMauro Carvalho Chehab if (status < 0) {
4353a4398f5SMauro Carvalho Chehab pr_err("%s: i2c write error at addr 0x%02x\n",
436cd7a67a4SMauro Carvalho Chehab __func__, address);
4379a0bf528SMauro Carvalho Chehab break;
4389a0bf528SMauro Carvalho Chehab }
439cd7a67a4SMauro Carvalho Chehab p_block += chunk;
440cd7a67a4SMauro Carvalho Chehab address += (chunk >> 1);
441cd7a67a4SMauro Carvalho Chehab blk_size -= chunk;
4429a0bf528SMauro Carvalho Chehab }
4439a0bf528SMauro Carvalho Chehab return status;
4449a0bf528SMauro Carvalho Chehab }
4459a0bf528SMauro Carvalho Chehab
4469a0bf528SMauro Carvalho Chehab #ifndef DRXK_MAX_RETRIES_POWERUP
4479a0bf528SMauro Carvalho Chehab #define DRXK_MAX_RETRIES_POWERUP 20
4489a0bf528SMauro Carvalho Chehab #endif
4499a0bf528SMauro Carvalho Chehab
power_up_device(struct drxk_state * state)450cd7a67a4SMauro Carvalho Chehab static int power_up_device(struct drxk_state *state)
4519a0bf528SMauro Carvalho Chehab {
4529a0bf528SMauro Carvalho Chehab int status;
4539a0bf528SMauro Carvalho Chehab u8 data = 0;
454cd7a67a4SMauro Carvalho Chehab u16 retry_count = 0;
4559a0bf528SMauro Carvalho Chehab
4569a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
4579a0bf528SMauro Carvalho Chehab
4589a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address, &data);
4599a0bf528SMauro Carvalho Chehab if (status < 0) {
4609a0bf528SMauro Carvalho Chehab do {
4619a0bf528SMauro Carvalho Chehab data = 0;
4629a0bf528SMauro Carvalho Chehab status = i2c_write(state, state->demod_address,
4639a0bf528SMauro Carvalho Chehab &data, 1);
464b72852baSMauro Carvalho Chehab usleep_range(10000, 11000);
465cd7a67a4SMauro Carvalho Chehab retry_count++;
4669a0bf528SMauro Carvalho Chehab if (status < 0)
4679a0bf528SMauro Carvalho Chehab continue;
4689a0bf528SMauro Carvalho Chehab status = i2c_read1(state, state->demod_address,
4699a0bf528SMauro Carvalho Chehab &data);
4709a0bf528SMauro Carvalho Chehab } while (status < 0 &&
471cd7a67a4SMauro Carvalho Chehab (retry_count < DRXK_MAX_RETRIES_POWERUP));
472cd7a67a4SMauro Carvalho Chehab if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
4739a0bf528SMauro Carvalho Chehab goto error;
4749a0bf528SMauro Carvalho Chehab }
4759a0bf528SMauro Carvalho Chehab
4769a0bf528SMauro Carvalho Chehab /* Make sure all clk domains are active */
4779a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
4789a0bf528SMauro Carvalho Chehab if (status < 0)
4799a0bf528SMauro Carvalho Chehab goto error;
4809a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
4819a0bf528SMauro Carvalho Chehab if (status < 0)
4829a0bf528SMauro Carvalho Chehab goto error;
4839a0bf528SMauro Carvalho Chehab /* Enable pll lock tests */
4849a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_PLL_LOCK__A, 1);
4859a0bf528SMauro Carvalho Chehab if (status < 0)
4869a0bf528SMauro Carvalho Chehab goto error;
4879a0bf528SMauro Carvalho Chehab
488cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_UP;
4899a0bf528SMauro Carvalho Chehab
4909a0bf528SMauro Carvalho Chehab error:
4919a0bf528SMauro Carvalho Chehab if (status < 0)
4923a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
4939a0bf528SMauro Carvalho Chehab
4949a0bf528SMauro Carvalho Chehab return status;
4959a0bf528SMauro Carvalho Chehab }
4969a0bf528SMauro Carvalho Chehab
4979a0bf528SMauro Carvalho Chehab
init_state(struct drxk_state * state)4989a0bf528SMauro Carvalho Chehab static int init_state(struct drxk_state *state)
4999a0bf528SMauro Carvalho Chehab {
5009a0bf528SMauro Carvalho Chehab /*
5015a13e40bSMauro Carvalho Chehab * FIXME: most (all?) of the values below should be moved into
5029a0bf528SMauro Carvalho Chehab * struct drxk_config, as they are probably board-specific
5039a0bf528SMauro Carvalho Chehab */
504cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
505cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_output_level = 0;
506cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_min_level = 0;
507cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_max_level = 0x7FFF;
508cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_if_agc_speed = 3;
5099a0bf528SMauro Carvalho Chehab
510cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
511cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_output_level = 0;
512cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_min_level = 0;
513cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_max_level = 0x7FFF;
514cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_speed = 3;
515cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_top = 9500;
516cd7a67a4SMauro Carvalho Chehab u32 ul_vsb_rf_agc_cut_off_current = 4000;
5179a0bf528SMauro Carvalho Chehab
518cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
519cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_output_level = 0;
520cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_min_level = 0;
521cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_max_level = 0;
522cd7a67a4SMauro Carvalho Chehab u32 ul_atv_if_agc_speed = 3;
5239a0bf528SMauro Carvalho Chehab
524cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
525cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_output_level = 0;
526cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_min_level = 0;
527cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_max_level = 0;
528cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_top = 9500;
529cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_cut_off_current = 4000;
530cd7a67a4SMauro Carvalho Chehab u32 ul_atv_rf_agc_speed = 3;
5319a0bf528SMauro Carvalho Chehab
5329a0bf528SMauro Carvalho Chehab u32 ulQual83 = DEFAULT_MER_83;
5339a0bf528SMauro Carvalho Chehab u32 ulQual93 = DEFAULT_MER_93;
5349a0bf528SMauro Carvalho Chehab
535cd7a67a4SMauro Carvalho Chehab u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
536cd7a67a4SMauro Carvalho Chehab u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
5379a0bf528SMauro Carvalho Chehab
5389a0bf528SMauro Carvalho Chehab /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
5399a0bf528SMauro Carvalho Chehab /* io_pad_cfg_mode output mode is drive always */
5409a0bf528SMauro Carvalho Chehab /* io_pad_cfg_drive is set to power 2 (23 mA) */
541cd7a67a4SMauro Carvalho Chehab u32 ul_gpio_cfg = 0x0113;
542cd7a67a4SMauro Carvalho Chehab u32 ul_invert_ts_clock = 0;
543cd7a67a4SMauro Carvalho Chehab u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
544cd7a67a4SMauro Carvalho Chehab u32 ul_dvbt_bitrate = 50000000;
545cd7a67a4SMauro Carvalho Chehab u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
5469a0bf528SMauro Carvalho Chehab
547cd7a67a4SMauro Carvalho Chehab u32 ul_insert_rs_byte = 0;
5489a0bf528SMauro Carvalho Chehab
549cd7a67a4SMauro Carvalho Chehab u32 ul_rf_mirror = 1;
550cd7a67a4SMauro Carvalho Chehab u32 ul_power_down = 0;
5519a0bf528SMauro Carvalho Chehab
5529a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
5539a0bf528SMauro Carvalho Chehab
554cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
555cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = false;
556cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false;
557cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false;
558cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
559cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false;
5609a0bf528SMauro Carvalho Chehab
561cd7a67a4SMauro Carvalho Chehab if (!state->m_chunk_size)
562cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = 124;
5639a0bf528SMauro Carvalho Chehab
564cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 0;
565cd7a67a4SMauro Carvalho Chehab state->m_smart_ant_inverted = false;
566cd7a67a4SMauro Carvalho Chehab state->m_b_p_down_open_bridge = false;
5679a0bf528SMauro Carvalho Chehab
5689a0bf528SMauro Carvalho Chehab /* real system clock frequency in kHz */
569cd7a67a4SMauro Carvalho Chehab state->m_sys_clock_freq = 151875;
5709a0bf528SMauro Carvalho Chehab /* Timing div, 250ns/Psys */
5719a0bf528SMauro Carvalho Chehab /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
572cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
5739a0bf528SMauro Carvalho Chehab HI_I2C_DELAY) / 1000;
5749a0bf528SMauro Carvalho Chehab /* Clipping */
575cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
576cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
577cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
5789a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */
579cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
5809a0bf528SMauro Carvalho Chehab
581cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = (ul_power_down != 0);
5829a0bf528SMauro Carvalho Chehab
583cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = false;
5849a0bf528SMauro Carvalho Chehab
5859a0bf528SMauro Carvalho Chehab /* Init AGC and PGA parameters */
5869a0bf528SMauro Carvalho Chehab /* VSB IF */
587949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
588949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
589949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
590949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
591949dd08dSMauro Carvalho Chehab state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
592cd7a67a4SMauro Carvalho Chehab state->m_vsb_pga_cfg = 140;
5939a0bf528SMauro Carvalho Chehab
5949a0bf528SMauro Carvalho Chehab /* VSB RF */
595949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
596949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
597949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
598949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
599949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
600949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
601949dd08dSMauro Carvalho Chehab state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
602cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.reference = 0x07;
603cd7a67a4SMauro Carvalho Chehab state->m_vsb_pre_saw_cfg.use_pre_saw = true;
6049a0bf528SMauro Carvalho Chehab
6059a0bf528SMauro Carvalho Chehab state->m_Quality83percent = DEFAULT_MER_83;
6069a0bf528SMauro Carvalho Chehab state->m_Quality93percent = DEFAULT_MER_93;
6079a0bf528SMauro Carvalho Chehab if (ulQual93 <= 500 && ulQual83 < ulQual93) {
6089a0bf528SMauro Carvalho Chehab state->m_Quality83percent = ulQual83;
6099a0bf528SMauro Carvalho Chehab state->m_Quality93percent = ulQual93;
6109a0bf528SMauro Carvalho Chehab }
6119a0bf528SMauro Carvalho Chehab
6129a0bf528SMauro Carvalho Chehab /* ATV IF */
613949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
614949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
615949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
616949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
617949dd08dSMauro Carvalho Chehab state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
6189a0bf528SMauro Carvalho Chehab
6199a0bf528SMauro Carvalho Chehab /* ATV RF */
620949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
621949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
622949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
623949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
624949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
625949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
626949dd08dSMauro Carvalho Chehab state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
627cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.reference = 0x04;
628cd7a67a4SMauro Carvalho Chehab state->m_atv_pre_saw_cfg.use_pre_saw = true;
6299a0bf528SMauro Carvalho Chehab
6309a0bf528SMauro Carvalho Chehab
6319a0bf528SMauro Carvalho Chehab /* DVBT RF */
632cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
633cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.output_level = 0;
634cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.min_output_level = 0;
635cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
636cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.top = 0x2100;
637cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
638cd7a67a4SMauro Carvalho Chehab state->m_dvbt_rf_agc_cfg.speed = 1;
6399a0bf528SMauro Carvalho Chehab
6409a0bf528SMauro Carvalho Chehab
6419a0bf528SMauro Carvalho Chehab /* DVBT IF */
642cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
643cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.output_level = 0;
644cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.min_output_level = 0;
645cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.max_output_level = 9000;
646cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.top = 13424;
647cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.cut_off_current = 0;
648cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.speed = 3;
649cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
650cd7a67a4SMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
6519a0bf528SMauro Carvalho Chehab /* state->m_dvbtPgaCfg = 140; */
6529a0bf528SMauro Carvalho Chehab
653cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.reference = 4;
654cd7a67a4SMauro Carvalho Chehab state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
6559a0bf528SMauro Carvalho Chehab
6569a0bf528SMauro Carvalho Chehab /* QAM RF */
657cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
658cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.output_level = 0;
659cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.min_output_level = 6023;
660cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.max_output_level = 27000;
661cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.top = 0x2380;
662cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.cut_off_current = 4000;
663cd7a67a4SMauro Carvalho Chehab state->m_qam_rf_agc_cfg.speed = 3;
6649a0bf528SMauro Carvalho Chehab
6659a0bf528SMauro Carvalho Chehab /* QAM IF */
666cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
667cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.output_level = 0;
668cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.min_output_level = 0;
669cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.max_output_level = 9000;
670cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.top = 0x0511;
671cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.cut_off_current = 0;
672cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.speed = 3;
673cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
674cd7a67a4SMauro Carvalho Chehab state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
6759a0bf528SMauro Carvalho Chehab
676cd7a67a4SMauro Carvalho Chehab state->m_qam_pga_cfg = 140;
677cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.reference = 4;
678cd7a67a4SMauro Carvalho Chehab state->m_qam_pre_saw_cfg.use_pre_saw = false;
6799a0bf528SMauro Carvalho Chehab
680cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE;
681cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_UNINITIALIZED;
6829a0bf528SMauro Carvalho Chehab
6839a0bf528SMauro Carvalho Chehab /* MPEG output configuration */
684868c9a17SMauro Carvalho Chehab state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG output */
685cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */
686cd7a67a4SMauro Carvalho Chehab state->m_invert_data = false; /* If TRUE; invert DATA signals */
687cd7a67a4SMauro Carvalho Chehab state->m_invert_err = false; /* If TRUE; invert ERR signal */
688cd7a67a4SMauro Carvalho Chehab state->m_invert_str = false; /* If TRUE; invert STR signals */
689cd7a67a4SMauro Carvalho Chehab state->m_invert_val = false; /* If TRUE; invert VAL signals */
690cd7a67a4SMauro Carvalho Chehab state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */
6919a0bf528SMauro Carvalho Chehab
6929a0bf528SMauro Carvalho Chehab /* If TRUE; static MPEG clockrate will be used;
6939a0bf528SMauro Carvalho Chehab otherwise clockrate will adapt to the bitrate of the TS */
6949a0bf528SMauro Carvalho Chehab
695cd7a67a4SMauro Carvalho Chehab state->m_dvbt_bitrate = ul_dvbt_bitrate;
696cd7a67a4SMauro Carvalho Chehab state->m_dvbc_bitrate = ul_dvbc_bitrate;
6979a0bf528SMauro Carvalho Chehab
698cd7a67a4SMauro Carvalho Chehab state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
6999a0bf528SMauro Carvalho Chehab
7009a0bf528SMauro Carvalho Chehab /* Maximum bitrate in b/s in case static clockrate is selected */
701cd7a67a4SMauro Carvalho Chehab state->m_mpeg_ts_static_bitrate = 19392658;
702cd7a67a4SMauro Carvalho Chehab state->m_disable_te_ihandling = false;
7039a0bf528SMauro Carvalho Chehab
704cd7a67a4SMauro Carvalho Chehab if (ul_insert_rs_byte)
705cd7a67a4SMauro Carvalho Chehab state->m_insert_rs_byte = true;
7069a0bf528SMauro Carvalho Chehab
707cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
708cd7a67a4SMauro Carvalho Chehab if (ul_mpeg_lock_time_out < 10000)
709cd7a67a4SMauro Carvalho Chehab state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
710cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
711cd7a67a4SMauro Carvalho Chehab if (ul_demod_lock_time_out < 10000)
712cd7a67a4SMauro Carvalho Chehab state->m_demod_lock_time_out = ul_demod_lock_time_out;
7139a0bf528SMauro Carvalho Chehab
7149a0bf528SMauro Carvalho Chehab /* QAM defaults */
715cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_AUTO;
716cd7a67a4SMauro Carvalho Chehab state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
717cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */
718cd7a67a4SMauro Carvalho Chehab state->m_fec_rs_prescale = 1;
7199a0bf528SMauro Carvalho Chehab
720cd7a67a4SMauro Carvalho Chehab state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
721cd7a67a4SMauro Carvalho Chehab state->m_agcfast_clip_ctrl_delay = 0;
7229a0bf528SMauro Carvalho Chehab
723949dd08dSMauro Carvalho Chehab state->m_gpio_cfg = ul_gpio_cfg;
7249a0bf528SMauro Carvalho Chehab
725cd7a67a4SMauro Carvalho Chehab state->m_b_power_down = false;
726cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = DRX_POWER_DOWN;
7279a0bf528SMauro Carvalho Chehab
728cd7a67a4SMauro Carvalho Chehab state->m_rfmirror = (ul_rf_mirror == 0);
729cd7a67a4SMauro Carvalho Chehab state->m_if_agc_pol = false;
7309a0bf528SMauro Carvalho Chehab return 0;
7319a0bf528SMauro Carvalho Chehab }
7329a0bf528SMauro Carvalho Chehab
drxx_open(struct drxk_state * state)733cd7a67a4SMauro Carvalho Chehab static int drxx_open(struct drxk_state *state)
7349a0bf528SMauro Carvalho Chehab {
7359a0bf528SMauro Carvalho Chehab int status = 0;
7369a0bf528SMauro Carvalho Chehab u32 jtag = 0;
7379a0bf528SMauro Carvalho Chehab u16 bid = 0;
7389a0bf528SMauro Carvalho Chehab u16 key = 0;
7399a0bf528SMauro Carvalho Chehab
7409a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
7419a0bf528SMauro Carvalho Chehab /* stop lock indicator process */
742ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
743ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7449a0bf528SMauro Carvalho Chehab if (status < 0)
7459a0bf528SMauro Carvalho Chehab goto error;
7469a0bf528SMauro Carvalho Chehab /* Check device id */
7479a0bf528SMauro Carvalho Chehab status = read16(state, SIO_TOP_COMM_KEY__A, &key);
7489a0bf528SMauro Carvalho Chehab if (status < 0)
7499a0bf528SMauro Carvalho Chehab goto error;
7509a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7519a0bf528SMauro Carvalho Chehab if (status < 0)
7529a0bf528SMauro Carvalho Chehab goto error;
7539a0bf528SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
7549a0bf528SMauro Carvalho Chehab if (status < 0)
7559a0bf528SMauro Carvalho Chehab goto error;
7569a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
7579a0bf528SMauro Carvalho Chehab if (status < 0)
7589a0bf528SMauro Carvalho Chehab goto error;
7599a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, key);
7609a0bf528SMauro Carvalho Chehab error:
7619a0bf528SMauro Carvalho Chehab if (status < 0)
7623a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
7639a0bf528SMauro Carvalho Chehab return status;
7649a0bf528SMauro Carvalho Chehab }
7659a0bf528SMauro Carvalho Chehab
get_device_capabilities(struct drxk_state * state)766cd7a67a4SMauro Carvalho Chehab static int get_device_capabilities(struct drxk_state *state)
7679a0bf528SMauro Carvalho Chehab {
768cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_ohw_cfg = 0;
769cd7a67a4SMauro Carvalho Chehab u32 sio_top_jtagid_lo = 0;
7709a0bf528SMauro Carvalho Chehab int status;
7719a0bf528SMauro Carvalho Chehab const char *spin = "";
7729a0bf528SMauro Carvalho Chehab
7739a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
7749a0bf528SMauro Carvalho Chehab
7759a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */
7769a0bf528SMauro Carvalho Chehab /* stop lock indicator process */
777ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
778ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
7799a0bf528SMauro Carvalho Chehab if (status < 0)
7809a0bf528SMauro Carvalho Chehab goto error;
7818418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
7829a0bf528SMauro Carvalho Chehab if (status < 0)
7839a0bf528SMauro Carvalho Chehab goto error;
784cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
7859a0bf528SMauro Carvalho Chehab if (status < 0)
7869a0bf528SMauro Carvalho Chehab goto error;
7879a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
7889a0bf528SMauro Carvalho Chehab if (status < 0)
7899a0bf528SMauro Carvalho Chehab goto error;
7909a0bf528SMauro Carvalho Chehab
791cd7a67a4SMauro Carvalho Chehab switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
7929a0bf528SMauro Carvalho Chehab case 0:
7939a0bf528SMauro Carvalho Chehab /* ignore (bypass ?) */
7949a0bf528SMauro Carvalho Chehab break;
7959a0bf528SMauro Carvalho Chehab case 1:
7969a0bf528SMauro Carvalho Chehab /* 27 MHz */
797cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 27000;
7989a0bf528SMauro Carvalho Chehab break;
7999a0bf528SMauro Carvalho Chehab case 2:
8009a0bf528SMauro Carvalho Chehab /* 20.25 MHz */
801cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250;
8029a0bf528SMauro Carvalho Chehab break;
8039a0bf528SMauro Carvalho Chehab case 3:
8049a0bf528SMauro Carvalho Chehab /* 4 MHz */
805cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq = 20250;
8069a0bf528SMauro Carvalho Chehab break;
8079a0bf528SMauro Carvalho Chehab default:
8083a4398f5SMauro Carvalho Chehab pr_err("Clock Frequency is unknown\n");
8099a0bf528SMauro Carvalho Chehab return -EINVAL;
8109a0bf528SMauro Carvalho Chehab }
8119a0bf528SMauro Carvalho Chehab /*
8129a0bf528SMauro Carvalho Chehab Determine device capabilities
8139a0bf528SMauro Carvalho Chehab Based on pinning v14
8149a0bf528SMauro Carvalho Chehab */
815cd7a67a4SMauro Carvalho Chehab status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
8169a0bf528SMauro Carvalho Chehab if (status < 0)
8179a0bf528SMauro Carvalho Chehab goto error;
8189a0bf528SMauro Carvalho Chehab
8193a4398f5SMauro Carvalho Chehab pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
8209a0bf528SMauro Carvalho Chehab
8219a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */
822cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 29) & 0xF) {
8239a0bf528SMauro Carvalho Chehab case 0:
824cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A1;
8259a0bf528SMauro Carvalho Chehab spin = "A1";
8269a0bf528SMauro Carvalho Chehab break;
8279a0bf528SMauro Carvalho Chehab case 2:
828cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A2;
8299a0bf528SMauro Carvalho Chehab spin = "A2";
8309a0bf528SMauro Carvalho Chehab break;
8319a0bf528SMauro Carvalho Chehab case 3:
832cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_A3;
8339a0bf528SMauro Carvalho Chehab spin = "A3";
8349a0bf528SMauro Carvalho Chehab break;
8359a0bf528SMauro Carvalho Chehab default:
836cd7a67a4SMauro Carvalho Chehab state->m_device_spin = DRXK_SPIN_UNKNOWN;
8379a0bf528SMauro Carvalho Chehab status = -EINVAL;
8383a4398f5SMauro Carvalho Chehab pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
8399a0bf528SMauro Carvalho Chehab goto error2;
8409a0bf528SMauro Carvalho Chehab }
841cd7a67a4SMauro Carvalho Chehab switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
8429a0bf528SMauro Carvalho Chehab case 0x13:
8439a0bf528SMauro Carvalho Chehab /* typeId = DRX3913K_TYPE_ID */
844cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
845cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
846cd7a67a4SMauro Carvalho Chehab state->m_has_atv = false;
847cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false;
848cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
849cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true;
850cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
851cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = false;
852cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = false;
853cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
8549a0bf528SMauro Carvalho Chehab break;
8559a0bf528SMauro Carvalho Chehab case 0x15:
8569a0bf528SMauro Carvalho Chehab /* typeId = DRX3915K_TYPE_ID */
857cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
858cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
859cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
860cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false;
861cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
862cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false;
863cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
864cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
865cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
866cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
8679a0bf528SMauro Carvalho Chehab break;
8689a0bf528SMauro Carvalho Chehab case 0x16:
8699a0bf528SMauro Carvalho Chehab /* typeId = DRX3916K_TYPE_ID */
870cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
871cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
872cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
873cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false;
874cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
875cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false;
876cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
877cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
878cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
879cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
8809a0bf528SMauro Carvalho Chehab break;
8819a0bf528SMauro Carvalho Chehab case 0x18:
8829a0bf528SMauro Carvalho Chehab /* typeId = DRX3918K_TYPE_ID */
883cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
884cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
885cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
886cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true;
887cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
888cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = false;
889cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
890cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
891cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
892cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
8939a0bf528SMauro Carvalho Chehab break;
8949a0bf528SMauro Carvalho Chehab case 0x21:
8959a0bf528SMauro Carvalho Chehab /* typeId = DRX3921K_TYPE_ID */
896cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
897cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
898cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
899cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true;
900cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
901cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true;
902cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
903cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
904cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
905cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
9069a0bf528SMauro Carvalho Chehab break;
9079a0bf528SMauro Carvalho Chehab case 0x23:
9089a0bf528SMauro Carvalho Chehab /* typeId = DRX3923K_TYPE_ID */
909cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
910cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
911cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
912cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true;
913cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
914cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true;
915cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
916cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
917cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
918cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
9199a0bf528SMauro Carvalho Chehab break;
9209a0bf528SMauro Carvalho Chehab case 0x25:
9219a0bf528SMauro Carvalho Chehab /* typeId = DRX3925K_TYPE_ID */
922cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
923cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
924cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
925cd7a67a4SMauro Carvalho Chehab state->m_has_audio = true;
926cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
927cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true;
928cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
929cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
930cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
931cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
9329a0bf528SMauro Carvalho Chehab break;
9339a0bf528SMauro Carvalho Chehab case 0x26:
9349a0bf528SMauro Carvalho Chehab /* typeId = DRX3926K_TYPE_ID */
935cd7a67a4SMauro Carvalho Chehab state->m_has_lna = false;
936cd7a67a4SMauro Carvalho Chehab state->m_has_oob = false;
937cd7a67a4SMauro Carvalho Chehab state->m_has_atv = true;
938cd7a67a4SMauro Carvalho Chehab state->m_has_audio = false;
939cd7a67a4SMauro Carvalho Chehab state->m_has_dvbt = true;
940cd7a67a4SMauro Carvalho Chehab state->m_has_dvbc = true;
941cd7a67a4SMauro Carvalho Chehab state->m_has_sawsw = true;
942cd7a67a4SMauro Carvalho Chehab state->m_has_gpio2 = true;
943cd7a67a4SMauro Carvalho Chehab state->m_has_gpio1 = true;
944cd7a67a4SMauro Carvalho Chehab state->m_has_irqn = false;
9459a0bf528SMauro Carvalho Chehab break;
9469a0bf528SMauro Carvalho Chehab default:
9473a4398f5SMauro Carvalho Chehab pr_err("DeviceID 0x%02x not supported\n",
948cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF));
9499a0bf528SMauro Carvalho Chehab status = -EINVAL;
9509a0bf528SMauro Carvalho Chehab goto error2;
9519a0bf528SMauro Carvalho Chehab }
9529a0bf528SMauro Carvalho Chehab
9533a4398f5SMauro Carvalho Chehab pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
954cd7a67a4SMauro Carvalho Chehab ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
955cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq / 1000,
956cd7a67a4SMauro Carvalho Chehab state->m_osc_clock_freq % 1000);
9579a0bf528SMauro Carvalho Chehab
9589a0bf528SMauro Carvalho Chehab error:
9599a0bf528SMauro Carvalho Chehab if (status < 0)
9603a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
9619a0bf528SMauro Carvalho Chehab
9629a0bf528SMauro Carvalho Chehab error2:
9639a0bf528SMauro Carvalho Chehab return status;
9649a0bf528SMauro Carvalho Chehab }
9659a0bf528SMauro Carvalho Chehab
hi_command(struct drxk_state * state,u16 cmd,u16 * p_result)966cd7a67a4SMauro Carvalho Chehab static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
9679a0bf528SMauro Carvalho Chehab {
9689a0bf528SMauro Carvalho Chehab int status;
9699a0bf528SMauro Carvalho Chehab bool powerdown_cmd;
9709a0bf528SMauro Carvalho Chehab
9719a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
9729a0bf528SMauro Carvalho Chehab
9739a0bf528SMauro Carvalho Chehab /* Write command */
9749a0bf528SMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
9759a0bf528SMauro Carvalho Chehab if (status < 0)
9769a0bf528SMauro Carvalho Chehab goto error;
9779a0bf528SMauro Carvalho Chehab if (cmd == SIO_HI_RA_RAM_CMD_RESET)
978b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
9799a0bf528SMauro Carvalho Chehab
9809a0bf528SMauro Carvalho Chehab powerdown_cmd =
9819a0bf528SMauro Carvalho Chehab (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
982cd7a67a4SMauro Carvalho Chehab ((state->m_hi_cfg_ctrl) &
9839a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
9849a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
9855a7f7b79SMauro Carvalho Chehab if (!powerdown_cmd) {
9869a0bf528SMauro Carvalho Chehab /* Wait until command rdy */
987cd7a67a4SMauro Carvalho Chehab u32 retry_count = 0;
988cd7a67a4SMauro Carvalho Chehab u16 wait_cmd;
9899a0bf528SMauro Carvalho Chehab
9909a0bf528SMauro Carvalho Chehab do {
991b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
992cd7a67a4SMauro Carvalho Chehab retry_count += 1;
9939a0bf528SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_CMD__A,
994cd7a67a4SMauro Carvalho Chehab &wait_cmd);
995c386e079SHans Verkuil } while ((status < 0 || wait_cmd) && (retry_count < DRXK_MAX_RETRIES));
9969a0bf528SMauro Carvalho Chehab if (status < 0)
9979a0bf528SMauro Carvalho Chehab goto error;
998cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
9999a0bf528SMauro Carvalho Chehab }
10009a0bf528SMauro Carvalho Chehab error:
10019a0bf528SMauro Carvalho Chehab if (status < 0)
10023a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
10039a0bf528SMauro Carvalho Chehab
10049a0bf528SMauro Carvalho Chehab return status;
10059a0bf528SMauro Carvalho Chehab }
10069a0bf528SMauro Carvalho Chehab
hi_cfg_command(struct drxk_state * state)1007cd7a67a4SMauro Carvalho Chehab static int hi_cfg_command(struct drxk_state *state)
10089a0bf528SMauro Carvalho Chehab {
10099a0bf528SMauro Carvalho Chehab int status;
10109a0bf528SMauro Carvalho Chehab
10119a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
10129a0bf528SMauro Carvalho Chehab
10139a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex);
10149a0bf528SMauro Carvalho Chehab
1015ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
1016ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timeout);
10179a0bf528SMauro Carvalho Chehab if (status < 0)
10189a0bf528SMauro Carvalho Chehab goto error;
1019ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
1020ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_ctrl);
10219a0bf528SMauro Carvalho Chehab if (status < 0)
10229a0bf528SMauro Carvalho Chehab goto error;
1023ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
1024ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_wake_up_key);
10259a0bf528SMauro Carvalho Chehab if (status < 0)
10269a0bf528SMauro Carvalho Chehab goto error;
1027ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
1028ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_bridge_delay);
10299a0bf528SMauro Carvalho Chehab if (status < 0)
10309a0bf528SMauro Carvalho Chehab goto error;
1031ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
1032ab5060cdSMauro Carvalho Chehab state->m_hi_cfg_timing_div);
10339a0bf528SMauro Carvalho Chehab if (status < 0)
10349a0bf528SMauro Carvalho Chehab goto error;
1035ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
1036ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
10379a0bf528SMauro Carvalho Chehab if (status < 0)
10389a0bf528SMauro Carvalho Chehab goto error;
1039b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
10409a0bf528SMauro Carvalho Chehab if (status < 0)
10419a0bf528SMauro Carvalho Chehab goto error;
10429a0bf528SMauro Carvalho Chehab
1043cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
10449a0bf528SMauro Carvalho Chehab error:
10459a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex);
10469a0bf528SMauro Carvalho Chehab if (status < 0)
10473a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
10489a0bf528SMauro Carvalho Chehab return status;
10499a0bf528SMauro Carvalho Chehab }
10509a0bf528SMauro Carvalho Chehab
init_hi(struct drxk_state * state)1051cd7a67a4SMauro Carvalho Chehab static int init_hi(struct drxk_state *state)
10529a0bf528SMauro Carvalho Chehab {
10539a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
10549a0bf528SMauro Carvalho Chehab
1055cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
1056cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_timeout = 0x96FF;
10579a0bf528SMauro Carvalho Chehab /* port/bridge/power down ctrl */
1058cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
10599a0bf528SMauro Carvalho Chehab
1060cd7a67a4SMauro Carvalho Chehab return hi_cfg_command(state);
10619a0bf528SMauro Carvalho Chehab }
10629a0bf528SMauro Carvalho Chehab
mpegts_configure_pins(struct drxk_state * state,bool mpeg_enable)1063cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
10649a0bf528SMauro Carvalho Chehab {
106543c4dc3fSColin Ian King int status;
1066cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mclk_cfg = 0;
1067cd7a67a4SMauro Carvalho Chehab u16 sio_pdr_mdx_cfg = 0;
10689a0bf528SMauro Carvalho Chehab u16 err_cfg = 0;
10699a0bf528SMauro Carvalho Chehab
10709a0bf528SMauro Carvalho Chehab dprintk(1, ": mpeg %s, %s mode\n",
1071cd7a67a4SMauro Carvalho Chehab mpeg_enable ? "enable" : "disable",
1072cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel ? "parallel" : "serial");
10739a0bf528SMauro Carvalho Chehab
10749a0bf528SMauro Carvalho Chehab /* stop lock indicator process */
1075ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
1076ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
10779a0bf528SMauro Carvalho Chehab if (status < 0)
10789a0bf528SMauro Carvalho Chehab goto error;
10799a0bf528SMauro Carvalho Chehab
10809a0bf528SMauro Carvalho Chehab /* MPEG TS pad configuration */
10818418366dSMartin Blumenstingl status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
10829a0bf528SMauro Carvalho Chehab if (status < 0)
10839a0bf528SMauro Carvalho Chehab goto error;
10849a0bf528SMauro Carvalho Chehab
10855a7f7b79SMauro Carvalho Chehab if (!mpeg_enable) {
10869a0bf528SMauro Carvalho Chehab /* Set MPEG TS pads to inputmode */
10879a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
10889a0bf528SMauro Carvalho Chehab if (status < 0)
10899a0bf528SMauro Carvalho Chehab goto error;
10909a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
10919a0bf528SMauro Carvalho Chehab if (status < 0)
10929a0bf528SMauro Carvalho Chehab goto error;
10939a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
10949a0bf528SMauro Carvalho Chehab if (status < 0)
10959a0bf528SMauro Carvalho Chehab goto error;
10969a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
10979a0bf528SMauro Carvalho Chehab if (status < 0)
10989a0bf528SMauro Carvalho Chehab goto error;
10999a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
11009a0bf528SMauro Carvalho Chehab if (status < 0)
11019a0bf528SMauro Carvalho Chehab goto error;
11029a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11039a0bf528SMauro Carvalho Chehab if (status < 0)
11049a0bf528SMauro Carvalho Chehab goto error;
11059a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11069a0bf528SMauro Carvalho Chehab if (status < 0)
11079a0bf528SMauro Carvalho Chehab goto error;
11089a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11099a0bf528SMauro Carvalho Chehab if (status < 0)
11109a0bf528SMauro Carvalho Chehab goto error;
11119a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11129a0bf528SMauro Carvalho Chehab if (status < 0)
11139a0bf528SMauro Carvalho Chehab goto error;
11149a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11159a0bf528SMauro Carvalho Chehab if (status < 0)
11169a0bf528SMauro Carvalho Chehab goto error;
11179a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11189a0bf528SMauro Carvalho Chehab if (status < 0)
11199a0bf528SMauro Carvalho Chehab goto error;
11209a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
11219a0bf528SMauro Carvalho Chehab if (status < 0)
11229a0bf528SMauro Carvalho Chehab goto error;
11239a0bf528SMauro Carvalho Chehab } else {
11249a0bf528SMauro Carvalho Chehab /* Enable MPEG output */
1125cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg =
1126cd7a67a4SMauro Carvalho Chehab ((state->m_ts_data_strength <<
11279a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1128cd7a67a4SMauro Carvalho Chehab sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
11299a0bf528SMauro Carvalho Chehab SIO_PDR_MCLK_CFG_DRIVE__B) |
11309a0bf528SMauro Carvalho Chehab 0x0003);
11319a0bf528SMauro Carvalho Chehab
1132cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
11339a0bf528SMauro Carvalho Chehab if (status < 0)
11349a0bf528SMauro Carvalho Chehab goto error;
11359a0bf528SMauro Carvalho Chehab
11369a0bf528SMauro Carvalho Chehab if (state->enable_merr_cfg)
1137cd7a67a4SMauro Carvalho Chehab err_cfg = sio_pdr_mdx_cfg;
11389a0bf528SMauro Carvalho Chehab
11399a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
11409a0bf528SMauro Carvalho Chehab if (status < 0)
11419a0bf528SMauro Carvalho Chehab goto error;
11429a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
11439a0bf528SMauro Carvalho Chehab if (status < 0)
11449a0bf528SMauro Carvalho Chehab goto error;
11459a0bf528SMauro Carvalho Chehab
11465a7f7b79SMauro Carvalho Chehab if (state->m_enable_parallel) {
114739c1cb2bSJonathan McCrohan /* parallel -> enable MD1 to MD7 */
1148ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A,
1149ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11509a0bf528SMauro Carvalho Chehab if (status < 0)
11519a0bf528SMauro Carvalho Chehab goto error;
1152ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A,
1153ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11549a0bf528SMauro Carvalho Chehab if (status < 0)
11559a0bf528SMauro Carvalho Chehab goto error;
1156ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A,
1157ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11589a0bf528SMauro Carvalho Chehab if (status < 0)
11599a0bf528SMauro Carvalho Chehab goto error;
1160ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A,
1161ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11629a0bf528SMauro Carvalho Chehab if (status < 0)
11639a0bf528SMauro Carvalho Chehab goto error;
1164ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A,
1165ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11669a0bf528SMauro Carvalho Chehab if (status < 0)
11679a0bf528SMauro Carvalho Chehab goto error;
1168ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A,
1169ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11709a0bf528SMauro Carvalho Chehab if (status < 0)
11719a0bf528SMauro Carvalho Chehab goto error;
1172ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A,
1173ab5060cdSMauro Carvalho Chehab sio_pdr_mdx_cfg);
11749a0bf528SMauro Carvalho Chehab if (status < 0)
11759a0bf528SMauro Carvalho Chehab goto error;
11769a0bf528SMauro Carvalho Chehab } else {
1177cd7a67a4SMauro Carvalho Chehab sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
11789a0bf528SMauro Carvalho Chehab SIO_PDR_MD0_CFG_DRIVE__B)
11799a0bf528SMauro Carvalho Chehab | 0x0003);
11809a0bf528SMauro Carvalho Chehab /* serial -> disable MD1 to MD7 */
11819a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
11829a0bf528SMauro Carvalho Chehab if (status < 0)
11839a0bf528SMauro Carvalho Chehab goto error;
11849a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
11859a0bf528SMauro Carvalho Chehab if (status < 0)
11869a0bf528SMauro Carvalho Chehab goto error;
11879a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
11889a0bf528SMauro Carvalho Chehab if (status < 0)
11899a0bf528SMauro Carvalho Chehab goto error;
11909a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
11919a0bf528SMauro Carvalho Chehab if (status < 0)
11929a0bf528SMauro Carvalho Chehab goto error;
11939a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
11949a0bf528SMauro Carvalho Chehab if (status < 0)
11959a0bf528SMauro Carvalho Chehab goto error;
11969a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
11979a0bf528SMauro Carvalho Chehab if (status < 0)
11989a0bf528SMauro Carvalho Chehab goto error;
11999a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
12009a0bf528SMauro Carvalho Chehab if (status < 0)
12019a0bf528SMauro Carvalho Chehab goto error;
12029a0bf528SMauro Carvalho Chehab }
1203cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
12049a0bf528SMauro Carvalho Chehab if (status < 0)
12059a0bf528SMauro Carvalho Chehab goto error;
1206cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
12079a0bf528SMauro Carvalho Chehab if (status < 0)
12089a0bf528SMauro Carvalho Chehab goto error;
12099a0bf528SMauro Carvalho Chehab }
12109a0bf528SMauro Carvalho Chehab /* Enable MB output over MPEG pads and ctl input */
12119a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
12129a0bf528SMauro Carvalho Chehab if (status < 0)
12139a0bf528SMauro Carvalho Chehab goto error;
12149a0bf528SMauro Carvalho Chehab /* Write nomagic word to enable pdr reg write */
12159a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
12169a0bf528SMauro Carvalho Chehab error:
12179a0bf528SMauro Carvalho Chehab if (status < 0)
12183a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
12199a0bf528SMauro Carvalho Chehab return status;
12209a0bf528SMauro Carvalho Chehab }
12219a0bf528SMauro Carvalho Chehab
mpegts_disable(struct drxk_state * state)1222cd7a67a4SMauro Carvalho Chehab static int mpegts_disable(struct drxk_state *state)
12239a0bf528SMauro Carvalho Chehab {
12249a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
12259a0bf528SMauro Carvalho Chehab
1226cd7a67a4SMauro Carvalho Chehab return mpegts_configure_pins(state, false);
12279a0bf528SMauro Carvalho Chehab }
12289a0bf528SMauro Carvalho Chehab
bl_chain_cmd(struct drxk_state * state,u16 rom_offset,u16 nr_of_elements,u32 time_out)1229cd7a67a4SMauro Carvalho Chehab static int bl_chain_cmd(struct drxk_state *state,
1230cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out)
12319a0bf528SMauro Carvalho Chehab {
1232cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0;
12339a0bf528SMauro Carvalho Chehab int status;
12349a0bf528SMauro Carvalho Chehab unsigned long end;
12359a0bf528SMauro Carvalho Chehab
12369a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
12379a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex);
12389a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
12399a0bf528SMauro Carvalho Chehab if (status < 0)
12409a0bf528SMauro Carvalho Chehab goto error;
1241cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
12429a0bf528SMauro Carvalho Chehab if (status < 0)
12439a0bf528SMauro Carvalho Chehab goto error;
1244cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
12459a0bf528SMauro Carvalho Chehab if (status < 0)
12469a0bf528SMauro Carvalho Chehab goto error;
12479a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
12489a0bf528SMauro Carvalho Chehab if (status < 0)
12499a0bf528SMauro Carvalho Chehab goto error;
12509a0bf528SMauro Carvalho Chehab
1251cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out);
12529a0bf528SMauro Carvalho Chehab do {
1253b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
1254cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status);
12559a0bf528SMauro Carvalho Chehab if (status < 0)
12569a0bf528SMauro Carvalho Chehab goto error;
1257cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) &&
12589a0bf528SMauro Carvalho Chehab ((time_is_after_jiffies(end))));
12599a0bf528SMauro Carvalho Chehab
1260cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) {
12613a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n");
12629a0bf528SMauro Carvalho Chehab status = -EINVAL;
12639a0bf528SMauro Carvalho Chehab goto error2;
12649a0bf528SMauro Carvalho Chehab }
12659a0bf528SMauro Carvalho Chehab error:
12669a0bf528SMauro Carvalho Chehab if (status < 0)
12673a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
12689a0bf528SMauro Carvalho Chehab error2:
12699a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex);
12709a0bf528SMauro Carvalho Chehab return status;
12719a0bf528SMauro Carvalho Chehab }
12729a0bf528SMauro Carvalho Chehab
12739a0bf528SMauro Carvalho Chehab
download_microcode(struct drxk_state * state,const u8 p_mc_image[],u32 length)1274cd7a67a4SMauro Carvalho Chehab static int download_microcode(struct drxk_state *state,
1275cd7a67a4SMauro Carvalho Chehab const u8 p_mc_image[], u32 length)
12769a0bf528SMauro Carvalho Chehab {
1277cd7a67a4SMauro Carvalho Chehab const u8 *p_src = p_mc_image;
1278cd7a67a4SMauro Carvalho Chehab u32 address;
1279cd7a67a4SMauro Carvalho Chehab u16 n_blocks;
1280cd7a67a4SMauro Carvalho Chehab u16 block_size;
12819a0bf528SMauro Carvalho Chehab u32 offset = 0;
12829a0bf528SMauro Carvalho Chehab u32 i;
12839a0bf528SMauro Carvalho Chehab int status = 0;
12849a0bf528SMauro Carvalho Chehab
12859a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
12869a0bf528SMauro Carvalho Chehab
12879a0bf528SMauro Carvalho Chehab /* down the drain (we don't care about MAGIC_WORD) */
12889a0bf528SMauro Carvalho Chehab #if 0
12899a0bf528SMauro Carvalho Chehab /* For future reference */
1290cd7a67a4SMauro Carvalho Chehab drain = (p_src[0] << 8) | p_src[1];
12919a0bf528SMauro Carvalho Chehab #endif
1292cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16);
12939a0bf528SMauro Carvalho Chehab offset += sizeof(u16);
1294cd7a67a4SMauro Carvalho Chehab n_blocks = (p_src[0] << 8) | p_src[1];
1295cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16);
12969a0bf528SMauro Carvalho Chehab offset += sizeof(u16);
12979a0bf528SMauro Carvalho Chehab
1298cd7a67a4SMauro Carvalho Chehab for (i = 0; i < n_blocks; i += 1) {
1299cd7a67a4SMauro Carvalho Chehab address = (p_src[0] << 24) | (p_src[1] << 16) |
1300cd7a67a4SMauro Carvalho Chehab (p_src[2] << 8) | p_src[3];
1301cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u32);
13029a0bf528SMauro Carvalho Chehab offset += sizeof(u32);
13039a0bf528SMauro Carvalho Chehab
1304cd7a67a4SMauro Carvalho Chehab block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
1305cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16);
13069a0bf528SMauro Carvalho Chehab offset += sizeof(u16);
13079a0bf528SMauro Carvalho Chehab
13089a0bf528SMauro Carvalho Chehab #if 0
13099a0bf528SMauro Carvalho Chehab /* For future reference */
1310cd7a67a4SMauro Carvalho Chehab flags = (p_src[0] << 8) | p_src[1];
13119a0bf528SMauro Carvalho Chehab #endif
1312cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16);
13139a0bf528SMauro Carvalho Chehab offset += sizeof(u16);
13149a0bf528SMauro Carvalho Chehab
13159a0bf528SMauro Carvalho Chehab #if 0
13169a0bf528SMauro Carvalho Chehab /* For future reference */
1317cd7a67a4SMauro Carvalho Chehab block_crc = (p_src[0] << 8) | p_src[1];
13189a0bf528SMauro Carvalho Chehab #endif
1319cd7a67a4SMauro Carvalho Chehab p_src += sizeof(u16);
13209a0bf528SMauro Carvalho Chehab offset += sizeof(u16);
13219a0bf528SMauro Carvalho Chehab
1322cd7a67a4SMauro Carvalho Chehab if (offset + block_size > length) {
13233a4398f5SMauro Carvalho Chehab pr_err("Firmware is corrupted.\n");
13249a0bf528SMauro Carvalho Chehab return -EINVAL;
13259a0bf528SMauro Carvalho Chehab }
13269a0bf528SMauro Carvalho Chehab
1327cd7a67a4SMauro Carvalho Chehab status = write_block(state, address, block_size, p_src);
13289a0bf528SMauro Carvalho Chehab if (status < 0) {
13293a4398f5SMauro Carvalho Chehab pr_err("Error %d while loading firmware\n", status);
13309a0bf528SMauro Carvalho Chehab break;
13319a0bf528SMauro Carvalho Chehab }
1332cd7a67a4SMauro Carvalho Chehab p_src += block_size;
1333cd7a67a4SMauro Carvalho Chehab offset += block_size;
13349a0bf528SMauro Carvalho Chehab }
13359a0bf528SMauro Carvalho Chehab return status;
13369a0bf528SMauro Carvalho Chehab }
13379a0bf528SMauro Carvalho Chehab
dvbt_enable_ofdm_token_ring(struct drxk_state * state,bool enable)1338cd7a67a4SMauro Carvalho Chehab static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
13399a0bf528SMauro Carvalho Chehab {
13409a0bf528SMauro Carvalho Chehab int status;
13419a0bf528SMauro Carvalho Chehab u16 data = 0;
1342cd7a67a4SMauro Carvalho Chehab u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1343cd7a67a4SMauro Carvalho Chehab u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
13449a0bf528SMauro Carvalho Chehab unsigned long end;
13459a0bf528SMauro Carvalho Chehab
13469a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
13479a0bf528SMauro Carvalho Chehab
13485a7f7b79SMauro Carvalho Chehab if (!enable) {
1349cd7a67a4SMauro Carvalho Chehab desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1350cd7a67a4SMauro Carvalho Chehab desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
13519a0bf528SMauro Carvalho Chehab }
13529a0bf528SMauro Carvalho Chehab
13539a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1354cd7a67a4SMauro Carvalho Chehab if (status >= 0 && data == desired_status) {
13559a0bf528SMauro Carvalho Chehab /* tokenring already has correct status */
13569a0bf528SMauro Carvalho Chehab return status;
13579a0bf528SMauro Carvalho Chehab }
13589a0bf528SMauro Carvalho Chehab /* Disable/enable dvbt tokenring bridge */
1359cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
13609a0bf528SMauro Carvalho Chehab
13619a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
13629a0bf528SMauro Carvalho Chehab do {
13639a0bf528SMauro Carvalho Chehab status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1364ab5060cdSMauro Carvalho Chehab if ((status >= 0 && data == desired_status)
1365ab5060cdSMauro Carvalho Chehab || time_is_after_jiffies(end))
13669a0bf528SMauro Carvalho Chehab break;
1367b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
13689a0bf528SMauro Carvalho Chehab } while (1);
1369cd7a67a4SMauro Carvalho Chehab if (data != desired_status) {
13703a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n");
13719a0bf528SMauro Carvalho Chehab return -EINVAL;
13729a0bf528SMauro Carvalho Chehab }
13739a0bf528SMauro Carvalho Chehab return status;
13749a0bf528SMauro Carvalho Chehab }
13759a0bf528SMauro Carvalho Chehab
mpegts_stop(struct drxk_state * state)1376cd7a67a4SMauro Carvalho Chehab static int mpegts_stop(struct drxk_state *state)
13779a0bf528SMauro Carvalho Chehab {
13789a0bf528SMauro Carvalho Chehab int status = 0;
1379cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0;
1380cd7a67a4SMauro Carvalho Chehab u16 fec_oc_ipr_mode = 0;
13819a0bf528SMauro Carvalho Chehab
13829a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
13839a0bf528SMauro Carvalho Chehab
138439c1cb2bSJonathan McCrohan /* Graceful shutdown (byte boundaries) */
1385cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
13869a0bf528SMauro Carvalho Chehab if (status < 0)
13879a0bf528SMauro Carvalho Chehab goto error;
1388cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1389cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
13909a0bf528SMauro Carvalho Chehab if (status < 0)
13919a0bf528SMauro Carvalho Chehab goto error;
13929a0bf528SMauro Carvalho Chehab
13939a0bf528SMauro Carvalho Chehab /* Suppress MCLK during absence of data */
1394cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
13959a0bf528SMauro Carvalho Chehab if (status < 0)
13969a0bf528SMauro Carvalho Chehab goto error;
1397cd7a67a4SMauro Carvalho Chehab fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1398cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
13999a0bf528SMauro Carvalho Chehab
14009a0bf528SMauro Carvalho Chehab error:
14019a0bf528SMauro Carvalho Chehab if (status < 0)
14023a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
14039a0bf528SMauro Carvalho Chehab
14049a0bf528SMauro Carvalho Chehab return status;
14059a0bf528SMauro Carvalho Chehab }
14069a0bf528SMauro Carvalho Chehab
scu_command(struct drxk_state * state,u16 cmd,u8 parameter_len,u16 * parameter,u8 result_len,u16 * result)14079a0bf528SMauro Carvalho Chehab static int scu_command(struct drxk_state *state,
1408cd7a67a4SMauro Carvalho Chehab u16 cmd, u8 parameter_len,
1409cd7a67a4SMauro Carvalho Chehab u16 *parameter, u8 result_len, u16 *result)
14109a0bf528SMauro Carvalho Chehab {
14119a0bf528SMauro Carvalho Chehab #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
14129a0bf528SMauro Carvalho Chehab #error DRXK register mapping no longer compatible with this routine!
14139a0bf528SMauro Carvalho Chehab #endif
1414cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0;
14159a0bf528SMauro Carvalho Chehab int status = -EINVAL;
14169a0bf528SMauro Carvalho Chehab unsigned long end;
14179a0bf528SMauro Carvalho Chehab u8 buffer[34];
14189a0bf528SMauro Carvalho Chehab int cnt = 0, ii;
14199a0bf528SMauro Carvalho Chehab const char *p;
14209a0bf528SMauro Carvalho Chehab char errname[30];
14219a0bf528SMauro Carvalho Chehab
14229a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
14239a0bf528SMauro Carvalho Chehab
1424cd7a67a4SMauro Carvalho Chehab if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
1425cd7a67a4SMauro Carvalho Chehab ((result_len > 0) && (result == NULL))) {
14263a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
14279a0bf528SMauro Carvalho Chehab return status;
14289a0bf528SMauro Carvalho Chehab }
14299a0bf528SMauro Carvalho Chehab
14309a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex);
14319a0bf528SMauro Carvalho Chehab
14329a0bf528SMauro Carvalho Chehab /* assume that the command register is ready
14339a0bf528SMauro Carvalho Chehab since it is checked afterwards */
1434daad52c8SMauro Carvalho Chehab if (parameter) {
1435cd7a67a4SMauro Carvalho Chehab for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
14369a0bf528SMauro Carvalho Chehab buffer[cnt++] = (parameter[ii] & 0xFF);
14379a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
14389a0bf528SMauro Carvalho Chehab }
1439daad52c8SMauro Carvalho Chehab }
14409a0bf528SMauro Carvalho Chehab buffer[cnt++] = (cmd & 0xFF);
14419a0bf528SMauro Carvalho Chehab buffer[cnt++] = ((cmd >> 8) & 0xFF);
14429a0bf528SMauro Carvalho Chehab
14439a0bf528SMauro Carvalho Chehab write_block(state, SCU_RAM_PARAM_0__A -
1444cd7a67a4SMauro Carvalho Chehab (parameter_len - 1), cnt, buffer);
14459a0bf528SMauro Carvalho Chehab /* Wait until SCU has processed command */
14469a0bf528SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
14479a0bf528SMauro Carvalho Chehab do {
1448b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
1449cd7a67a4SMauro Carvalho Chehab status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
14509a0bf528SMauro Carvalho Chehab if (status < 0)
14519a0bf528SMauro Carvalho Chehab goto error;
1452cd7a67a4SMauro Carvalho Chehab } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1453cd7a67a4SMauro Carvalho Chehab if (cur_cmd != DRX_SCU_READY) {
14543a4398f5SMauro Carvalho Chehab pr_err("SCU not ready\n");
14559a0bf528SMauro Carvalho Chehab status = -EIO;
14569a0bf528SMauro Carvalho Chehab goto error2;
14579a0bf528SMauro Carvalho Chehab }
14589a0bf528SMauro Carvalho Chehab /* read results */
1459cd7a67a4SMauro Carvalho Chehab if ((result_len > 0) && (result != NULL)) {
14609a0bf528SMauro Carvalho Chehab s16 err;
14619a0bf528SMauro Carvalho Chehab int ii;
14629a0bf528SMauro Carvalho Chehab
1463cd7a67a4SMauro Carvalho Chehab for (ii = result_len - 1; ii >= 0; ii -= 1) {
1464ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_PARAM_0__A - ii,
1465ab5060cdSMauro Carvalho Chehab &result[ii]);
14669a0bf528SMauro Carvalho Chehab if (status < 0)
14679a0bf528SMauro Carvalho Chehab goto error;
14689a0bf528SMauro Carvalho Chehab }
14699a0bf528SMauro Carvalho Chehab
14709a0bf528SMauro Carvalho Chehab /* Check if an error was reported by SCU */
14719a0bf528SMauro Carvalho Chehab err = (s16)result[0];
14729a0bf528SMauro Carvalho Chehab if (err >= 0)
14739a0bf528SMauro Carvalho Chehab goto error;
14749a0bf528SMauro Carvalho Chehab
14759a0bf528SMauro Carvalho Chehab /* check for the known error codes */
14769a0bf528SMauro Carvalho Chehab switch (err) {
14779a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKCMD:
14789a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKCMD";
14799a0bf528SMauro Carvalho Chehab break;
14809a0bf528SMauro Carvalho Chehab case SCU_RESULT_UNKSTD:
14819a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_UNKSTD";
14829a0bf528SMauro Carvalho Chehab break;
14839a0bf528SMauro Carvalho Chehab case SCU_RESULT_SIZE:
14849a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_SIZE";
14859a0bf528SMauro Carvalho Chehab break;
14869a0bf528SMauro Carvalho Chehab case SCU_RESULT_INVPAR:
14879a0bf528SMauro Carvalho Chehab p = "SCU_RESULT_INVPAR";
14889a0bf528SMauro Carvalho Chehab break;
14899a0bf528SMauro Carvalho Chehab default: /* Other negative values are errors */
14909a0bf528SMauro Carvalho Chehab sprintf(errname, "ERROR: %d\n", err);
14919a0bf528SMauro Carvalho Chehab p = errname;
14929a0bf528SMauro Carvalho Chehab }
14933a4398f5SMauro Carvalho Chehab pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
14949a0bf528SMauro Carvalho Chehab print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
14959a0bf528SMauro Carvalho Chehab status = -EINVAL;
14969a0bf528SMauro Carvalho Chehab goto error2;
14979a0bf528SMauro Carvalho Chehab }
14989a0bf528SMauro Carvalho Chehab
14999a0bf528SMauro Carvalho Chehab error:
15009a0bf528SMauro Carvalho Chehab if (status < 0)
15013a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
15029a0bf528SMauro Carvalho Chehab error2:
15039a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex);
15049a0bf528SMauro Carvalho Chehab return status;
15059a0bf528SMauro Carvalho Chehab }
15069a0bf528SMauro Carvalho Chehab
set_iqm_af(struct drxk_state * state,bool active)1507cd7a67a4SMauro Carvalho Chehab static int set_iqm_af(struct drxk_state *state, bool active)
15089a0bf528SMauro Carvalho Chehab {
15099a0bf528SMauro Carvalho Chehab u16 data = 0;
15109a0bf528SMauro Carvalho Chehab int status;
15119a0bf528SMauro Carvalho Chehab
15129a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
15139a0bf528SMauro Carvalho Chehab
15149a0bf528SMauro Carvalho Chehab /* Configure IQM */
15159a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
15169a0bf528SMauro Carvalho Chehab if (status < 0)
15179a0bf528SMauro Carvalho Chehab goto error;
15189a0bf528SMauro Carvalho Chehab
15199a0bf528SMauro Carvalho Chehab if (!active) {
15209a0bf528SMauro Carvalho Chehab data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
15219a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_AMP_STANDBY
15229a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_PD_STANDBY
15239a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
15249a0bf528SMauro Carvalho Chehab | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
15259a0bf528SMauro Carvalho Chehab } else {
15269a0bf528SMauro Carvalho Chehab data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
15279a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
15289a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
15299a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
15309a0bf528SMauro Carvalho Chehab & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
15319a0bf528SMauro Carvalho Chehab );
15329a0bf528SMauro Carvalho Chehab }
15339a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
15349a0bf528SMauro Carvalho Chehab
15359a0bf528SMauro Carvalho Chehab error:
15369a0bf528SMauro Carvalho Chehab if (status < 0)
15373a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
15389a0bf528SMauro Carvalho Chehab return status;
15399a0bf528SMauro Carvalho Chehab }
15409a0bf528SMauro Carvalho Chehab
ctrl_power_mode(struct drxk_state * state,enum drx_power_mode * mode)1541cd7a67a4SMauro Carvalho Chehab static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
15429a0bf528SMauro Carvalho Chehab {
15439a0bf528SMauro Carvalho Chehab int status = 0;
1544cd7a67a4SMauro Carvalho Chehab u16 sio_cc_pwd_mode = 0;
15459a0bf528SMauro Carvalho Chehab
15469a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
15479a0bf528SMauro Carvalho Chehab
15489a0bf528SMauro Carvalho Chehab /* Check arguments */
15499a0bf528SMauro Carvalho Chehab if (mode == NULL)
15509a0bf528SMauro Carvalho Chehab return -EINVAL;
15519a0bf528SMauro Carvalho Chehab
15529a0bf528SMauro Carvalho Chehab switch (*mode) {
15539a0bf528SMauro Carvalho Chehab case DRX_POWER_UP:
1554cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
15559a0bf528SMauro Carvalho Chehab break;
15569a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_OFDM:
1557cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
15589a0bf528SMauro Carvalho Chehab break;
15599a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_CORE:
1560cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
15619a0bf528SMauro Carvalho Chehab break;
15629a0bf528SMauro Carvalho Chehab case DRXK_POWER_DOWN_PLL:
1563cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
15649a0bf528SMauro Carvalho Chehab break;
15659a0bf528SMauro Carvalho Chehab case DRX_POWER_DOWN:
1566cd7a67a4SMauro Carvalho Chehab sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
15679a0bf528SMauro Carvalho Chehab break;
15689a0bf528SMauro Carvalho Chehab default:
1569e78da4daSJonathan Neuschäfer /* Unknown sleep mode */
15709a0bf528SMauro Carvalho Chehab return -EINVAL;
15719a0bf528SMauro Carvalho Chehab }
15729a0bf528SMauro Carvalho Chehab
15739a0bf528SMauro Carvalho Chehab /* If already in requested power mode, do nothing */
1574cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode == *mode)
15759a0bf528SMauro Carvalho Chehab return 0;
15769a0bf528SMauro Carvalho Chehab
15779a0bf528SMauro Carvalho Chehab /* For next steps make sure to start from DRX_POWER_UP mode */
1578cd7a67a4SMauro Carvalho Chehab if (state->m_current_power_mode != DRX_POWER_UP) {
1579cd7a67a4SMauro Carvalho Chehab status = power_up_device(state);
15809a0bf528SMauro Carvalho Chehab if (status < 0)
15819a0bf528SMauro Carvalho Chehab goto error;
1582cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, true);
15839a0bf528SMauro Carvalho Chehab if (status < 0)
15849a0bf528SMauro Carvalho Chehab goto error;
15859a0bf528SMauro Carvalho Chehab }
15869a0bf528SMauro Carvalho Chehab
15879a0bf528SMauro Carvalho Chehab if (*mode == DRX_POWER_UP) {
15882c149601SMasahiro Yamada /* Restore analog & pin configuration */
15899a0bf528SMauro Carvalho Chehab } else {
15909a0bf528SMauro Carvalho Chehab /* Power down to requested mode */
15919a0bf528SMauro Carvalho Chehab /* Backup some register settings */
15929a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected
15939a0bf528SMauro Carvalho Chehab to them in input mode */
15949a0bf528SMauro Carvalho Chehab /* Analog power down */
15959a0bf528SMauro Carvalho Chehab /* ADC power down */
15969a0bf528SMauro Carvalho Chehab /* Power down device */
15979a0bf528SMauro Carvalho Chehab /* stop all comm_exec */
15989a0bf528SMauro Carvalho Chehab /* Stop and power down previous standard */
1599cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
16009a0bf528SMauro Carvalho Chehab case OM_DVBT:
1601cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
16029a0bf528SMauro Carvalho Chehab if (status < 0)
16039a0bf528SMauro Carvalho Chehab goto error;
1604cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, false);
16059a0bf528SMauro Carvalho Chehab if (status < 0)
16069a0bf528SMauro Carvalho Chehab goto error;
16079a0bf528SMauro Carvalho Chehab break;
16089a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
16099a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
1610cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
16119a0bf528SMauro Carvalho Chehab if (status < 0)
16129a0bf528SMauro Carvalho Chehab goto error;
1613cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state);
16149a0bf528SMauro Carvalho Chehab if (status < 0)
16159a0bf528SMauro Carvalho Chehab goto error;
16169a0bf528SMauro Carvalho Chehab break;
16179a0bf528SMauro Carvalho Chehab default:
16189a0bf528SMauro Carvalho Chehab break;
16199a0bf528SMauro Carvalho Chehab }
1620cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false);
16219a0bf528SMauro Carvalho Chehab if (status < 0)
16229a0bf528SMauro Carvalho Chehab goto error;
1623cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
16249a0bf528SMauro Carvalho Chehab if (status < 0)
16259a0bf528SMauro Carvalho Chehab goto error;
16269a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
16279a0bf528SMauro Carvalho Chehab if (status < 0)
16289a0bf528SMauro Carvalho Chehab goto error;
16299a0bf528SMauro Carvalho Chehab
16309a0bf528SMauro Carvalho Chehab if (*mode != DRXK_POWER_DOWN_OFDM) {
1631cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |=
16329a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1633cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state);
16349a0bf528SMauro Carvalho Chehab if (status < 0)
16359a0bf528SMauro Carvalho Chehab goto error;
16369a0bf528SMauro Carvalho Chehab }
16379a0bf528SMauro Carvalho Chehab }
1638cd7a67a4SMauro Carvalho Chehab state->m_current_power_mode = *mode;
16399a0bf528SMauro Carvalho Chehab
16409a0bf528SMauro Carvalho Chehab error:
16419a0bf528SMauro Carvalho Chehab if (status < 0)
16423a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
16439a0bf528SMauro Carvalho Chehab
16449a0bf528SMauro Carvalho Chehab return status;
16459a0bf528SMauro Carvalho Chehab }
16469a0bf528SMauro Carvalho Chehab
power_down_dvbt(struct drxk_state * state,bool set_power_mode)1647cd7a67a4SMauro Carvalho Chehab static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
16489a0bf528SMauro Carvalho Chehab {
1649cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
1650cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0;
16519a0bf528SMauro Carvalho Chehab u16 data = 0;
16529a0bf528SMauro Carvalho Chehab int status;
16539a0bf528SMauro Carvalho Chehab
16549a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
16559a0bf528SMauro Carvalho Chehab
16569a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data);
16579a0bf528SMauro Carvalho Chehab if (status < 0)
16589a0bf528SMauro Carvalho Chehab goto error;
16599a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) {
16609a0bf528SMauro Carvalho Chehab /* Send OFDM stop command */
1661ab5060cdSMauro Carvalho Chehab status = scu_command(state,
1662ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM
1663ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
1664ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
16659a0bf528SMauro Carvalho Chehab if (status < 0)
16669a0bf528SMauro Carvalho Chehab goto error;
16679a0bf528SMauro Carvalho Chehab /* Send OFDM reset command */
1668ab5060cdSMauro Carvalho Chehab status = scu_command(state,
1669ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM
1670ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
1671ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
16729a0bf528SMauro Carvalho Chehab if (status < 0)
16739a0bf528SMauro Carvalho Chehab goto error;
16749a0bf528SMauro Carvalho Chehab }
16759a0bf528SMauro Carvalho Chehab
16769a0bf528SMauro Carvalho Chehab /* Reset datapath for OFDM, processors first */
16779a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
16789a0bf528SMauro Carvalho Chehab if (status < 0)
16799a0bf528SMauro Carvalho Chehab goto error;
16809a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
16819a0bf528SMauro Carvalho Chehab if (status < 0)
16829a0bf528SMauro Carvalho Chehab goto error;
16839a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
16849a0bf528SMauro Carvalho Chehab if (status < 0)
16859a0bf528SMauro Carvalho Chehab goto error;
16869a0bf528SMauro Carvalho Chehab
16879a0bf528SMauro Carvalho Chehab /* powerdown AFE */
1688cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false);
16899a0bf528SMauro Carvalho Chehab if (status < 0)
16909a0bf528SMauro Carvalho Chehab goto error;
16919a0bf528SMauro Carvalho Chehab
16929a0bf528SMauro Carvalho Chehab /* powerdown to OFDM mode */
1693cd7a67a4SMauro Carvalho Chehab if (set_power_mode) {
1694cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode);
16959a0bf528SMauro Carvalho Chehab if (status < 0)
16969a0bf528SMauro Carvalho Chehab goto error;
16979a0bf528SMauro Carvalho Chehab }
16989a0bf528SMauro Carvalho Chehab error:
16999a0bf528SMauro Carvalho Chehab if (status < 0)
17003a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
17019a0bf528SMauro Carvalho Chehab return status;
17029a0bf528SMauro Carvalho Chehab }
17039a0bf528SMauro Carvalho Chehab
setoperation_mode(struct drxk_state * state,enum operation_mode o_mode)1704cd7a67a4SMauro Carvalho Chehab static int setoperation_mode(struct drxk_state *state,
1705cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode)
17069a0bf528SMauro Carvalho Chehab {
17079a0bf528SMauro Carvalho Chehab int status = 0;
17089a0bf528SMauro Carvalho Chehab
17099a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
17109a0bf528SMauro Carvalho Chehab /*
17119a0bf528SMauro Carvalho Chehab Stop and power down previous standard
17129a0bf528SMauro Carvalho Chehab TODO investigate total power down instead of partial
17139a0bf528SMauro Carvalho Chehab power down depending on "previous" standard.
17149a0bf528SMauro Carvalho Chehab */
17159a0bf528SMauro Carvalho Chehab
17169a0bf528SMauro Carvalho Chehab /* disable HW lock indicator */
1717ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
1718ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
17199a0bf528SMauro Carvalho Chehab if (status < 0)
17209a0bf528SMauro Carvalho Chehab goto error;
17219a0bf528SMauro Carvalho Chehab
17229a0bf528SMauro Carvalho Chehab /* Device is already at the required mode */
1723cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == o_mode)
17249a0bf528SMauro Carvalho Chehab return 0;
17259a0bf528SMauro Carvalho Chehab
1726cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
17279a0bf528SMauro Carvalho Chehab /* OM_NONE was added for start up */
17289a0bf528SMauro Carvalho Chehab case OM_NONE:
17299a0bf528SMauro Carvalho Chehab break;
17309a0bf528SMauro Carvalho Chehab case OM_DVBT:
1731cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
17329a0bf528SMauro Carvalho Chehab if (status < 0)
17339a0bf528SMauro Carvalho Chehab goto error;
1734cd7a67a4SMauro Carvalho Chehab status = power_down_dvbt(state, true);
17359a0bf528SMauro Carvalho Chehab if (status < 0)
17369a0bf528SMauro Carvalho Chehab goto error;
1737cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE;
17389a0bf528SMauro Carvalho Chehab break;
1739df561f66SGustavo A. R. Silva case OM_QAM_ITU_A:
17409a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
1741cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
17429a0bf528SMauro Carvalho Chehab if (status < 0)
17439a0bf528SMauro Carvalho Chehab goto error;
1744cd7a67a4SMauro Carvalho Chehab status = power_down_qam(state);
17459a0bf528SMauro Carvalho Chehab if (status < 0)
17469a0bf528SMauro Carvalho Chehab goto error;
1747cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = OM_NONE;
17489a0bf528SMauro Carvalho Chehab break;
17499a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B:
17509a0bf528SMauro Carvalho Chehab default:
17519a0bf528SMauro Carvalho Chehab status = -EINVAL;
17529a0bf528SMauro Carvalho Chehab goto error;
17539a0bf528SMauro Carvalho Chehab }
17549a0bf528SMauro Carvalho Chehab
17559a0bf528SMauro Carvalho Chehab /*
17569a0bf528SMauro Carvalho Chehab Power up new standard
17579a0bf528SMauro Carvalho Chehab */
1758cd7a67a4SMauro Carvalho Chehab switch (o_mode) {
17599a0bf528SMauro Carvalho Chehab case OM_DVBT:
17609a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-T\n");
1761cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode;
1762cd7a67a4SMauro Carvalho Chehab status = set_dvbt_standard(state, o_mode);
17639a0bf528SMauro Carvalho Chehab if (status < 0)
17649a0bf528SMauro Carvalho Chehab goto error;
17659a0bf528SMauro Carvalho Chehab break;
1766df561f66SGustavo A. R. Silva case OM_QAM_ITU_A:
17679a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
17689a0bf528SMauro Carvalho Chehab dprintk(1, ": DVB-C Annex %c\n",
1769cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
1770cd7a67a4SMauro Carvalho Chehab state->m_operation_mode = o_mode;
1771cd7a67a4SMauro Carvalho Chehab status = set_qam_standard(state, o_mode);
17729a0bf528SMauro Carvalho Chehab if (status < 0)
17739a0bf528SMauro Carvalho Chehab goto error;
17749a0bf528SMauro Carvalho Chehab break;
17759a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B:
17769a0bf528SMauro Carvalho Chehab default:
17779a0bf528SMauro Carvalho Chehab status = -EINVAL;
17789a0bf528SMauro Carvalho Chehab }
17799a0bf528SMauro Carvalho Chehab error:
17809a0bf528SMauro Carvalho Chehab if (status < 0)
17813a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
17829a0bf528SMauro Carvalho Chehab return status;
17839a0bf528SMauro Carvalho Chehab }
17849a0bf528SMauro Carvalho Chehab
start(struct drxk_state * state,s32 offset_freq,s32 intermediate_frequency)1785cd7a67a4SMauro Carvalho Chehab static int start(struct drxk_state *state, s32 offset_freq,
1786cd7a67a4SMauro Carvalho Chehab s32 intermediate_frequency)
17879a0bf528SMauro Carvalho Chehab {
17889a0bf528SMauro Carvalho Chehab int status = -EINVAL;
17899a0bf528SMauro Carvalho Chehab
1790cd7a67a4SMauro Carvalho Chehab u16 i_freqk_hz;
1791cd7a67a4SMauro Carvalho Chehab s32 offsetk_hz = offset_freq / 1000;
17929a0bf528SMauro Carvalho Chehab
17939a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
1794cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state != DRXK_STOPPED &&
1795cd7a67a4SMauro Carvalho Chehab state->m_drxk_state != DRXK_DTV_STARTED)
17969a0bf528SMauro Carvalho Chehab goto error;
17979a0bf528SMauro Carvalho Chehab
1798cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
17999a0bf528SMauro Carvalho Chehab
1800cd7a67a4SMauro Carvalho Chehab if (intermediate_frequency < 0) {
1801cd7a67a4SMauro Carvalho Chehab state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
1802cd7a67a4SMauro Carvalho Chehab intermediate_frequency = -intermediate_frequency;
18039a0bf528SMauro Carvalho Chehab }
18049a0bf528SMauro Carvalho Chehab
1805cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
18069a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
18079a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
1808cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000);
1809cd7a67a4SMauro Carvalho Chehab status = set_qam(state, i_freqk_hz, offsetk_hz);
18109a0bf528SMauro Carvalho Chehab if (status < 0)
18119a0bf528SMauro Carvalho Chehab goto error;
1812cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED;
18139a0bf528SMauro Carvalho Chehab break;
18149a0bf528SMauro Carvalho Chehab case OM_DVBT:
1815cd7a67a4SMauro Carvalho Chehab i_freqk_hz = (intermediate_frequency / 1000);
1816cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
18179a0bf528SMauro Carvalho Chehab if (status < 0)
18189a0bf528SMauro Carvalho Chehab goto error;
1819cd7a67a4SMauro Carvalho Chehab status = set_dvbt(state, i_freqk_hz, offsetk_hz);
18209a0bf528SMauro Carvalho Chehab if (status < 0)
18219a0bf528SMauro Carvalho Chehab goto error;
1822cd7a67a4SMauro Carvalho Chehab status = dvbt_start(state);
18239a0bf528SMauro Carvalho Chehab if (status < 0)
18249a0bf528SMauro Carvalho Chehab goto error;
1825cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_DTV_STARTED;
18269a0bf528SMauro Carvalho Chehab break;
18279a0bf528SMauro Carvalho Chehab default:
18289a0bf528SMauro Carvalho Chehab break;
18299a0bf528SMauro Carvalho Chehab }
18309a0bf528SMauro Carvalho Chehab error:
18319a0bf528SMauro Carvalho Chehab if (status < 0)
18323a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
18339a0bf528SMauro Carvalho Chehab return status;
18349a0bf528SMauro Carvalho Chehab }
18359a0bf528SMauro Carvalho Chehab
shut_down(struct drxk_state * state)1836cd7a67a4SMauro Carvalho Chehab static int shut_down(struct drxk_state *state)
18379a0bf528SMauro Carvalho Chehab {
18389a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
18399a0bf528SMauro Carvalho Chehab
1840cd7a67a4SMauro Carvalho Chehab mpegts_stop(state);
18419a0bf528SMauro Carvalho Chehab return 0;
18429a0bf528SMauro Carvalho Chehab }
18439a0bf528SMauro Carvalho Chehab
get_lock_status(struct drxk_state * state,u32 * p_lock_status)1844cd7a67a4SMauro Carvalho Chehab static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
18459a0bf528SMauro Carvalho Chehab {
18469a0bf528SMauro Carvalho Chehab int status = -EINVAL;
18479a0bf528SMauro Carvalho Chehab
18489a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
18499a0bf528SMauro Carvalho Chehab
1850cd7a67a4SMauro Carvalho Chehab if (p_lock_status == NULL)
18519a0bf528SMauro Carvalho Chehab goto error;
18529a0bf528SMauro Carvalho Chehab
1853cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED;
18549a0bf528SMauro Carvalho Chehab
18559a0bf528SMauro Carvalho Chehab /* define the SCU command code */
1856cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
18579a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
18589a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_B:
18599a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
1860cd7a67a4SMauro Carvalho Chehab status = get_qam_lock_status(state, p_lock_status);
18619a0bf528SMauro Carvalho Chehab break;
18629a0bf528SMauro Carvalho Chehab case OM_DVBT:
1863cd7a67a4SMauro Carvalho Chehab status = get_dvbt_lock_status(state, p_lock_status);
18649a0bf528SMauro Carvalho Chehab break;
18659a0bf528SMauro Carvalho Chehab default:
1866b73bb2abSDaniel Scheller pr_debug("Unsupported operation mode %d in %s\n",
1867b73bb2abSDaniel Scheller state->m_operation_mode, __func__);
1868b73bb2abSDaniel Scheller return 0;
18699a0bf528SMauro Carvalho Chehab }
18709a0bf528SMauro Carvalho Chehab error:
18719a0bf528SMauro Carvalho Chehab if (status < 0)
18723a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
18739a0bf528SMauro Carvalho Chehab return status;
18749a0bf528SMauro Carvalho Chehab }
18759a0bf528SMauro Carvalho Chehab
mpegts_start(struct drxk_state * state)1876cd7a67a4SMauro Carvalho Chehab static int mpegts_start(struct drxk_state *state)
18779a0bf528SMauro Carvalho Chehab {
18789a0bf528SMauro Carvalho Chehab int status;
18799a0bf528SMauro Carvalho Chehab
1880cd7a67a4SMauro Carvalho Chehab u16 fec_oc_snc_mode = 0;
18819a0bf528SMauro Carvalho Chehab
18829a0bf528SMauro Carvalho Chehab /* Allow OC to sync again */
1883cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
18849a0bf528SMauro Carvalho Chehab if (status < 0)
18859a0bf528SMauro Carvalho Chehab goto error;
1886cd7a67a4SMauro Carvalho Chehab fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1887cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
18889a0bf528SMauro Carvalho Chehab if (status < 0)
18899a0bf528SMauro Carvalho Chehab goto error;
18909a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
18919a0bf528SMauro Carvalho Chehab error:
18929a0bf528SMauro Carvalho Chehab if (status < 0)
18933a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
18949a0bf528SMauro Carvalho Chehab return status;
18959a0bf528SMauro Carvalho Chehab }
18969a0bf528SMauro Carvalho Chehab
mpegts_dto_init(struct drxk_state * state)1897cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_init(struct drxk_state *state)
18989a0bf528SMauro Carvalho Chehab {
18999a0bf528SMauro Carvalho Chehab int status;
19009a0bf528SMauro Carvalho Chehab
19019a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
19029a0bf528SMauro Carvalho Chehab
19039a0bf528SMauro Carvalho Chehab /* Rate integration settings */
19049a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
19059a0bf528SMauro Carvalho Chehab if (status < 0)
19069a0bf528SMauro Carvalho Chehab goto error;
19079a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
19089a0bf528SMauro Carvalho Chehab if (status < 0)
19099a0bf528SMauro Carvalho Chehab goto error;
19109a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
19119a0bf528SMauro Carvalho Chehab if (status < 0)
19129a0bf528SMauro Carvalho Chehab goto error;
19139a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
19149a0bf528SMauro Carvalho Chehab if (status < 0)
19159a0bf528SMauro Carvalho Chehab goto error;
19169a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
19179a0bf528SMauro Carvalho Chehab if (status < 0)
19189a0bf528SMauro Carvalho Chehab goto error;
19199a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
19209a0bf528SMauro Carvalho Chehab if (status < 0)
19219a0bf528SMauro Carvalho Chehab goto error;
19229a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
19239a0bf528SMauro Carvalho Chehab if (status < 0)
19249a0bf528SMauro Carvalho Chehab goto error;
19259a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
19269a0bf528SMauro Carvalho Chehab if (status < 0)
19279a0bf528SMauro Carvalho Chehab goto error;
19289a0bf528SMauro Carvalho Chehab
19299a0bf528SMauro Carvalho Chehab /* Additional configuration */
19309a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_OCR_INVERT__A, 0);
19319a0bf528SMauro Carvalho Chehab if (status < 0)
19329a0bf528SMauro Carvalho Chehab goto error;
19339a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_LWM__A, 2);
19349a0bf528SMauro Carvalho Chehab if (status < 0)
19359a0bf528SMauro Carvalho Chehab goto error;
19369a0bf528SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_HWM__A, 12);
19379a0bf528SMauro Carvalho Chehab error:
19389a0bf528SMauro Carvalho Chehab if (status < 0)
19393a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
19409a0bf528SMauro Carvalho Chehab
19419a0bf528SMauro Carvalho Chehab return status;
19429a0bf528SMauro Carvalho Chehab }
19439a0bf528SMauro Carvalho Chehab
mpegts_dto_setup(struct drxk_state * state,enum operation_mode o_mode)1944cd7a67a4SMauro Carvalho Chehab static int mpegts_dto_setup(struct drxk_state *state,
1945cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode)
19469a0bf528SMauro Carvalho Chehab {
19479a0bf528SMauro Carvalho Chehab int status;
19489a0bf528SMauro Carvalho Chehab
1949cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */
1950cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */
1951cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */
1952cd7a67a4SMauro Carvalho Chehab u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */
1953cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */
1954cd7a67a4SMauro Carvalho Chehab u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */
1955cd7a67a4SMauro Carvalho Chehab u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */
1956cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_mode = 0;
1957cd7a67a4SMauro Carvalho Chehab u16 fec_oc_tmd_int_upd_rate = 0;
1958cd7a67a4SMauro Carvalho Chehab u32 max_bit_rate = 0;
1959cd7a67a4SMauro Carvalho Chehab bool static_clk = false;
19609a0bf528SMauro Carvalho Chehab
19619a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
19629a0bf528SMauro Carvalho Chehab
19639a0bf528SMauro Carvalho Chehab /* Check insertion of the Reed-Solomon parity bytes */
1964cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
19659a0bf528SMauro Carvalho Chehab if (status < 0)
19669a0bf528SMauro Carvalho Chehab goto error;
1967cd7a67a4SMauro Carvalho Chehab status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
19689a0bf528SMauro Carvalho Chehab if (status < 0)
19699a0bf528SMauro Carvalho Chehab goto error;
1970cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
1971cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
19725a7f7b79SMauro Carvalho Chehab if (state->m_insert_rs_byte) {
19739a0bf528SMauro Carvalho Chehab /* enable parity symbol forward */
1974cd7a67a4SMauro Carvalho Chehab fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
19759a0bf528SMauro Carvalho Chehab /* MVAL disable during parity bytes */
1976cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
19779a0bf528SMauro Carvalho Chehab /* TS burst length to 204 */
1978cd7a67a4SMauro Carvalho Chehab fec_oc_dto_burst_len = 204;
19799a0bf528SMauro Carvalho Chehab }
19809a0bf528SMauro Carvalho Chehab
198139c1cb2bSJonathan McCrohan /* Check serial or parallel output */
1982cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
19835a7f7b79SMauro Carvalho Chehab if (!state->m_enable_parallel) {
19849a0bf528SMauro Carvalho Chehab /* MPEG data output is serial -> set ipr_mode[0] */
1985cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
19869a0bf528SMauro Carvalho Chehab }
19879a0bf528SMauro Carvalho Chehab
1988cd7a67a4SMauro Carvalho Chehab switch (o_mode) {
19899a0bf528SMauro Carvalho Chehab case OM_DVBT:
1990cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbt_bitrate;
1991cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 3;
1992cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xC00000;
1993cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbt_static_clk;
19949a0bf528SMauro Carvalho Chehab break;
1995df561f66SGustavo A. R. Silva case OM_QAM_ITU_A:
19969a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
1997cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_mode = 0x0004;
1998cd7a67a4SMauro Carvalho Chehab fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */
1999cd7a67a4SMauro Carvalho Chehab max_bit_rate = state->m_dvbc_bitrate;
2000cd7a67a4SMauro Carvalho Chehab static_clk = state->m_dvbc_static_clk;
20019a0bf528SMauro Carvalho Chehab break;
20029a0bf528SMauro Carvalho Chehab default:
20039a0bf528SMauro Carvalho Chehab status = -EINVAL;
20049a0bf528SMauro Carvalho Chehab } /* switch (standard) */
20059a0bf528SMauro Carvalho Chehab if (status < 0)
20069a0bf528SMauro Carvalho Chehab goto error;
20079a0bf528SMauro Carvalho Chehab
20089a0bf528SMauro Carvalho Chehab /* Configure DTO's */
2009cd7a67a4SMauro Carvalho Chehab if (static_clk) {
2010cd7a67a4SMauro Carvalho Chehab u32 bit_rate = 0;
20119a0bf528SMauro Carvalho Chehab
20129a0bf528SMauro Carvalho Chehab /* Rational DTO for MCLK source (static MCLK rate),
20139a0bf528SMauro Carvalho Chehab Dynamic DTO for optimal grouping
20149a0bf528SMauro Carvalho Chehab (avoid intra-packet gaps),
20159a0bf528SMauro Carvalho Chehab DTO offset enable to sync TS burst with MSTRT */
2016cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
20179a0bf528SMauro Carvalho Chehab FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2018cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
20199a0bf528SMauro Carvalho Chehab FEC_OC_FCT_MODE_VIRT_ENA__M);
20209a0bf528SMauro Carvalho Chehab
20219a0bf528SMauro Carvalho Chehab /* Check user defined bitrate */
2022cd7a67a4SMauro Carvalho Chehab bit_rate = max_bit_rate;
2023cd7a67a4SMauro Carvalho Chehab if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */
2024cd7a67a4SMauro Carvalho Chehab bit_rate = 75900000UL;
20259a0bf528SMauro Carvalho Chehab }
20269a0bf528SMauro Carvalho Chehab /* Rational DTO period:
20279a0bf528SMauro Carvalho Chehab dto_period = (Fsys / bitrate) - 2
20289a0bf528SMauro Carvalho Chehab
2029cd7a67a4SMauro Carvalho Chehab result should be floored,
20309a0bf528SMauro Carvalho Chehab to make sure >= requested bitrate
20319a0bf528SMauro Carvalho Chehab */
2032cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
2033cd7a67a4SMauro Carvalho Chehab * 1000) / bit_rate);
2034cd7a67a4SMauro Carvalho Chehab if (fec_oc_dto_period <= 2)
2035cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period = 0;
20369a0bf528SMauro Carvalho Chehab else
2037cd7a67a4SMauro Carvalho Chehab fec_oc_dto_period -= 2;
2038cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 8;
20399a0bf528SMauro Carvalho Chehab } else {
2040cd7a67a4SMauro Carvalho Chehab /* (commonAttr->static_clk == false) => dynamic mode */
2041cd7a67a4SMauro Carvalho Chehab fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
2042cd7a67a4SMauro Carvalho Chehab fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
2043cd7a67a4SMauro Carvalho Chehab fec_oc_tmd_int_upd_rate = 5;
20449a0bf528SMauro Carvalho Chehab }
20459a0bf528SMauro Carvalho Chehab
20469a0bf528SMauro Carvalho Chehab /* Write appropriate registers with requested configuration */
2047cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
20489a0bf528SMauro Carvalho Chehab if (status < 0)
20499a0bf528SMauro Carvalho Chehab goto error;
2050cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
20519a0bf528SMauro Carvalho Chehab if (status < 0)
20529a0bf528SMauro Carvalho Chehab goto error;
2053cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
20549a0bf528SMauro Carvalho Chehab if (status < 0)
20559a0bf528SMauro Carvalho Chehab goto error;
2056cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
20579a0bf528SMauro Carvalho Chehab if (status < 0)
20589a0bf528SMauro Carvalho Chehab goto error;
2059cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
20609a0bf528SMauro Carvalho Chehab if (status < 0)
20619a0bf528SMauro Carvalho Chehab goto error;
2062cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
20639a0bf528SMauro Carvalho Chehab if (status < 0)
20649a0bf528SMauro Carvalho Chehab goto error;
20659a0bf528SMauro Carvalho Chehab
20669a0bf528SMauro Carvalho Chehab /* Rate integration settings */
2067cd7a67a4SMauro Carvalho Chehab status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
20689a0bf528SMauro Carvalho Chehab if (status < 0)
20699a0bf528SMauro Carvalho Chehab goto error;
2070ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
2071ab5060cdSMauro Carvalho Chehab fec_oc_tmd_int_upd_rate);
20729a0bf528SMauro Carvalho Chehab if (status < 0)
20739a0bf528SMauro Carvalho Chehab goto error;
2074cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
20759a0bf528SMauro Carvalho Chehab error:
20769a0bf528SMauro Carvalho Chehab if (status < 0)
20773a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
20789a0bf528SMauro Carvalho Chehab return status;
20799a0bf528SMauro Carvalho Chehab }
20809a0bf528SMauro Carvalho Chehab
mpegts_configure_polarity(struct drxk_state * state)2081cd7a67a4SMauro Carvalho Chehab static int mpegts_configure_polarity(struct drxk_state *state)
20829a0bf528SMauro Carvalho Chehab {
2083cd7a67a4SMauro Carvalho Chehab u16 fec_oc_reg_ipr_invert = 0;
20849a0bf528SMauro Carvalho Chehab
20859a0bf528SMauro Carvalho Chehab /* Data mask for the output data byte */
2086cd7a67a4SMauro Carvalho Chehab u16 invert_data_mask =
20879a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
20889a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
20899a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
20909a0bf528SMauro Carvalho Chehab FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
20919a0bf528SMauro Carvalho Chehab
20929a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
20939a0bf528SMauro Carvalho Chehab
20949a0bf528SMauro Carvalho Chehab /* Control selective inversion of output bits */
2095cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(invert_data_mask));
20965a7f7b79SMauro Carvalho Chehab if (state->m_invert_data)
2097cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= invert_data_mask;
2098cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
20995a7f7b79SMauro Carvalho Chehab if (state->m_invert_err)
2100cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2101cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
21025a7f7b79SMauro Carvalho Chehab if (state->m_invert_str)
2103cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2104cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
21055a7f7b79SMauro Carvalho Chehab if (state->m_invert_val)
2106cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2107cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
21085a7f7b79SMauro Carvalho Chehab if (state->m_invert_clk)
2109cd7a67a4SMauro Carvalho Chehab fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
21109a0bf528SMauro Carvalho Chehab
2111cd7a67a4SMauro Carvalho Chehab return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
21129a0bf528SMauro Carvalho Chehab }
21139a0bf528SMauro Carvalho Chehab
21149a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
21159a0bf528SMauro Carvalho Chehab
set_agc_rf(struct drxk_state * state,struct s_cfg_agc * p_agc_cfg,bool is_dtv)2116cd7a67a4SMauro Carvalho Chehab static int set_agc_rf(struct drxk_state *state,
2117cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv)
21189a0bf528SMauro Carvalho Chehab {
21199a0bf528SMauro Carvalho Chehab int status = -EINVAL;
21209a0bf528SMauro Carvalho Chehab u16 data = 0;
2121cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_if_agc_settings;
21229a0bf528SMauro Carvalho Chehab
21239a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
21249a0bf528SMauro Carvalho Chehab
2125cd7a67a4SMauro Carvalho Chehab if (p_agc_cfg == NULL)
21269a0bf528SMauro Carvalho Chehab goto error;
21279a0bf528SMauro Carvalho Chehab
2128cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) {
21299a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO:
21309a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */
21319a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
21329a0bf528SMauro Carvalho Chehab if (status < 0)
21339a0bf528SMauro Carvalho Chehab goto error;
21349a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
21359a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
21369a0bf528SMauro Carvalho Chehab if (status < 0)
21379a0bf528SMauro Carvalho Chehab goto error;
21389a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
21399a0bf528SMauro Carvalho Chehab if (status < 0)
21409a0bf528SMauro Carvalho Chehab goto error;
21419a0bf528SMauro Carvalho Chehab
21429a0bf528SMauro Carvalho Chehab /* Enable SCU RF AGC loop */
21439a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
21449a0bf528SMauro Carvalho Chehab
21459a0bf528SMauro Carvalho Chehab /* Polarity */
2146cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol)
21479a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21489a0bf528SMauro Carvalho Chehab else
21499a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
21509a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
21519a0bf528SMauro Carvalho Chehab if (status < 0)
21529a0bf528SMauro Carvalho Chehab goto error;
21539a0bf528SMauro Carvalho Chehab
21549a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */
21559a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
21569a0bf528SMauro Carvalho Chehab if (status < 0)
21579a0bf528SMauro Carvalho Chehab goto error;
21589a0bf528SMauro Carvalho Chehab
21599a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2160cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed <<
21619a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_RAGC_RED__B)
21629a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
21639a0bf528SMauro Carvalho Chehab
21649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
21659a0bf528SMauro Carvalho Chehab if (status < 0)
21669a0bf528SMauro Carvalho Chehab goto error;
21679a0bf528SMauro Carvalho Chehab
2168cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state))
2169cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
2170cd7a67a4SMauro Carvalho Chehab else if (is_qam(state))
2171cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_qam_if_agc_cfg;
21729a0bf528SMauro Carvalho Chehab else
2173cd7a67a4SMauro Carvalho Chehab p_if_agc_settings = &state->m_atv_if_agc_cfg;
2174cd7a67a4SMauro Carvalho Chehab if (p_if_agc_settings == NULL) {
21759a0bf528SMauro Carvalho Chehab status = -EINVAL;
21769a0bf528SMauro Carvalho Chehab goto error;
21779a0bf528SMauro Carvalho Chehab }
21789a0bf528SMauro Carvalho Chehab
21799a0bf528SMauro Carvalho Chehab /* Set TOP, only if IF-AGC is in AUTO mode */
218089fffac8SMauro Carvalho Chehab if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
2181ab5060cdSMauro Carvalho Chehab status = write16(state,
2182ab5060cdSMauro Carvalho Chehab SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2183ab5060cdSMauro Carvalho Chehab p_agc_cfg->top);
21849a0bf528SMauro Carvalho Chehab if (status < 0)
21859a0bf528SMauro Carvalho Chehab goto error;
218689fffac8SMauro Carvalho Chehab }
21879a0bf528SMauro Carvalho Chehab
21889a0bf528SMauro Carvalho Chehab /* Cut-Off current */
2189ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
2190ab5060cdSMauro Carvalho Chehab p_agc_cfg->cut_off_current);
21919a0bf528SMauro Carvalho Chehab if (status < 0)
21929a0bf528SMauro Carvalho Chehab goto error;
21939a0bf528SMauro Carvalho Chehab
21949a0bf528SMauro Carvalho Chehab /* Max. output level */
2195ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_MAX__A,
2196ab5060cdSMauro Carvalho Chehab p_agc_cfg->max_output_level);
21979a0bf528SMauro Carvalho Chehab if (status < 0)
21989a0bf528SMauro Carvalho Chehab goto error;
21999a0bf528SMauro Carvalho Chehab
22009a0bf528SMauro Carvalho Chehab break;
22019a0bf528SMauro Carvalho Chehab
22029a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER:
22039a0bf528SMauro Carvalho Chehab /* Enable RF AGC DAC */
22049a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
22059a0bf528SMauro Carvalho Chehab if (status < 0)
22069a0bf528SMauro Carvalho Chehab goto error;
22079a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22089a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
22099a0bf528SMauro Carvalho Chehab if (status < 0)
22109a0bf528SMauro Carvalho Chehab goto error;
22119a0bf528SMauro Carvalho Chehab
22129a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */
22139a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22149a0bf528SMauro Carvalho Chehab if (status < 0)
22159a0bf528SMauro Carvalho Chehab goto error;
22169a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2217cd7a67a4SMauro Carvalho Chehab if (state->m_rf_agc_pol)
22189a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22199a0bf528SMauro Carvalho Chehab else
22209a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
22219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22229a0bf528SMauro Carvalho Chehab if (status < 0)
22239a0bf528SMauro Carvalho Chehab goto error;
22249a0bf528SMauro Carvalho Chehab
22259a0bf528SMauro Carvalho Chehab /* SCU c.o.c. to 0, enabling full control range */
22269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
22279a0bf528SMauro Carvalho Chehab if (status < 0)
22289a0bf528SMauro Carvalho Chehab goto error;
22299a0bf528SMauro Carvalho Chehab
22309a0bf528SMauro Carvalho Chehab /* Write value to output pin */
2231ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
2232ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level);
22339a0bf528SMauro Carvalho Chehab if (status < 0)
22349a0bf528SMauro Carvalho Chehab goto error;
22359a0bf528SMauro Carvalho Chehab break;
22369a0bf528SMauro Carvalho Chehab
22379a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF:
22389a0bf528SMauro Carvalho Chehab /* Disable RF AGC DAC */
22399a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
22409a0bf528SMauro Carvalho Chehab if (status < 0)
22419a0bf528SMauro Carvalho Chehab goto error;
22429a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
22439a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
22449a0bf528SMauro Carvalho Chehab if (status < 0)
22459a0bf528SMauro Carvalho Chehab goto error;
22469a0bf528SMauro Carvalho Chehab
22479a0bf528SMauro Carvalho Chehab /* Disable SCU RF AGC loop */
22489a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22499a0bf528SMauro Carvalho Chehab if (status < 0)
22509a0bf528SMauro Carvalho Chehab goto error;
22519a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
22529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
22539a0bf528SMauro Carvalho Chehab if (status < 0)
22549a0bf528SMauro Carvalho Chehab goto error;
22559a0bf528SMauro Carvalho Chehab break;
22569a0bf528SMauro Carvalho Chehab
22579a0bf528SMauro Carvalho Chehab default:
22589a0bf528SMauro Carvalho Chehab status = -EINVAL;
22599a0bf528SMauro Carvalho Chehab
22609a0bf528SMauro Carvalho Chehab }
22619a0bf528SMauro Carvalho Chehab error:
22629a0bf528SMauro Carvalho Chehab if (status < 0)
22633a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
22649a0bf528SMauro Carvalho Chehab return status;
22659a0bf528SMauro Carvalho Chehab }
22669a0bf528SMauro Carvalho Chehab
22679a0bf528SMauro Carvalho Chehab #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
22689a0bf528SMauro Carvalho Chehab
set_agc_if(struct drxk_state * state,struct s_cfg_agc * p_agc_cfg,bool is_dtv)2269cd7a67a4SMauro Carvalho Chehab static int set_agc_if(struct drxk_state *state,
2270cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_agc_cfg, bool is_dtv)
22719a0bf528SMauro Carvalho Chehab {
22729a0bf528SMauro Carvalho Chehab u16 data = 0;
22739a0bf528SMauro Carvalho Chehab int status = 0;
2274cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc *p_rf_agc_settings;
22759a0bf528SMauro Carvalho Chehab
22769a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
22779a0bf528SMauro Carvalho Chehab
2278cd7a67a4SMauro Carvalho Chehab switch (p_agc_cfg->ctrl_mode) {
22799a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_AUTO:
22809a0bf528SMauro Carvalho Chehab
22819a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */
22829a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
22839a0bf528SMauro Carvalho Chehab if (status < 0)
22849a0bf528SMauro Carvalho Chehab goto error;
22859a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
22869a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
22879a0bf528SMauro Carvalho Chehab if (status < 0)
22889a0bf528SMauro Carvalho Chehab goto error;
22899a0bf528SMauro Carvalho Chehab
22909a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
22919a0bf528SMauro Carvalho Chehab if (status < 0)
22929a0bf528SMauro Carvalho Chehab goto error;
22939a0bf528SMauro Carvalho Chehab
22949a0bf528SMauro Carvalho Chehab /* Enable SCU IF AGC loop */
22959a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
22969a0bf528SMauro Carvalho Chehab
22979a0bf528SMauro Carvalho Chehab /* Polarity */
2298cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol)
22999a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23009a0bf528SMauro Carvalho Chehab else
23019a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23039a0bf528SMauro Carvalho Chehab if (status < 0)
23049a0bf528SMauro Carvalho Chehab goto error;
23059a0bf528SMauro Carvalho Chehab
23069a0bf528SMauro Carvalho Chehab /* Set speed (using complementary reduction value) */
23079a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
23089a0bf528SMauro Carvalho Chehab if (status < 0)
23099a0bf528SMauro Carvalho Chehab goto error;
23109a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2311cd7a67a4SMauro Carvalho Chehab data |= (~(p_agc_cfg->speed <<
23129a0bf528SMauro Carvalho Chehab SCU_RAM_AGC_KI_RED_IAGC_RED__B)
23139a0bf528SMauro Carvalho Chehab & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
23149a0bf528SMauro Carvalho Chehab
23159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
23169a0bf528SMauro Carvalho Chehab if (status < 0)
23179a0bf528SMauro Carvalho Chehab goto error;
23189a0bf528SMauro Carvalho Chehab
2319cd7a67a4SMauro Carvalho Chehab if (is_qam(state))
2320cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
23219a0bf528SMauro Carvalho Chehab else
2322cd7a67a4SMauro Carvalho Chehab p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
2323cd7a67a4SMauro Carvalho Chehab if (p_rf_agc_settings == NULL)
23249a0bf528SMauro Carvalho Chehab return -1;
23259a0bf528SMauro Carvalho Chehab /* Restore TOP */
2326ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2327ab5060cdSMauro Carvalho Chehab p_rf_agc_settings->top);
23289a0bf528SMauro Carvalho Chehab if (status < 0)
23299a0bf528SMauro Carvalho Chehab goto error;
23309a0bf528SMauro Carvalho Chehab break;
23319a0bf528SMauro Carvalho Chehab
23329a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_USER:
23339a0bf528SMauro Carvalho Chehab
23349a0bf528SMauro Carvalho Chehab /* Enable IF AGC DAC */
23359a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
23369a0bf528SMauro Carvalho Chehab if (status < 0)
23379a0bf528SMauro Carvalho Chehab goto error;
23389a0bf528SMauro Carvalho Chehab data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23399a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
23409a0bf528SMauro Carvalho Chehab if (status < 0)
23419a0bf528SMauro Carvalho Chehab goto error;
23429a0bf528SMauro Carvalho Chehab
23439a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23449a0bf528SMauro Carvalho Chehab if (status < 0)
23459a0bf528SMauro Carvalho Chehab goto error;
23469a0bf528SMauro Carvalho Chehab
23479a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */
23489a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23499a0bf528SMauro Carvalho Chehab
23509a0bf528SMauro Carvalho Chehab /* Polarity */
2351cd7a67a4SMauro Carvalho Chehab if (state->m_if_agc_pol)
23529a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23539a0bf528SMauro Carvalho Chehab else
23549a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
23559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23569a0bf528SMauro Carvalho Chehab if (status < 0)
23579a0bf528SMauro Carvalho Chehab goto error;
23589a0bf528SMauro Carvalho Chehab
23599a0bf528SMauro Carvalho Chehab /* Write value to output pin */
2360ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
2361ab5060cdSMauro Carvalho Chehab p_agc_cfg->output_level);
23629a0bf528SMauro Carvalho Chehab if (status < 0)
23639a0bf528SMauro Carvalho Chehab goto error;
23649a0bf528SMauro Carvalho Chehab break;
23659a0bf528SMauro Carvalho Chehab
23669a0bf528SMauro Carvalho Chehab case DRXK_AGC_CTRL_OFF:
23679a0bf528SMauro Carvalho Chehab
23689a0bf528SMauro Carvalho Chehab /* Disable If AGC DAC */
23699a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_STDBY__A, &data);
23709a0bf528SMauro Carvalho Chehab if (status < 0)
23719a0bf528SMauro Carvalho Chehab goto error;
23729a0bf528SMauro Carvalho Chehab data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
23739a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_STDBY__A, data);
23749a0bf528SMauro Carvalho Chehab if (status < 0)
23759a0bf528SMauro Carvalho Chehab goto error;
23769a0bf528SMauro Carvalho Chehab
23779a0bf528SMauro Carvalho Chehab /* Disable SCU IF AGC loop */
23789a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
23799a0bf528SMauro Carvalho Chehab if (status < 0)
23809a0bf528SMauro Carvalho Chehab goto error;
23819a0bf528SMauro Carvalho Chehab data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
23829a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
23839a0bf528SMauro Carvalho Chehab if (status < 0)
23849a0bf528SMauro Carvalho Chehab goto error;
23859a0bf528SMauro Carvalho Chehab break;
2386cd7a67a4SMauro Carvalho Chehab } /* switch (agcSettingsIf->ctrl_mode) */
23879a0bf528SMauro Carvalho Chehab
23889a0bf528SMauro Carvalho Chehab /* always set the top to support
23899a0bf528SMauro Carvalho Chehab configurations without if-loop */
2390cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
23919a0bf528SMauro Carvalho Chehab error:
23929a0bf528SMauro Carvalho Chehab if (status < 0)
23933a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
23949a0bf528SMauro Carvalho Chehab return status;
23959a0bf528SMauro Carvalho Chehab }
23969a0bf528SMauro Carvalho Chehab
get_qam_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2397cd7a67a4SMauro Carvalho Chehab static int get_qam_signal_to_noise(struct drxk_state *state,
2398cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise)
23999a0bf528SMauro Carvalho Chehab {
24009a0bf528SMauro Carvalho Chehab int status = 0;
2401cd7a67a4SMauro Carvalho Chehab u16 qam_sl_err_power = 0; /* accum. error between
24029a0bf528SMauro Carvalho Chehab raw and sliced symbols */
2403cd7a67a4SMauro Carvalho Chehab u32 qam_sl_sig_power = 0; /* used for MER, depends of
24049a0bf528SMauro Carvalho Chehab QAM modulation */
2405cd7a67a4SMauro Carvalho Chehab u32 qam_sl_mer = 0; /* QAM MER */
24069a0bf528SMauro Carvalho Chehab
24079a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
24089a0bf528SMauro Carvalho Chehab
24099a0bf528SMauro Carvalho Chehab /* MER calculation */
24109a0bf528SMauro Carvalho Chehab
24119a0bf528SMauro Carvalho Chehab /* get the register value needed for MER */
2412cd7a67a4SMauro Carvalho Chehab status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
24139a0bf528SMauro Carvalho Chehab if (status < 0) {
24143a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
24159a0bf528SMauro Carvalho Chehab return -EINVAL;
24169a0bf528SMauro Carvalho Chehab }
24179a0bf528SMauro Carvalho Chehab
24189a0bf528SMauro Carvalho Chehab switch (state->props.modulation) {
24199a0bf528SMauro Carvalho Chehab case QAM_16:
2420cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
24219a0bf528SMauro Carvalho Chehab break;
24229a0bf528SMauro Carvalho Chehab case QAM_32:
2423cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
24249a0bf528SMauro Carvalho Chehab break;
24259a0bf528SMauro Carvalho Chehab case QAM_64:
2426cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
24279a0bf528SMauro Carvalho Chehab break;
24289a0bf528SMauro Carvalho Chehab case QAM_128:
2429cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
24309a0bf528SMauro Carvalho Chehab break;
24319a0bf528SMauro Carvalho Chehab default:
24329a0bf528SMauro Carvalho Chehab case QAM_256:
2433cd7a67a4SMauro Carvalho Chehab qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
24349a0bf528SMauro Carvalho Chehab break;
24359a0bf528SMauro Carvalho Chehab }
24369a0bf528SMauro Carvalho Chehab
2437cd7a67a4SMauro Carvalho Chehab if (qam_sl_err_power > 0) {
2438cd7a67a4SMauro Carvalho Chehab qam_sl_mer = log10times100(qam_sl_sig_power) -
2439cd7a67a4SMauro Carvalho Chehab log10times100((u32) qam_sl_err_power);
24409a0bf528SMauro Carvalho Chehab }
2441cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = qam_sl_mer;
24429a0bf528SMauro Carvalho Chehab
24439a0bf528SMauro Carvalho Chehab return status;
24449a0bf528SMauro Carvalho Chehab }
24459a0bf528SMauro Carvalho Chehab
get_dvbt_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2446cd7a67a4SMauro Carvalho Chehab static int get_dvbt_signal_to_noise(struct drxk_state *state,
2447cd7a67a4SMauro Carvalho Chehab s32 *p_signal_to_noise)
24489a0bf528SMauro Carvalho Chehab {
24499a0bf528SMauro Carvalho Chehab int status;
2450cd7a67a4SMauro Carvalho Chehab u16 reg_data = 0;
2451cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_i = 0;
2452cd7a67a4SMauro Carvalho Chehab u32 eq_reg_td_sqr_err_q = 0;
2453cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_sqr_err_exp = 0;
2454cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_tps_pwr_ofs = 0;
2455cd7a67a4SMauro Carvalho Chehab u16 eq_reg_td_req_smb_cnt = 0;
2456cd7a67a4SMauro Carvalho Chehab u32 tps_cnt = 0;
2457cd7a67a4SMauro Carvalho Chehab u32 sqr_err_iq = 0;
24589a0bf528SMauro Carvalho Chehab u32 a = 0;
24599a0bf528SMauro Carvalho Chehab u32 b = 0;
24609a0bf528SMauro Carvalho Chehab u32 c = 0;
2461cd7a67a4SMauro Carvalho Chehab u32 i_mer = 0;
2462cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0;
24639a0bf528SMauro Carvalho Chehab
24649a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
24659a0bf528SMauro Carvalho Chehab
2466ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
2467ab5060cdSMauro Carvalho Chehab &eq_reg_td_tps_pwr_ofs);
24689a0bf528SMauro Carvalho Chehab if (status < 0)
24699a0bf528SMauro Carvalho Chehab goto error;
2470ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
2471ab5060cdSMauro Carvalho Chehab &eq_reg_td_req_smb_cnt);
24729a0bf528SMauro Carvalho Chehab if (status < 0)
24739a0bf528SMauro Carvalho Chehab goto error;
2474ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
2475ab5060cdSMauro Carvalho Chehab &eq_reg_td_sqr_err_exp);
24769a0bf528SMauro Carvalho Chehab if (status < 0)
24779a0bf528SMauro Carvalho Chehab goto error;
2478ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
2479ab5060cdSMauro Carvalho Chehab ®_data);
24809a0bf528SMauro Carvalho Chehab if (status < 0)
24819a0bf528SMauro Carvalho Chehab goto error;
24829a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_I operational range */
2483cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i = (u32) reg_data;
2484cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) &&
2485cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
2486cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_i += 0x00010000UL;
24879a0bf528SMauro Carvalho Chehab }
2488cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data);
24899a0bf528SMauro Carvalho Chehab if (status < 0)
24909a0bf528SMauro Carvalho Chehab goto error;
24919a0bf528SMauro Carvalho Chehab /* Extend SQR_ERR_Q operational range */
2492cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q = (u32) reg_data;
2493cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_sqr_err_exp > 11) &&
2494cd7a67a4SMauro Carvalho Chehab (eq_reg_td_sqr_err_q < 0x00000FFFUL))
2495cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_q += 0x00010000UL;
24969a0bf528SMauro Carvalho Chehab
2497ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
2498ab5060cdSMauro Carvalho Chehab &transmission_params);
24999a0bf528SMauro Carvalho Chehab if (status < 0)
25009a0bf528SMauro Carvalho Chehab goto error;
25019a0bf528SMauro Carvalho Chehab
25029a0bf528SMauro Carvalho Chehab /* Check input data for MER */
25039a0bf528SMauro Carvalho Chehab
25049a0bf528SMauro Carvalho Chehab /* MER calculation (in 0.1 dB) without math.h */
2505cd7a67a4SMauro Carvalho Chehab if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
2506cd7a67a4SMauro Carvalho Chehab i_mer = 0;
2507cd7a67a4SMauro Carvalho Chehab else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
25089a0bf528SMauro Carvalho Chehab /* No error at all, this must be the HW reset value
25099a0bf528SMauro Carvalho Chehab * Apparently no first measurement yet
25109a0bf528SMauro Carvalho Chehab * Set MER to 0.0 */
2511cd7a67a4SMauro Carvalho Chehab i_mer = 0;
25129a0bf528SMauro Carvalho Chehab } else {
2513cd7a67a4SMauro Carvalho Chehab sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
2514cd7a67a4SMauro Carvalho Chehab eq_reg_td_sqr_err_exp;
2515cd7a67a4SMauro Carvalho Chehab if ((transmission_params &
25169a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
25179a0bf528SMauro Carvalho Chehab == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2518cd7a67a4SMauro Carvalho Chehab tps_cnt = 17;
25199a0bf528SMauro Carvalho Chehab else
2520cd7a67a4SMauro Carvalho Chehab tps_cnt = 68;
25219a0bf528SMauro Carvalho Chehab
25229a0bf528SMauro Carvalho Chehab /* IMER = 100 * log10 (x)
2523cd7a67a4SMauro Carvalho Chehab where x = (eq_reg_td_tps_pwr_ofs^2 *
2524cd7a67a4SMauro Carvalho Chehab eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
25259a0bf528SMauro Carvalho Chehab
25269a0bf528SMauro Carvalho Chehab => IMER = a + b -c
2527cd7a67a4SMauro Carvalho Chehab where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
2528cd7a67a4SMauro Carvalho Chehab b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
2529cd7a67a4SMauro Carvalho Chehab c = 100 * log10 (sqr_err_iq)
25309a0bf528SMauro Carvalho Chehab */
25319a0bf528SMauro Carvalho Chehab
25329a0bf528SMauro Carvalho Chehab /* log(x) x = 9bits * 9bits->18 bits */
2533cd7a67a4SMauro Carvalho Chehab a = log10times100(eq_reg_td_tps_pwr_ofs *
2534cd7a67a4SMauro Carvalho Chehab eq_reg_td_tps_pwr_ofs);
25359a0bf528SMauro Carvalho Chehab /* log(x) x = 16bits * 7bits->23 bits */
2536cd7a67a4SMauro Carvalho Chehab b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
25379a0bf528SMauro Carvalho Chehab /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2538cd7a67a4SMauro Carvalho Chehab c = log10times100(sqr_err_iq);
25399a0bf528SMauro Carvalho Chehab
2540cd7a67a4SMauro Carvalho Chehab i_mer = a + b - c;
25419a0bf528SMauro Carvalho Chehab }
2542cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = i_mer;
25439a0bf528SMauro Carvalho Chehab
25449a0bf528SMauro Carvalho Chehab error:
25459a0bf528SMauro Carvalho Chehab if (status < 0)
25463a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
25479a0bf528SMauro Carvalho Chehab return status;
25489a0bf528SMauro Carvalho Chehab }
25499a0bf528SMauro Carvalho Chehab
get_signal_to_noise(struct drxk_state * state,s32 * p_signal_to_noise)2550cd7a67a4SMauro Carvalho Chehab static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
25519a0bf528SMauro Carvalho Chehab {
25529a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
25539a0bf528SMauro Carvalho Chehab
2554cd7a67a4SMauro Carvalho Chehab *p_signal_to_noise = 0;
2555cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
25569a0bf528SMauro Carvalho Chehab case OM_DVBT:
2557cd7a67a4SMauro Carvalho Chehab return get_dvbt_signal_to_noise(state, p_signal_to_noise);
25589a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
25599a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
2560cd7a67a4SMauro Carvalho Chehab return get_qam_signal_to_noise(state, p_signal_to_noise);
25619a0bf528SMauro Carvalho Chehab default:
25629a0bf528SMauro Carvalho Chehab break;
25639a0bf528SMauro Carvalho Chehab }
25649a0bf528SMauro Carvalho Chehab return 0;
25659a0bf528SMauro Carvalho Chehab }
25669a0bf528SMauro Carvalho Chehab
25679a0bf528SMauro Carvalho Chehab #if 0
2568cd7a67a4SMauro Carvalho Chehab static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
25699a0bf528SMauro Carvalho Chehab {
25709a0bf528SMauro Carvalho Chehab /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
25719a0bf528SMauro Carvalho Chehab int status = 0;
25729a0bf528SMauro Carvalho Chehab
25739a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
25749a0bf528SMauro Carvalho Chehab
25759a0bf528SMauro Carvalho Chehab static s32 QE_SN[] = {
25769a0bf528SMauro Carvalho Chehab 51, /* QPSK 1/2 */
25779a0bf528SMauro Carvalho Chehab 69, /* QPSK 2/3 */
25789a0bf528SMauro Carvalho Chehab 79, /* QPSK 3/4 */
25799a0bf528SMauro Carvalho Chehab 89, /* QPSK 5/6 */
25809a0bf528SMauro Carvalho Chehab 97, /* QPSK 7/8 */
25819a0bf528SMauro Carvalho Chehab 108, /* 16-QAM 1/2 */
25829a0bf528SMauro Carvalho Chehab 131, /* 16-QAM 2/3 */
25839a0bf528SMauro Carvalho Chehab 146, /* 16-QAM 3/4 */
25849a0bf528SMauro Carvalho Chehab 156, /* 16-QAM 5/6 */
25859a0bf528SMauro Carvalho Chehab 160, /* 16-QAM 7/8 */
25869a0bf528SMauro Carvalho Chehab 165, /* 64-QAM 1/2 */
25879a0bf528SMauro Carvalho Chehab 187, /* 64-QAM 2/3 */
25889a0bf528SMauro Carvalho Chehab 202, /* 64-QAM 3/4 */
25899a0bf528SMauro Carvalho Chehab 216, /* 64-QAM 5/6 */
25909a0bf528SMauro Carvalho Chehab 225, /* 64-QAM 7/8 */
25919a0bf528SMauro Carvalho Chehab };
25929a0bf528SMauro Carvalho Chehab
2593cd7a67a4SMauro Carvalho Chehab *p_quality = 0;
25949a0bf528SMauro Carvalho Chehab
25959a0bf528SMauro Carvalho Chehab do {
2596cd7a67a4SMauro Carvalho Chehab s32 signal_to_noise = 0;
2597cd7a67a4SMauro Carvalho Chehab u16 constellation = 0;
2598cd7a67a4SMauro Carvalho Chehab u16 code_rate = 0;
2599cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel;
2600cd7a67a4SMauro Carvalho Chehab u32 ber_quality;
26019a0bf528SMauro Carvalho Chehab
2602cd7a67a4SMauro Carvalho Chehab status = get_dvbt_signal_to_noise(state, &signal_to_noise);
26039a0bf528SMauro Carvalho Chehab if (status < 0)
26049a0bf528SMauro Carvalho Chehab break;
2605ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
2606ab5060cdSMauro Carvalho Chehab &constellation);
26079a0bf528SMauro Carvalho Chehab if (status < 0)
26089a0bf528SMauro Carvalho Chehab break;
2609cd7a67a4SMauro Carvalho Chehab constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
26109a0bf528SMauro Carvalho Chehab
2611ab5060cdSMauro Carvalho Chehab status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
2612ab5060cdSMauro Carvalho Chehab &code_rate);
26139a0bf528SMauro Carvalho Chehab if (status < 0)
26149a0bf528SMauro Carvalho Chehab break;
2615cd7a67a4SMauro Carvalho Chehab code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
26169a0bf528SMauro Carvalho Chehab
2617cd7a67a4SMauro Carvalho Chehab if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2618cd7a67a4SMauro Carvalho Chehab code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
26199a0bf528SMauro Carvalho Chehab break;
2620cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise -
2621cd7a67a4SMauro Carvalho Chehab QE_SN[constellation * 5 + code_rate];
2622cd7a67a4SMauro Carvalho Chehab ber_quality = 100;
26239a0bf528SMauro Carvalho Chehab
2624cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70)
2625cd7a67a4SMauro Carvalho Chehab *p_quality = 0;
2626cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30)
2627cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) *
2628cd7a67a4SMauro Carvalho Chehab ber_quality) / 100;
26299a0bf528SMauro Carvalho Chehab else
2630cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality;
26319a0bf528SMauro Carvalho Chehab } while (0);
26329a0bf528SMauro Carvalho Chehab return 0;
26339a0bf528SMauro Carvalho Chehab };
26349a0bf528SMauro Carvalho Chehab
2635cd7a67a4SMauro Carvalho Chehab static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
26369a0bf528SMauro Carvalho Chehab {
26379a0bf528SMauro Carvalho Chehab int status = 0;
2638cd7a67a4SMauro Carvalho Chehab *p_quality = 0;
26399a0bf528SMauro Carvalho Chehab
26409a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
26419a0bf528SMauro Carvalho Chehab
26429a0bf528SMauro Carvalho Chehab do {
2643cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise = 0;
2644cd7a67a4SMauro Carvalho Chehab u32 ber_quality = 100;
2645cd7a67a4SMauro Carvalho Chehab u32 signal_to_noise_rel = 0;
26469a0bf528SMauro Carvalho Chehab
2647cd7a67a4SMauro Carvalho Chehab status = get_qam_signal_to_noise(state, &signal_to_noise);
26489a0bf528SMauro Carvalho Chehab if (status < 0)
26499a0bf528SMauro Carvalho Chehab break;
26509a0bf528SMauro Carvalho Chehab
26519a0bf528SMauro Carvalho Chehab switch (state->props.modulation) {
26529a0bf528SMauro Carvalho Chehab case QAM_16:
2653cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 200;
26549a0bf528SMauro Carvalho Chehab break;
26559a0bf528SMauro Carvalho Chehab case QAM_32:
2656cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 230;
26579a0bf528SMauro Carvalho Chehab break; /* Not in NorDig */
26589a0bf528SMauro Carvalho Chehab case QAM_64:
2659cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 260;
26609a0bf528SMauro Carvalho Chehab break;
26619a0bf528SMauro Carvalho Chehab case QAM_128:
2662cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 290;
26639a0bf528SMauro Carvalho Chehab break;
26649a0bf528SMauro Carvalho Chehab default:
26659a0bf528SMauro Carvalho Chehab case QAM_256:
2666cd7a67a4SMauro Carvalho Chehab signal_to_noise_rel = signal_to_noise - 320;
26679a0bf528SMauro Carvalho Chehab break;
26689a0bf528SMauro Carvalho Chehab }
26699a0bf528SMauro Carvalho Chehab
2670cd7a67a4SMauro Carvalho Chehab if (signal_to_noise_rel < -70)
2671cd7a67a4SMauro Carvalho Chehab *p_quality = 0;
2672cd7a67a4SMauro Carvalho Chehab else if (signal_to_noise_rel < 30)
2673cd7a67a4SMauro Carvalho Chehab *p_quality = ((signal_to_noise_rel + 70) *
2674cd7a67a4SMauro Carvalho Chehab ber_quality) / 100;
26759a0bf528SMauro Carvalho Chehab else
2676cd7a67a4SMauro Carvalho Chehab *p_quality = ber_quality;
26779a0bf528SMauro Carvalho Chehab } while (0);
26789a0bf528SMauro Carvalho Chehab
26799a0bf528SMauro Carvalho Chehab return status;
26809a0bf528SMauro Carvalho Chehab }
26819a0bf528SMauro Carvalho Chehab
2682cd7a67a4SMauro Carvalho Chehab static int get_quality(struct drxk_state *state, s32 *p_quality)
26839a0bf528SMauro Carvalho Chehab {
26849a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
26859a0bf528SMauro Carvalho Chehab
2686cd7a67a4SMauro Carvalho Chehab switch (state->m_operation_mode) {
26879a0bf528SMauro Carvalho Chehab case OM_DVBT:
2688cd7a67a4SMauro Carvalho Chehab return get_dvbt_quality(state, p_quality);
26899a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
2690cd7a67a4SMauro Carvalho Chehab return get_dvbc_quality(state, p_quality);
26919a0bf528SMauro Carvalho Chehab default:
26929a0bf528SMauro Carvalho Chehab break;
26939a0bf528SMauro Carvalho Chehab }
26949a0bf528SMauro Carvalho Chehab
26959a0bf528SMauro Carvalho Chehab return 0;
26969a0bf528SMauro Carvalho Chehab }
26979a0bf528SMauro Carvalho Chehab #endif
26989a0bf528SMauro Carvalho Chehab
26999a0bf528SMauro Carvalho Chehab /* Free data ram in SIO HI */
27009a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
27019a0bf528SMauro Carvalho Chehab #define SIO_HI_RA_RAM_USR_END__A 0x420060
27029a0bf528SMauro Carvalho Chehab
27039a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
27049a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
27059a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
27069a0bf528SMauro Carvalho Chehab #define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
27079a0bf528SMauro Carvalho Chehab
27089a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
27099a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
27109a0bf528SMauro Carvalho Chehab #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
27119a0bf528SMauro Carvalho Chehab
ConfigureI2CBridge(struct drxk_state * state,bool b_enable_bridge)2712cd7a67a4SMauro Carvalho Chehab static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
27139a0bf528SMauro Carvalho Chehab {
27149a0bf528SMauro Carvalho Chehab int status = -EINVAL;
27159a0bf528SMauro Carvalho Chehab
27169a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
27179a0bf528SMauro Carvalho Chehab
2718cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
27199a0bf528SMauro Carvalho Chehab return 0;
2720cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_POWERED_DOWN)
27219a0bf528SMauro Carvalho Chehab goto error;
27229a0bf528SMauro Carvalho Chehab
27239a0bf528SMauro Carvalho Chehab if (state->no_i2c_bridge)
27249a0bf528SMauro Carvalho Chehab return 0;
27259a0bf528SMauro Carvalho Chehab
2726ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
2727ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
27289a0bf528SMauro Carvalho Chehab if (status < 0)
27299a0bf528SMauro Carvalho Chehab goto error;
2730cd7a67a4SMauro Carvalho Chehab if (b_enable_bridge) {
2731ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2732ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
27339a0bf528SMauro Carvalho Chehab if (status < 0)
27349a0bf528SMauro Carvalho Chehab goto error;
27359a0bf528SMauro Carvalho Chehab } else {
2736ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
2737ab5060cdSMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
27389a0bf528SMauro Carvalho Chehab if (status < 0)
27399a0bf528SMauro Carvalho Chehab goto error;
27409a0bf528SMauro Carvalho Chehab }
27419a0bf528SMauro Carvalho Chehab
2742b1cf2019SHans Verkuil status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
27439a0bf528SMauro Carvalho Chehab
27449a0bf528SMauro Carvalho Chehab error:
27459a0bf528SMauro Carvalho Chehab if (status < 0)
27463a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
27479a0bf528SMauro Carvalho Chehab return status;
27489a0bf528SMauro Carvalho Chehab }
27499a0bf528SMauro Carvalho Chehab
set_pre_saw(struct drxk_state * state,struct s_cfg_pre_saw * p_pre_saw_cfg)2750cd7a67a4SMauro Carvalho Chehab static int set_pre_saw(struct drxk_state *state,
2751cd7a67a4SMauro Carvalho Chehab struct s_cfg_pre_saw *p_pre_saw_cfg)
27529a0bf528SMauro Carvalho Chehab {
27539a0bf528SMauro Carvalho Chehab int status = -EINVAL;
27549a0bf528SMauro Carvalho Chehab
27559a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
27569a0bf528SMauro Carvalho Chehab
2757cd7a67a4SMauro Carvalho Chehab if ((p_pre_saw_cfg == NULL)
2758cd7a67a4SMauro Carvalho Chehab || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
27599a0bf528SMauro Carvalho Chehab goto error;
27609a0bf528SMauro Carvalho Chehab
2761cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
27629a0bf528SMauro Carvalho Chehab error:
27639a0bf528SMauro Carvalho Chehab if (status < 0)
27643a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
27659a0bf528SMauro Carvalho Chehab return status;
27669a0bf528SMauro Carvalho Chehab }
27679a0bf528SMauro Carvalho Chehab
bl_direct_cmd(struct drxk_state * state,u32 target_addr,u16 rom_offset,u16 nr_of_elements,u32 time_out)2768cd7a67a4SMauro Carvalho Chehab static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
2769cd7a67a4SMauro Carvalho Chehab u16 rom_offset, u16 nr_of_elements, u32 time_out)
27709a0bf528SMauro Carvalho Chehab {
2771cd7a67a4SMauro Carvalho Chehab u16 bl_status = 0;
2772cd7a67a4SMauro Carvalho Chehab u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
2773cd7a67a4SMauro Carvalho Chehab u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
27749a0bf528SMauro Carvalho Chehab int status;
27759a0bf528SMauro Carvalho Chehab unsigned long end;
27769a0bf528SMauro Carvalho Chehab
27779a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
27789a0bf528SMauro Carvalho Chehab
27799a0bf528SMauro Carvalho Chehab mutex_lock(&state->mutex);
27809a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
27819a0bf528SMauro Carvalho Chehab if (status < 0)
27829a0bf528SMauro Carvalho Chehab goto error;
27839a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
27849a0bf528SMauro Carvalho Chehab if (status < 0)
27859a0bf528SMauro Carvalho Chehab goto error;
27869a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_TGT_ADDR__A, offset);
27879a0bf528SMauro Carvalho Chehab if (status < 0)
27889a0bf528SMauro Carvalho Chehab goto error;
2789cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
27909a0bf528SMauro Carvalho Chehab if (status < 0)
27919a0bf528SMauro Carvalho Chehab goto error;
2792cd7a67a4SMauro Carvalho Chehab status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
27939a0bf528SMauro Carvalho Chehab if (status < 0)
27949a0bf528SMauro Carvalho Chehab goto error;
27959a0bf528SMauro Carvalho Chehab status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
27969a0bf528SMauro Carvalho Chehab if (status < 0)
27979a0bf528SMauro Carvalho Chehab goto error;
27989a0bf528SMauro Carvalho Chehab
2799cd7a67a4SMauro Carvalho Chehab end = jiffies + msecs_to_jiffies(time_out);
28009a0bf528SMauro Carvalho Chehab do {
2801cd7a67a4SMauro Carvalho Chehab status = read16(state, SIO_BL_STATUS__A, &bl_status);
28029a0bf528SMauro Carvalho Chehab if (status < 0)
28039a0bf528SMauro Carvalho Chehab goto error;
2804cd7a67a4SMauro Carvalho Chehab } while ((bl_status == 0x1) && time_is_after_jiffies(end));
2805cd7a67a4SMauro Carvalho Chehab if (bl_status == 0x1) {
28063a4398f5SMauro Carvalho Chehab pr_err("SIO not ready\n");
28079a0bf528SMauro Carvalho Chehab status = -EINVAL;
28089a0bf528SMauro Carvalho Chehab goto error2;
28099a0bf528SMauro Carvalho Chehab }
28109a0bf528SMauro Carvalho Chehab error:
28119a0bf528SMauro Carvalho Chehab if (status < 0)
28123a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
28139a0bf528SMauro Carvalho Chehab error2:
28149a0bf528SMauro Carvalho Chehab mutex_unlock(&state->mutex);
28159a0bf528SMauro Carvalho Chehab return status;
28169a0bf528SMauro Carvalho Chehab
28179a0bf528SMauro Carvalho Chehab }
28189a0bf528SMauro Carvalho Chehab
adc_sync_measurement(struct drxk_state * state,u16 * count)2819cd7a67a4SMauro Carvalho Chehab static int adc_sync_measurement(struct drxk_state *state, u16 *count)
28209a0bf528SMauro Carvalho Chehab {
28219a0bf528SMauro Carvalho Chehab u16 data = 0;
28229a0bf528SMauro Carvalho Chehab int status;
28239a0bf528SMauro Carvalho Chehab
28249a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
28259a0bf528SMauro Carvalho Chehab
2826cd7a67a4SMauro Carvalho Chehab /* start measurement */
28279a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
28289a0bf528SMauro Carvalho Chehab if (status < 0)
28299a0bf528SMauro Carvalho Chehab goto error;
28309a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 1);
28319a0bf528SMauro Carvalho Chehab if (status < 0)
28329a0bf528SMauro Carvalho Chehab goto error;
28339a0bf528SMauro Carvalho Chehab
28349a0bf528SMauro Carvalho Chehab *count = 0;
28359a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE0__A, &data);
28369a0bf528SMauro Carvalho Chehab if (status < 0)
28379a0bf528SMauro Carvalho Chehab goto error;
28389a0bf528SMauro Carvalho Chehab if (data == 127)
28399a0bf528SMauro Carvalho Chehab *count = *count + 1;
28409a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE1__A, &data);
28419a0bf528SMauro Carvalho Chehab if (status < 0)
28429a0bf528SMauro Carvalho Chehab goto error;
28439a0bf528SMauro Carvalho Chehab if (data == 127)
28449a0bf528SMauro Carvalho Chehab *count = *count + 1;
28459a0bf528SMauro Carvalho Chehab status = read16(state, IQM_AF_PHASE2__A, &data);
28469a0bf528SMauro Carvalho Chehab if (status < 0)
28479a0bf528SMauro Carvalho Chehab goto error;
28489a0bf528SMauro Carvalho Chehab if (data == 127)
28499a0bf528SMauro Carvalho Chehab *count = *count + 1;
28509a0bf528SMauro Carvalho Chehab
28519a0bf528SMauro Carvalho Chehab error:
28529a0bf528SMauro Carvalho Chehab if (status < 0)
28533a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
28549a0bf528SMauro Carvalho Chehab return status;
28559a0bf528SMauro Carvalho Chehab }
28569a0bf528SMauro Carvalho Chehab
adc_synchronization(struct drxk_state * state)2857cd7a67a4SMauro Carvalho Chehab static int adc_synchronization(struct drxk_state *state)
28589a0bf528SMauro Carvalho Chehab {
28599a0bf528SMauro Carvalho Chehab u16 count = 0;
28609a0bf528SMauro Carvalho Chehab int status;
28619a0bf528SMauro Carvalho Chehab
28629a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
28639a0bf528SMauro Carvalho Chehab
2864cd7a67a4SMauro Carvalho Chehab status = adc_sync_measurement(state, &count);
28659a0bf528SMauro Carvalho Chehab if (status < 0)
28669a0bf528SMauro Carvalho Chehab goto error;
28679a0bf528SMauro Carvalho Chehab
28689a0bf528SMauro Carvalho Chehab if (count == 1) {
286939c1cb2bSJonathan McCrohan /* Try sampling on a different edge */
2870cd7a67a4SMauro Carvalho Chehab u16 clk_neg = 0;
28719a0bf528SMauro Carvalho Chehab
2872cd7a67a4SMauro Carvalho Chehab status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
28739a0bf528SMauro Carvalho Chehab if (status < 0)
28749a0bf528SMauro Carvalho Chehab goto error;
2875cd7a67a4SMauro Carvalho Chehab if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
28769a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2877cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2878cd7a67a4SMauro Carvalho Chehab clk_neg |=
28799a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
28809a0bf528SMauro Carvalho Chehab } else {
2881cd7a67a4SMauro Carvalho Chehab clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2882cd7a67a4SMauro Carvalho Chehab clk_neg |=
28839a0bf528SMauro Carvalho Chehab IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
28849a0bf528SMauro Carvalho Chehab }
2885cd7a67a4SMauro Carvalho Chehab status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
28869a0bf528SMauro Carvalho Chehab if (status < 0)
28879a0bf528SMauro Carvalho Chehab goto error;
2888cd7a67a4SMauro Carvalho Chehab status = adc_sync_measurement(state, &count);
28899a0bf528SMauro Carvalho Chehab if (status < 0)
28909a0bf528SMauro Carvalho Chehab goto error;
28919a0bf528SMauro Carvalho Chehab }
28929a0bf528SMauro Carvalho Chehab
28939a0bf528SMauro Carvalho Chehab if (count < 2)
28949a0bf528SMauro Carvalho Chehab status = -EINVAL;
28959a0bf528SMauro Carvalho Chehab error:
28969a0bf528SMauro Carvalho Chehab if (status < 0)
28973a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
28989a0bf528SMauro Carvalho Chehab return status;
28999a0bf528SMauro Carvalho Chehab }
29009a0bf528SMauro Carvalho Chehab
set_frequency_shifter(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset,bool is_dtv)2901cd7a67a4SMauro Carvalho Chehab static int set_frequency_shifter(struct drxk_state *state,
2902cd7a67a4SMauro Carvalho Chehab u16 intermediate_freqk_hz,
2903cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset, bool is_dtv)
29049a0bf528SMauro Carvalho Chehab {
2905cd7a67a4SMauro Carvalho Chehab bool select_pos_image = false;
2906cd7a67a4SMauro Carvalho Chehab u32 rf_freq_residual = tuner_freq_offset;
2907cd7a67a4SMauro Carvalho Chehab u32 fm_frequency_shift = 0;
2908cd7a67a4SMauro Carvalho Chehab bool tuner_mirror = !state->m_b_mirror_freq_spect;
2909cd7a67a4SMauro Carvalho Chehab u32 adc_freq;
2910cd7a67a4SMauro Carvalho Chehab bool adc_flip;
29119a0bf528SMauro Carvalho Chehab int status;
2912cd7a67a4SMauro Carvalho Chehab u32 if_freq_actual;
2913cd7a67a4SMauro Carvalho Chehab u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
2914cd7a67a4SMauro Carvalho Chehab u32 frequency_shift;
2915cd7a67a4SMauro Carvalho Chehab bool image_to_select;
29169a0bf528SMauro Carvalho Chehab
29179a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
29189a0bf528SMauro Carvalho Chehab
29199a0bf528SMauro Carvalho Chehab /*
29209a0bf528SMauro Carvalho Chehab Program frequency shifter
29219a0bf528SMauro Carvalho Chehab No need to account for mirroring on RF
29229a0bf528SMauro Carvalho Chehab */
2923cd7a67a4SMauro Carvalho Chehab if (is_dtv) {
2924cd7a67a4SMauro Carvalho Chehab if ((state->m_operation_mode == OM_QAM_ITU_A) ||
2925cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_QAM_ITU_C) ||
2926cd7a67a4SMauro Carvalho Chehab (state->m_operation_mode == OM_DVBT))
2927cd7a67a4SMauro Carvalho Chehab select_pos_image = true;
29289a0bf528SMauro Carvalho Chehab else
2929cd7a67a4SMauro Carvalho Chehab select_pos_image = false;
29309a0bf528SMauro Carvalho Chehab }
2931cd7a67a4SMauro Carvalho Chehab if (tuner_mirror)
29329a0bf528SMauro Carvalho Chehab /* tuner doesn't mirror */
2933cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz +
2934cd7a67a4SMauro Carvalho Chehab rf_freq_residual + fm_frequency_shift;
29359a0bf528SMauro Carvalho Chehab else
29369a0bf528SMauro Carvalho Chehab /* tuner mirrors */
2937cd7a67a4SMauro Carvalho Chehab if_freq_actual = intermediate_freqk_hz -
2938cd7a67a4SMauro Carvalho Chehab rf_freq_residual - fm_frequency_shift;
2939cd7a67a4SMauro Carvalho Chehab if (if_freq_actual > sampling_frequency / 2) {
29409a0bf528SMauro Carvalho Chehab /* adc mirrors */
2941cd7a67a4SMauro Carvalho Chehab adc_freq = sampling_frequency - if_freq_actual;
2942cd7a67a4SMauro Carvalho Chehab adc_flip = true;
29439a0bf528SMauro Carvalho Chehab } else {
29449a0bf528SMauro Carvalho Chehab /* adc doesn't mirror */
2945cd7a67a4SMauro Carvalho Chehab adc_freq = if_freq_actual;
2946cd7a67a4SMauro Carvalho Chehab adc_flip = false;
29479a0bf528SMauro Carvalho Chehab }
29489a0bf528SMauro Carvalho Chehab
2949cd7a67a4SMauro Carvalho Chehab frequency_shift = adc_freq;
2950cd7a67a4SMauro Carvalho Chehab image_to_select = state->m_rfmirror ^ tuner_mirror ^
2951cd7a67a4SMauro Carvalho Chehab adc_flip ^ select_pos_image;
2952cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs =
2953cd7a67a4SMauro Carvalho Chehab Frac28a((frequency_shift), sampling_frequency);
29549a0bf528SMauro Carvalho Chehab
2955cd7a67a4SMauro Carvalho Chehab if (image_to_select)
2956cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
29579a0bf528SMauro Carvalho Chehab
29589a0bf528SMauro Carvalho Chehab /* Program frequency shifter with tuner offset compensation */
2959cd7a67a4SMauro Carvalho Chehab /* frequency_shift += tuner_freq_offset; TODO */
29609a0bf528SMauro Carvalho Chehab status = write32(state, IQM_FS_RATE_OFS_LO__A,
2961cd7a67a4SMauro Carvalho Chehab state->m_iqm_fs_rate_ofs);
29629a0bf528SMauro Carvalho Chehab if (status < 0)
29633a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
29649a0bf528SMauro Carvalho Chehab return status;
29659a0bf528SMauro Carvalho Chehab }
29669a0bf528SMauro Carvalho Chehab
init_agc(struct drxk_state * state,bool is_dtv)2967cd7a67a4SMauro Carvalho Chehab static int init_agc(struct drxk_state *state, bool is_dtv)
29689a0bf528SMauro Carvalho Chehab {
2969cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt = 0;
2970cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_min = 0;
2971cd7a67a4SMauro Carvalho Chehab u16 ingain_tgt_max = 0;
2972cd7a67a4SMauro Carvalho Chehab u16 clp_cyclen = 0;
2973cd7a67a4SMauro Carvalho Chehab u16 clp_sum_min = 0;
2974cd7a67a4SMauro Carvalho Chehab u16 clp_dir_to = 0;
2975cd7a67a4SMauro Carvalho Chehab u16 sns_sum_min = 0;
2976cd7a67a4SMauro Carvalho Chehab u16 sns_sum_max = 0;
2977cd7a67a4SMauro Carvalho Chehab u16 clp_sum_max = 0;
2978cd7a67a4SMauro Carvalho Chehab u16 sns_dir_to = 0;
2979cd7a67a4SMauro Carvalho Chehab u16 ki_innergain_min = 0;
2980cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt = 0;
2981cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_min = 0;
2982cd7a67a4SMauro Carvalho Chehab u16 if_iaccu_hi_tgt_max = 0;
29839a0bf528SMauro Carvalho Chehab u16 data = 0;
2984cd7a67a4SMauro Carvalho Chehab u16 fast_clp_ctrl_delay = 0;
2985cd7a67a4SMauro Carvalho Chehab u16 clp_ctrl_mode = 0;
29869a0bf528SMauro Carvalho Chehab int status = 0;
29879a0bf528SMauro Carvalho Chehab
29889a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
29899a0bf528SMauro Carvalho Chehab
29909a0bf528SMauro Carvalho Chehab /* Common settings */
2991cd7a67a4SMauro Carvalho Chehab sns_sum_max = 1023;
2992cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_min = 2047;
2993cd7a67a4SMauro Carvalho Chehab clp_cyclen = 500;
2994cd7a67a4SMauro Carvalho Chehab clp_sum_max = 1023;
29959a0bf528SMauro Carvalho Chehab
29969a0bf528SMauro Carvalho Chehab /* AGCInit() not available for DVBT; init done in microcode */
2997cd7a67a4SMauro Carvalho Chehab if (!is_qam(state)) {
29983a4398f5SMauro Carvalho Chehab pr_err("%s: mode %d is not DVB-C\n",
29993a4398f5SMauro Carvalho Chehab __func__, state->m_operation_mode);
30009a0bf528SMauro Carvalho Chehab return -EINVAL;
30019a0bf528SMauro Carvalho Chehab }
30029a0bf528SMauro Carvalho Chehab
30039a0bf528SMauro Carvalho Chehab /* FIXME: Analog TV AGC require different settings */
30049a0bf528SMauro Carvalho Chehab
30059a0bf528SMauro Carvalho Chehab /* Standard specific settings */
3006cd7a67a4SMauro Carvalho Chehab clp_sum_min = 8;
3007cd7a67a4SMauro Carvalho Chehab clp_dir_to = (u16) -9;
3008cd7a67a4SMauro Carvalho Chehab clp_ctrl_mode = 0;
3009cd7a67a4SMauro Carvalho Chehab sns_sum_min = 8;
3010cd7a67a4SMauro Carvalho Chehab sns_dir_to = (u16) -9;
3011cd7a67a4SMauro Carvalho Chehab ki_innergain_min = (u16) -1030;
3012cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt_max = 0x2380;
3013cd7a67a4SMauro Carvalho Chehab if_iaccu_hi_tgt = 0x2380;
3014cd7a67a4SMauro Carvalho Chehab ingain_tgt_min = 0x0511;
3015cd7a67a4SMauro Carvalho Chehab ingain_tgt = 0x0511;
3016cd7a67a4SMauro Carvalho Chehab ingain_tgt_max = 5119;
3017cd7a67a4SMauro Carvalho Chehab fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
30189a0bf528SMauro Carvalho Chehab
3019ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3020ab5060cdSMauro Carvalho Chehab fast_clp_ctrl_delay);
30219a0bf528SMauro Carvalho Chehab if (status < 0)
30229a0bf528SMauro Carvalho Chehab goto error;
30239a0bf528SMauro Carvalho Chehab
3024cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
30259a0bf528SMauro Carvalho Chehab if (status < 0)
30269a0bf528SMauro Carvalho Chehab goto error;
3027cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
30289a0bf528SMauro Carvalho Chehab if (status < 0)
30299a0bf528SMauro Carvalho Chehab goto error;
3030cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
30319a0bf528SMauro Carvalho Chehab if (status < 0)
30329a0bf528SMauro Carvalho Chehab goto error;
3033cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
30349a0bf528SMauro Carvalho Chehab if (status < 0)
30359a0bf528SMauro Carvalho Chehab goto error;
3036ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
3037ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_min);
30389a0bf528SMauro Carvalho Chehab if (status < 0)
30399a0bf528SMauro Carvalho Chehab goto error;
3040ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
3041ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt_max);
30429a0bf528SMauro Carvalho Chehab if (status < 0)
30439a0bf528SMauro Carvalho Chehab goto error;
30449a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
30459a0bf528SMauro Carvalho Chehab if (status < 0)
30469a0bf528SMauro Carvalho Chehab goto error;
30479a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
30489a0bf528SMauro Carvalho Chehab if (status < 0)
30499a0bf528SMauro Carvalho Chehab goto error;
30509a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
30519a0bf528SMauro Carvalho Chehab if (status < 0)
30529a0bf528SMauro Carvalho Chehab goto error;
30539a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
30549a0bf528SMauro Carvalho Chehab if (status < 0)
30559a0bf528SMauro Carvalho Chehab goto error;
3056cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
30579a0bf528SMauro Carvalho Chehab if (status < 0)
30589a0bf528SMauro Carvalho Chehab goto error;
3059cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
30609a0bf528SMauro Carvalho Chehab if (status < 0)
30619a0bf528SMauro Carvalho Chehab goto error;
30629a0bf528SMauro Carvalho Chehab
3063ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
3064ab5060cdSMauro Carvalho Chehab ki_innergain_min);
30659a0bf528SMauro Carvalho Chehab if (status < 0)
30669a0bf528SMauro Carvalho Chehab goto error;
3067ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
3068ab5060cdSMauro Carvalho Chehab if_iaccu_hi_tgt);
30699a0bf528SMauro Carvalho Chehab if (status < 0)
30709a0bf528SMauro Carvalho Chehab goto error;
3071cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
30729a0bf528SMauro Carvalho Chehab if (status < 0)
30739a0bf528SMauro Carvalho Chehab goto error;
30749a0bf528SMauro Carvalho Chehab
30759a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
30769a0bf528SMauro Carvalho Chehab if (status < 0)
30779a0bf528SMauro Carvalho Chehab goto error;
30789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
30799a0bf528SMauro Carvalho Chehab if (status < 0)
30809a0bf528SMauro Carvalho Chehab goto error;
30819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
30829a0bf528SMauro Carvalho Chehab if (status < 0)
30839a0bf528SMauro Carvalho Chehab goto error;
30849a0bf528SMauro Carvalho Chehab
30859a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
30869a0bf528SMauro Carvalho Chehab if (status < 0)
30879a0bf528SMauro Carvalho Chehab goto error;
3088cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
30899a0bf528SMauro Carvalho Chehab if (status < 0)
30909a0bf528SMauro Carvalho Chehab goto error;
3091cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
30929a0bf528SMauro Carvalho Chehab if (status < 0)
30939a0bf528SMauro Carvalho Chehab goto error;
3094cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
30959a0bf528SMauro Carvalho Chehab if (status < 0)
30969a0bf528SMauro Carvalho Chehab goto error;
3097cd7a67a4SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
30989a0bf528SMauro Carvalho Chehab if (status < 0)
30999a0bf528SMauro Carvalho Chehab goto error;
31009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
31019a0bf528SMauro Carvalho Chehab if (status < 0)
31029a0bf528SMauro Carvalho Chehab goto error;
31039a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
31049a0bf528SMauro Carvalho Chehab if (status < 0)
31059a0bf528SMauro Carvalho Chehab goto error;
31069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
31079a0bf528SMauro Carvalho Chehab if (status < 0)
31089a0bf528SMauro Carvalho Chehab goto error;
31099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
31109a0bf528SMauro Carvalho Chehab if (status < 0)
31119a0bf528SMauro Carvalho Chehab goto error;
31129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
31139a0bf528SMauro Carvalho Chehab if (status < 0)
31149a0bf528SMauro Carvalho Chehab goto error;
31159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
31169a0bf528SMauro Carvalho Chehab if (status < 0)
31179a0bf528SMauro Carvalho Chehab goto error;
31189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
31199a0bf528SMauro Carvalho Chehab if (status < 0)
31209a0bf528SMauro Carvalho Chehab goto error;
31219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
31229a0bf528SMauro Carvalho Chehab if (status < 0)
31239a0bf528SMauro Carvalho Chehab goto error;
31249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
31259a0bf528SMauro Carvalho Chehab if (status < 0)
31269a0bf528SMauro Carvalho Chehab goto error;
31279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
31289a0bf528SMauro Carvalho Chehab if (status < 0)
31299a0bf528SMauro Carvalho Chehab goto error;
31309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
31319a0bf528SMauro Carvalho Chehab if (status < 0)
31329a0bf528SMauro Carvalho Chehab goto error;
31339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
31349a0bf528SMauro Carvalho Chehab if (status < 0)
31359a0bf528SMauro Carvalho Chehab goto error;
31369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
31379a0bf528SMauro Carvalho Chehab if (status < 0)
31389a0bf528SMauro Carvalho Chehab goto error;
31399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
31409a0bf528SMauro Carvalho Chehab if (status < 0)
31419a0bf528SMauro Carvalho Chehab goto error;
31429a0bf528SMauro Carvalho Chehab
31439a0bf528SMauro Carvalho Chehab /* Initialize inner-loop KI gain factors */
31449a0bf528SMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_KI__A, &data);
31459a0bf528SMauro Carvalho Chehab if (status < 0)
31469a0bf528SMauro Carvalho Chehab goto error;
31479a0bf528SMauro Carvalho Chehab
31489a0bf528SMauro Carvalho Chehab data = 0x0657;
31499a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_RF__M;
31509a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
31519a0bf528SMauro Carvalho Chehab data &= ~SCU_RAM_AGC_KI_IF__M;
31529a0bf528SMauro Carvalho Chehab data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
31539a0bf528SMauro Carvalho Chehab
31549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_KI__A, data);
31559a0bf528SMauro Carvalho Chehab error:
31569a0bf528SMauro Carvalho Chehab if (status < 0)
31573a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
31589a0bf528SMauro Carvalho Chehab return status;
31599a0bf528SMauro Carvalho Chehab }
31609a0bf528SMauro Carvalho Chehab
dvbtqam_get_acc_pkt_err(struct drxk_state * state,u16 * packet_err)3161cd7a67a4SMauro Carvalho Chehab static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
31629a0bf528SMauro Carvalho Chehab {
31639a0bf528SMauro Carvalho Chehab int status;
31649a0bf528SMauro Carvalho Chehab
31659a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
3166cd7a67a4SMauro Carvalho Chehab if (packet_err == NULL)
31679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
31689a0bf528SMauro Carvalho Chehab else
3169ab5060cdSMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
3170ab5060cdSMauro Carvalho Chehab packet_err);
31719a0bf528SMauro Carvalho Chehab if (status < 0)
31723a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
31739a0bf528SMauro Carvalho Chehab return status;
31749a0bf528SMauro Carvalho Chehab }
31759a0bf528SMauro Carvalho Chehab
dvbt_sc_command(struct drxk_state * state,u16 cmd,u16 subcmd,u16 param0,u16 param1,u16 param2,u16 param3,u16 param4)3176cd7a67a4SMauro Carvalho Chehab static int dvbt_sc_command(struct drxk_state *state,
31779a0bf528SMauro Carvalho Chehab u16 cmd, u16 subcmd,
31789a0bf528SMauro Carvalho Chehab u16 param0, u16 param1, u16 param2,
31799a0bf528SMauro Carvalho Chehab u16 param3, u16 param4)
31809a0bf528SMauro Carvalho Chehab {
3181cd7a67a4SMauro Carvalho Chehab u16 cur_cmd = 0;
3182cd7a67a4SMauro Carvalho Chehab u16 err_code = 0;
3183cd7a67a4SMauro Carvalho Chehab u16 retry_cnt = 0;
3184cd7a67a4SMauro Carvalho Chehab u16 sc_exec = 0;
31859a0bf528SMauro Carvalho Chehab int status;
31869a0bf528SMauro Carvalho Chehab
31879a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
3188cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
3189cd7a67a4SMauro Carvalho Chehab if (sc_exec != 1) {
31909a0bf528SMauro Carvalho Chehab /* SC is not running */
31919a0bf528SMauro Carvalho Chehab status = -EINVAL;
31929a0bf528SMauro Carvalho Chehab }
31939a0bf528SMauro Carvalho Chehab if (status < 0)
31949a0bf528SMauro Carvalho Chehab goto error;
31959a0bf528SMauro Carvalho Chehab
31969a0bf528SMauro Carvalho Chehab /* Wait until sc is ready to receive command */
3197cd7a67a4SMauro Carvalho Chehab retry_cnt = 0;
31989a0bf528SMauro Carvalho Chehab do {
3199b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
3200cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3201cd7a67a4SMauro Carvalho Chehab retry_cnt++;
3202cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3203cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32049a0bf528SMauro Carvalho Chehab goto error;
32059a0bf528SMauro Carvalho Chehab
32069a0bf528SMauro Carvalho Chehab /* Write sub-command */
32079a0bf528SMauro Carvalho Chehab switch (cmd) {
32089a0bf528SMauro Carvalho Chehab /* All commands using sub-cmd */
32099a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START:
32109a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32119a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32129a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
32139a0bf528SMauro Carvalho Chehab if (status < 0)
32149a0bf528SMauro Carvalho Chehab goto error;
32159a0bf528SMauro Carvalho Chehab break;
32169a0bf528SMauro Carvalho Chehab default:
32179a0bf528SMauro Carvalho Chehab /* Do nothing */
32189a0bf528SMauro Carvalho Chehab break;
32199a0bf528SMauro Carvalho Chehab }
32209a0bf528SMauro Carvalho Chehab
32219a0bf528SMauro Carvalho Chehab /* Write needed parameters and the command */
32222f60f13cSMauro Carvalho Chehab status = 0;
32239a0bf528SMauro Carvalho Chehab switch (cmd) {
32249a0bf528SMauro Carvalho Chehab /* All commands using 5 parameters */
32259a0bf528SMauro Carvalho Chehab /* All commands using 4 parameters */
32269a0bf528SMauro Carvalho Chehab /* All commands using 3 parameters */
32279a0bf528SMauro Carvalho Chehab /* All commands using 2 parameters */
32289a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START:
32299a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32309a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32312f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
3232df561f66SGustavo A. R. Silva fallthrough; /* All commands using 1 parameters */
32339a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32349a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO:
32352f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
3236df561f66SGustavo A. R. Silva fallthrough; /* All commands using 0 parameters */
32379a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32389a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL:
32399a0bf528SMauro Carvalho Chehab /* Write command */
32402f60f13cSMauro Carvalho Chehab status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
32419a0bf528SMauro Carvalho Chehab break;
32429a0bf528SMauro Carvalho Chehab default:
32439a0bf528SMauro Carvalho Chehab /* Unknown command */
32449a0bf528SMauro Carvalho Chehab status = -EINVAL;
32459a0bf528SMauro Carvalho Chehab }
32469a0bf528SMauro Carvalho Chehab if (status < 0)
32479a0bf528SMauro Carvalho Chehab goto error;
32489a0bf528SMauro Carvalho Chehab
32499a0bf528SMauro Carvalho Chehab /* Wait until sc is ready processing command */
3250cd7a67a4SMauro Carvalho Chehab retry_cnt = 0;
32519a0bf528SMauro Carvalho Chehab do {
3252b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
3253cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
3254cd7a67a4SMauro Carvalho Chehab retry_cnt++;
3255cd7a67a4SMauro Carvalho Chehab } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
3256cd7a67a4SMauro Carvalho Chehab if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
32579a0bf528SMauro Carvalho Chehab goto error;
32589a0bf528SMauro Carvalho Chehab
32599a0bf528SMauro Carvalho Chehab /* Check for illegal cmd */
3260cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
3261cd7a67a4SMauro Carvalho Chehab if (err_code == 0xFFFF) {
32629a0bf528SMauro Carvalho Chehab /* illegal command */
32639a0bf528SMauro Carvalho Chehab status = -EINVAL;
32649a0bf528SMauro Carvalho Chehab }
32659a0bf528SMauro Carvalho Chehab if (status < 0)
32669a0bf528SMauro Carvalho Chehab goto error;
32679a0bf528SMauro Carvalho Chehab
326839c1cb2bSJonathan McCrohan /* Retrieve results parameters from SC */
32699a0bf528SMauro Carvalho Chehab switch (cmd) {
32709a0bf528SMauro Carvalho Chehab /* All commands yielding 5 results */
32719a0bf528SMauro Carvalho Chehab /* All commands yielding 4 results */
32729a0bf528SMauro Carvalho Chehab /* All commands yielding 3 results */
32739a0bf528SMauro Carvalho Chehab /* All commands yielding 2 results */
32749a0bf528SMauro Carvalho Chehab /* All commands yielding 1 result */
32759a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_USER_IO:
32769a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
32779a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
3278af7ab662SGustavo A. R. Silva break;
32799a0bf528SMauro Carvalho Chehab /* All commands yielding 0 results */
32809a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
32819a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_TIMER:
32829a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROC_START:
32839a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
32849a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
32859a0bf528SMauro Carvalho Chehab case OFDM_SC_RA_RAM_CMD_NULL:
32869a0bf528SMauro Carvalho Chehab break;
32879a0bf528SMauro Carvalho Chehab default:
32889a0bf528SMauro Carvalho Chehab /* Unknown command */
32899a0bf528SMauro Carvalho Chehab status = -EINVAL;
32909a0bf528SMauro Carvalho Chehab break;
32919a0bf528SMauro Carvalho Chehab } /* switch (cmd->cmd) */
32929a0bf528SMauro Carvalho Chehab error:
32939a0bf528SMauro Carvalho Chehab if (status < 0)
32943a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
32959a0bf528SMauro Carvalho Chehab return status;
32969a0bf528SMauro Carvalho Chehab }
32979a0bf528SMauro Carvalho Chehab
power_up_dvbt(struct drxk_state * state)3298cd7a67a4SMauro Carvalho Chehab static int power_up_dvbt(struct drxk_state *state)
32999a0bf528SMauro Carvalho Chehab {
3300cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRX_POWER_UP;
33019a0bf528SMauro Carvalho Chehab int status;
33029a0bf528SMauro Carvalho Chehab
33039a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
3304cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode);
33059a0bf528SMauro Carvalho Chehab if (status < 0)
33063a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
33079a0bf528SMauro Carvalho Chehab return status;
33089a0bf528SMauro Carvalho Chehab }
33099a0bf528SMauro Carvalho Chehab
dvbt_ctrl_set_inc_enable(struct drxk_state * state,bool * enabled)3310cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
33119a0bf528SMauro Carvalho Chehab {
33129a0bf528SMauro Carvalho Chehab int status;
33139a0bf528SMauro Carvalho Chehab
33149a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
33155a7f7b79SMauro Carvalho Chehab if (*enabled)
33169a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 0);
33179a0bf528SMauro Carvalho Chehab else
33189a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1);
33199a0bf528SMauro Carvalho Chehab if (status < 0)
33203a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
33219a0bf528SMauro Carvalho Chehab return status;
33229a0bf528SMauro Carvalho Chehab }
33239a0bf528SMauro Carvalho Chehab
33249a0bf528SMauro Carvalho Chehab #define DEFAULT_FR_THRES_8K 4000
dvbt_ctrl_set_fr_enable(struct drxk_state * state,bool * enabled)3325cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
33269a0bf528SMauro Carvalho Chehab {
33279a0bf528SMauro Carvalho Chehab
33289a0bf528SMauro Carvalho Chehab int status;
33299a0bf528SMauro Carvalho Chehab
33309a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
33315a7f7b79SMauro Carvalho Chehab if (*enabled) {
33329a0bf528SMauro Carvalho Chehab /* write mask to 1 */
33339a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
33349a0bf528SMauro Carvalho Chehab DEFAULT_FR_THRES_8K);
33359a0bf528SMauro Carvalho Chehab } else {
33369a0bf528SMauro Carvalho Chehab /* write mask to 0 */
33379a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
33389a0bf528SMauro Carvalho Chehab }
33399a0bf528SMauro Carvalho Chehab if (status < 0)
33403a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
33419a0bf528SMauro Carvalho Chehab
33429a0bf528SMauro Carvalho Chehab return status;
33439a0bf528SMauro Carvalho Chehab }
33449a0bf528SMauro Carvalho Chehab
dvbt_ctrl_set_echo_threshold(struct drxk_state * state,struct drxk_cfg_dvbt_echo_thres_t * echo_thres)3345cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
3346cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
33479a0bf528SMauro Carvalho Chehab {
33489a0bf528SMauro Carvalho Chehab u16 data = 0;
33499a0bf528SMauro Carvalho Chehab int status;
33509a0bf528SMauro Carvalho Chehab
33519a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
33529a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
33539a0bf528SMauro Carvalho Chehab if (status < 0)
33549a0bf528SMauro Carvalho Chehab goto error;
33559a0bf528SMauro Carvalho Chehab
3356cd7a67a4SMauro Carvalho Chehab switch (echo_thres->fft_mode) {
33579a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_2K:
33589a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3359cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold <<
33609a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
33619a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
33629a0bf528SMauro Carvalho Chehab break;
33639a0bf528SMauro Carvalho Chehab case DRX_FFTMODE_8K:
33649a0bf528SMauro Carvalho Chehab data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3365cd7a67a4SMauro Carvalho Chehab data |= ((echo_thres->threshold <<
33669a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
33679a0bf528SMauro Carvalho Chehab & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
33689a0bf528SMauro Carvalho Chehab break;
33699a0bf528SMauro Carvalho Chehab default:
33709a0bf528SMauro Carvalho Chehab return -EINVAL;
33719a0bf528SMauro Carvalho Chehab }
33729a0bf528SMauro Carvalho Chehab
33739a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
33749a0bf528SMauro Carvalho Chehab error:
33759a0bf528SMauro Carvalho Chehab if (status < 0)
33763a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
33779a0bf528SMauro Carvalho Chehab return status;
33789a0bf528SMauro Carvalho Chehab }
33799a0bf528SMauro Carvalho Chehab
dvbt_ctrl_set_sqi_speed(struct drxk_state * state,enum drxk_cfg_dvbt_sqi_speed * speed)3380cd7a67a4SMauro Carvalho Chehab static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
3381cd7a67a4SMauro Carvalho Chehab enum drxk_cfg_dvbt_sqi_speed *speed)
33829a0bf528SMauro Carvalho Chehab {
33839a0bf528SMauro Carvalho Chehab int status = -EINVAL;
33849a0bf528SMauro Carvalho Chehab
33859a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
33869a0bf528SMauro Carvalho Chehab
33879a0bf528SMauro Carvalho Chehab switch (*speed) {
33889a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_FAST:
33899a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_MEDIUM:
33909a0bf528SMauro Carvalho Chehab case DRXK_DVBT_SQI_SPEED_SLOW:
33919a0bf528SMauro Carvalho Chehab break;
33929a0bf528SMauro Carvalho Chehab default:
33939a0bf528SMauro Carvalho Chehab goto error;
33949a0bf528SMauro Carvalho Chehab }
33959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
33969a0bf528SMauro Carvalho Chehab (u16) *speed);
33979a0bf528SMauro Carvalho Chehab error:
33989a0bf528SMauro Carvalho Chehab if (status < 0)
33993a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
34009a0bf528SMauro Carvalho Chehab return status;
34019a0bf528SMauro Carvalho Chehab }
34029a0bf528SMauro Carvalho Chehab
34039a0bf528SMauro Carvalho Chehab /*============================================================================*/
34049a0bf528SMauro Carvalho Chehab
340534eb9751SMauro Carvalho Chehab /*
34069a0bf528SMauro Carvalho Chehab * \brief Activate DVBT specific presets
34079a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34089a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34099a0bf528SMauro Carvalho Chehab *
34109a0bf528SMauro Carvalho Chehab * Called in DVBTSetStandard
34119a0bf528SMauro Carvalho Chehab *
34129a0bf528SMauro Carvalho Chehab */
dvbt_activate_presets(struct drxk_state * state)3413cd7a67a4SMauro Carvalho Chehab static int dvbt_activate_presets(struct drxk_state *state)
34149a0bf528SMauro Carvalho Chehab {
34159a0bf528SMauro Carvalho Chehab int status;
34169a0bf528SMauro Carvalho Chehab bool setincenable = false;
34179a0bf528SMauro Carvalho Chehab bool setfrenable = true;
34189a0bf528SMauro Carvalho Chehab
3419cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
3420cd7a67a4SMauro Carvalho Chehab struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
34219a0bf528SMauro Carvalho Chehab
34229a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
3423cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_inc_enable(state, &setincenable);
34249a0bf528SMauro Carvalho Chehab if (status < 0)
34259a0bf528SMauro Carvalho Chehab goto error;
3426cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
34279a0bf528SMauro Carvalho Chehab if (status < 0)
34289a0bf528SMauro Carvalho Chehab goto error;
3429cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
34309a0bf528SMauro Carvalho Chehab if (status < 0)
34319a0bf528SMauro Carvalho Chehab goto error;
3432cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
34339a0bf528SMauro Carvalho Chehab if (status < 0)
34349a0bf528SMauro Carvalho Chehab goto error;
3435ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
3436ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.ingain_tgt_max);
34379a0bf528SMauro Carvalho Chehab error:
34389a0bf528SMauro Carvalho Chehab if (status < 0)
34393a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
34409a0bf528SMauro Carvalho Chehab return status;
34419a0bf528SMauro Carvalho Chehab }
34429a0bf528SMauro Carvalho Chehab
34439a0bf528SMauro Carvalho Chehab /*============================================================================*/
34449a0bf528SMauro Carvalho Chehab
344534eb9751SMauro Carvalho Chehab /*
34469a0bf528SMauro Carvalho Chehab * \brief Initialize channelswitch-independent settings for DVBT.
34479a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
34489a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
34499a0bf528SMauro Carvalho Chehab *
34509a0bf528SMauro Carvalho Chehab * For ROM code channel filter taps are loaded from the bootloader. For microcode
34519a0bf528SMauro Carvalho Chehab * the DVB-T taps from the drxk_filters.h are used.
34529a0bf528SMauro Carvalho Chehab */
set_dvbt_standard(struct drxk_state * state,enum operation_mode o_mode)3453cd7a67a4SMauro Carvalho Chehab static int set_dvbt_standard(struct drxk_state *state,
3454cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode)
34559a0bf528SMauro Carvalho Chehab {
3456cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0;
34579a0bf528SMauro Carvalho Chehab u16 data = 0;
34589a0bf528SMauro Carvalho Chehab int status;
34599a0bf528SMauro Carvalho Chehab
34609a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
34619a0bf528SMauro Carvalho Chehab
3462cd7a67a4SMauro Carvalho Chehab power_up_dvbt(state);
34639a0bf528SMauro Carvalho Chehab /* added antenna switch */
3464cd7a67a4SMauro Carvalho Chehab switch_antenna_to_dvbt(state);
34659a0bf528SMauro Carvalho Chehab /* send OFDM reset command */
3466ab5060cdSMauro Carvalho Chehab status = scu_command(state,
3467ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_OFDM
3468ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
3469ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
34709a0bf528SMauro Carvalho Chehab if (status < 0)
34719a0bf528SMauro Carvalho Chehab goto error;
34729a0bf528SMauro Carvalho Chehab
34739a0bf528SMauro Carvalho Chehab /* send OFDM setenv command */
3474ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3475ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
3476ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
34779a0bf528SMauro Carvalho Chehab if (status < 0)
34789a0bf528SMauro Carvalho Chehab goto error;
34799a0bf528SMauro Carvalho Chehab
34809a0bf528SMauro Carvalho Chehab /* reset datapath for OFDM, processors first */
34819a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
34829a0bf528SMauro Carvalho Chehab if (status < 0)
34839a0bf528SMauro Carvalho Chehab goto error;
34849a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
34859a0bf528SMauro Carvalho Chehab if (status < 0)
34869a0bf528SMauro Carvalho Chehab goto error;
34879a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
34889a0bf528SMauro Carvalho Chehab if (status < 0)
34899a0bf528SMauro Carvalho Chehab goto error;
34909a0bf528SMauro Carvalho Chehab
34919a0bf528SMauro Carvalho Chehab /* IQM setup */
34929a0bf528SMauro Carvalho Chehab /* synchronize on ofdstate->m_festart */
34939a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 1);
34949a0bf528SMauro Carvalho Chehab if (status < 0)
34959a0bf528SMauro Carvalho Chehab goto error;
34969a0bf528SMauro Carvalho Chehab /* window size for clipping ADC detection */
34979a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0);
34989a0bf528SMauro Carvalho Chehab if (status < 0)
34999a0bf528SMauro Carvalho Chehab goto error;
350073854b86SJason Wang /* window size for sense pre-SAW detection */
35019a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0);
35029a0bf528SMauro Carvalho Chehab if (status < 0)
35039a0bf528SMauro Carvalho Chehab goto error;
35049a0bf528SMauro Carvalho Chehab /* sense threshold for sense pre-SAW detection */
35059a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
35069a0bf528SMauro Carvalho Chehab if (status < 0)
35079a0bf528SMauro Carvalho Chehab goto error;
3508cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true);
35099a0bf528SMauro Carvalho Chehab if (status < 0)
35109a0bf528SMauro Carvalho Chehab goto error;
35119a0bf528SMauro Carvalho Chehab
35129a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AGC_RF__A, 0);
35139a0bf528SMauro Carvalho Chehab if (status < 0)
35149a0bf528SMauro Carvalho Chehab goto error;
35159a0bf528SMauro Carvalho Chehab
35169a0bf528SMauro Carvalho Chehab /* Impulse noise cruncher setup */
35179a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
35189a0bf528SMauro Carvalho Chehab if (status < 0)
35199a0bf528SMauro Carvalho Chehab goto error;
35209a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
35219a0bf528SMauro Carvalho Chehab if (status < 0)
35229a0bf528SMauro Carvalho Chehab goto error;
35239a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
35249a0bf528SMauro Carvalho Chehab if (status < 0)
35259a0bf528SMauro Carvalho Chehab goto error;
35269a0bf528SMauro Carvalho Chehab
35279a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 16);
35289a0bf528SMauro Carvalho Chehab if (status < 0)
35299a0bf528SMauro Carvalho Chehab goto error;
35309a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
35319a0bf528SMauro Carvalho Chehab if (status < 0)
35329a0bf528SMauro Carvalho Chehab goto error;
35339a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
35349a0bf528SMauro Carvalho Chehab if (status < 0)
35359a0bf528SMauro Carvalho Chehab goto error;
35369a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE__A, 1600);
35379a0bf528SMauro Carvalho Chehab if (status < 0)
35389a0bf528SMauro Carvalho Chehab goto error;
35399a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, 0);
35409a0bf528SMauro Carvalho Chehab if (status < 0)
35419a0bf528SMauro Carvalho Chehab goto error;
35429a0bf528SMauro Carvalho Chehab
35439a0bf528SMauro Carvalho Chehab /* virtual clipping threshold for clipping ADC detection */
35449a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448);
35459a0bf528SMauro Carvalho Chehab if (status < 0)
35469a0bf528SMauro Carvalho Chehab goto error;
35479a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
35489a0bf528SMauro Carvalho Chehab if (status < 0)
35499a0bf528SMauro Carvalho Chehab goto error;
35509a0bf528SMauro Carvalho Chehab
3551ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
3552ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
35539a0bf528SMauro Carvalho Chehab if (status < 0)
35549a0bf528SMauro Carvalho Chehab goto error;
35559a0bf528SMauro Carvalho Chehab
35569a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
35579a0bf528SMauro Carvalho Chehab if (status < 0)
35589a0bf528SMauro Carvalho Chehab goto error;
35599a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
35609a0bf528SMauro Carvalho Chehab if (status < 0)
35619a0bf528SMauro Carvalho Chehab goto error;
35629a0bf528SMauro Carvalho Chehab /* enable power measurement interrupt */
35639a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
35649a0bf528SMauro Carvalho Chehab if (status < 0)
35659a0bf528SMauro Carvalho Chehab goto error;
35669a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
35679a0bf528SMauro Carvalho Chehab if (status < 0)
35689a0bf528SMauro Carvalho Chehab goto error;
35699a0bf528SMauro Carvalho Chehab
35709a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */
3571cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state);
35729a0bf528SMauro Carvalho Chehab if (status < 0)
35739a0bf528SMauro Carvalho Chehab goto error;
3574cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
35759a0bf528SMauro Carvalho Chehab if (status < 0)
35769a0bf528SMauro Carvalho Chehab goto error;
35779a0bf528SMauro Carvalho Chehab
35789a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */
35799a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
35809a0bf528SMauro Carvalho Chehab if (status < 0)
35819a0bf528SMauro Carvalho Chehab goto error;
35829a0bf528SMauro Carvalho Chehab
3583cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
35849a0bf528SMauro Carvalho Chehab if (status < 0)
35859a0bf528SMauro Carvalho Chehab goto error;
3586cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
35879a0bf528SMauro Carvalho Chehab if (status < 0)
35889a0bf528SMauro Carvalho Chehab goto error;
35899a0bf528SMauro Carvalho Chehab
35909a0bf528SMauro Carvalho Chehab /* Set Noise Estimation notch width and enable DC fix */
35919a0bf528SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
35929a0bf528SMauro Carvalho Chehab if (status < 0)
35939a0bf528SMauro Carvalho Chehab goto error;
35949a0bf528SMauro Carvalho Chehab data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
35959a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
35969a0bf528SMauro Carvalho Chehab if (status < 0)
35979a0bf528SMauro Carvalho Chehab goto error;
35989a0bf528SMauro Carvalho Chehab
35999a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */
36009a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
36019a0bf528SMauro Carvalho Chehab if (status < 0)
36029a0bf528SMauro Carvalho Chehab goto error;
36039a0bf528SMauro Carvalho Chehab
3604cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code) {
3605cd7a67a4SMauro Carvalho Chehab /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */
3606ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
3607ab5060cdSMauro Carvalho Chehab state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
36089a0bf528SMauro Carvalho Chehab if (status < 0)
36099a0bf528SMauro Carvalho Chehab goto error;
36109a0bf528SMauro Carvalho Chehab }
36119a0bf528SMauro Carvalho Chehab
36129a0bf528SMauro Carvalho Chehab /* OFDM_SC setup */
36139a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36149a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
36159a0bf528SMauro Carvalho Chehab if (status < 0)
36169a0bf528SMauro Carvalho Chehab goto error;
36179a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
36189a0bf528SMauro Carvalho Chehab if (status < 0)
36199a0bf528SMauro Carvalho Chehab goto error;
36209a0bf528SMauro Carvalho Chehab #endif
36219a0bf528SMauro Carvalho Chehab
36229a0bf528SMauro Carvalho Chehab /* FEC setup */
36239a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
36249a0bf528SMauro Carvalho Chehab if (status < 0)
36259a0bf528SMauro Carvalho Chehab goto error;
36269a0bf528SMauro Carvalho Chehab
36279a0bf528SMauro Carvalho Chehab
36289a0bf528SMauro Carvalho Chehab #ifdef COMPILE_FOR_NONRT
36299a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
36309a0bf528SMauro Carvalho Chehab if (status < 0)
36319a0bf528SMauro Carvalho Chehab goto error;
36329a0bf528SMauro Carvalho Chehab #else
36339a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
36349a0bf528SMauro Carvalho Chehab if (status < 0)
36359a0bf528SMauro Carvalho Chehab goto error;
36369a0bf528SMauro Carvalho Chehab #endif
36379a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
36389a0bf528SMauro Carvalho Chehab if (status < 0)
36399a0bf528SMauro Carvalho Chehab goto error;
36409a0bf528SMauro Carvalho Chehab
36419a0bf528SMauro Carvalho Chehab /* Setup MPEG bus */
3642cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, OM_DVBT);
36439a0bf528SMauro Carvalho Chehab if (status < 0)
36449a0bf528SMauro Carvalho Chehab goto error;
36459a0bf528SMauro Carvalho Chehab /* Set DVBT Presets */
3646cd7a67a4SMauro Carvalho Chehab status = dvbt_activate_presets(state);
36479a0bf528SMauro Carvalho Chehab if (status < 0)
36489a0bf528SMauro Carvalho Chehab goto error;
36499a0bf528SMauro Carvalho Chehab
36509a0bf528SMauro Carvalho Chehab error:
36519a0bf528SMauro Carvalho Chehab if (status < 0)
36523a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
36539a0bf528SMauro Carvalho Chehab return status;
36549a0bf528SMauro Carvalho Chehab }
36559a0bf528SMauro Carvalho Chehab
36569a0bf528SMauro Carvalho Chehab /*============================================================================*/
365734eb9751SMauro Carvalho Chehab /*
3658cd7a67a4SMauro Carvalho Chehab * \brief start dvbt demodulating for channel.
36599a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
36609a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
36619a0bf528SMauro Carvalho Chehab */
dvbt_start(struct drxk_state * state)3662cd7a67a4SMauro Carvalho Chehab static int dvbt_start(struct drxk_state *state)
36639a0bf528SMauro Carvalho Chehab {
36649a0bf528SMauro Carvalho Chehab u16 param1;
36659a0bf528SMauro Carvalho Chehab int status;
3666cd7a67a4SMauro Carvalho Chehab /* drxk_ofdm_sc_cmd_t scCmd; */
36679a0bf528SMauro Carvalho Chehab
36689a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
3669cd7a67a4SMauro Carvalho Chehab /* start correct processes to get in lock */
36709a0bf528SMauro Carvalho Chehab /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
36719a0bf528SMauro Carvalho Chehab param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3672ab5060cdSMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
3673ab5060cdSMauro Carvalho Chehab OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
3674ab5060cdSMauro Carvalho Chehab 0, 0, 0);
36759a0bf528SMauro Carvalho Chehab if (status < 0)
36769a0bf528SMauro Carvalho Chehab goto error;
3677cd7a67a4SMauro Carvalho Chehab /* start FEC OC */
3678cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state);
36799a0bf528SMauro Carvalho Chehab if (status < 0)
36809a0bf528SMauro Carvalho Chehab goto error;
36819a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
36829a0bf528SMauro Carvalho Chehab if (status < 0)
36839a0bf528SMauro Carvalho Chehab goto error;
36849a0bf528SMauro Carvalho Chehab error:
36859a0bf528SMauro Carvalho Chehab if (status < 0)
36863a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
36879a0bf528SMauro Carvalho Chehab return status;
36889a0bf528SMauro Carvalho Chehab }
36899a0bf528SMauro Carvalho Chehab
36909a0bf528SMauro Carvalho Chehab
36919a0bf528SMauro Carvalho Chehab /*============================================================================*/
36929a0bf528SMauro Carvalho Chehab
369334eb9751SMauro Carvalho Chehab /*
36949a0bf528SMauro Carvalho Chehab * \brief Set up dvbt demodulator for channel.
36959a0bf528SMauro Carvalho Chehab * \param demod instance of demodulator.
36969a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
36979a0bf528SMauro Carvalho Chehab * // original DVBTSetChannel()
36989a0bf528SMauro Carvalho Chehab */
set_dvbt(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset)3699cd7a67a4SMauro Carvalho Chehab static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
3700cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset)
37019a0bf528SMauro Carvalho Chehab {
3702cd7a67a4SMauro Carvalho Chehab u16 cmd_result = 0;
3703cd7a67a4SMauro Carvalho Chehab u16 transmission_params = 0;
3704cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate_ofs = 0;
37059a0bf528SMauro Carvalho Chehab u32 bandwidth = 0;
37069a0bf528SMauro Carvalho Chehab u16 param1;
37079a0bf528SMauro Carvalho Chehab int status;
37089a0bf528SMauro Carvalho Chehab
3709ab5060cdSMauro Carvalho Chehab dprintk(1, "IF =%d, TFO = %d\n",
3710ab5060cdSMauro Carvalho Chehab intermediate_freqk_hz, tuner_freq_offset);
37119a0bf528SMauro Carvalho Chehab
3712ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
3713ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
3714ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
37159a0bf528SMauro Carvalho Chehab if (status < 0)
37169a0bf528SMauro Carvalho Chehab goto error;
37179a0bf528SMauro Carvalho Chehab
37189a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */
37199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
37209a0bf528SMauro Carvalho Chehab if (status < 0)
37219a0bf528SMauro Carvalho Chehab goto error;
37229a0bf528SMauro Carvalho Chehab
37239a0bf528SMauro Carvalho Chehab /* Stop processors */
37249a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
37259a0bf528SMauro Carvalho Chehab if (status < 0)
37269a0bf528SMauro Carvalho Chehab goto error;
37279a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
37289a0bf528SMauro Carvalho Chehab if (status < 0)
37299a0bf528SMauro Carvalho Chehab goto error;
37309a0bf528SMauro Carvalho Chehab
37319a0bf528SMauro Carvalho Chehab /* Mandatory fix, always stop CP, required to set spl offset back to
37329a0bf528SMauro Carvalho Chehab hardware default (is set to 0 by ucode during pilot detection */
37339a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
37349a0bf528SMauro Carvalho Chehab if (status < 0)
37359a0bf528SMauro Carvalho Chehab goto error;
37369a0bf528SMauro Carvalho Chehab
3737ab5060cdSMauro Carvalho Chehab /*== Write channel settings to device ================================*/
37389a0bf528SMauro Carvalho Chehab
37399a0bf528SMauro Carvalho Chehab /* mode */
37409a0bf528SMauro Carvalho Chehab switch (state->props.transmission_mode) {
37419a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_AUTO:
37429a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_8K:
37431cef3942SMauro Carvalho Chehab default:
3744cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
37459a0bf528SMauro Carvalho Chehab break;
37469a0bf528SMauro Carvalho Chehab case TRANSMISSION_MODE_2K:
3747cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
37489a0bf528SMauro Carvalho Chehab break;
37499a0bf528SMauro Carvalho Chehab }
37509a0bf528SMauro Carvalho Chehab
37519a0bf528SMauro Carvalho Chehab /* guard */
37529a0bf528SMauro Carvalho Chehab switch (state->props.guard_interval) {
37539a0bf528SMauro Carvalho Chehab default:
37541cef3942SMauro Carvalho Chehab case GUARD_INTERVAL_AUTO: /* try first guess DRX_GUARD_1DIV4 */
37559a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_4:
3756cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
37579a0bf528SMauro Carvalho Chehab break;
37589a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_32:
3759cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
37609a0bf528SMauro Carvalho Chehab break;
37619a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_16:
3762cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
37639a0bf528SMauro Carvalho Chehab break;
37649a0bf528SMauro Carvalho Chehab case GUARD_INTERVAL_1_8:
3765cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
37669a0bf528SMauro Carvalho Chehab break;
37679a0bf528SMauro Carvalho Chehab }
37689a0bf528SMauro Carvalho Chehab
37699a0bf528SMauro Carvalho Chehab /* hierarchy */
37709a0bf528SMauro Carvalho Chehab switch (state->props.hierarchy) {
37719a0bf528SMauro Carvalho Chehab case HIERARCHY_AUTO:
37729a0bf528SMauro Carvalho Chehab case HIERARCHY_NONE:
37731cef3942SMauro Carvalho Chehab default: /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
37749a0bf528SMauro Carvalho Chehab case HIERARCHY_1:
3775cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
37769a0bf528SMauro Carvalho Chehab break;
37779a0bf528SMauro Carvalho Chehab case HIERARCHY_2:
3778cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
37799a0bf528SMauro Carvalho Chehab break;
37809a0bf528SMauro Carvalho Chehab case HIERARCHY_4:
3781cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
37829a0bf528SMauro Carvalho Chehab break;
37839a0bf528SMauro Carvalho Chehab }
37849a0bf528SMauro Carvalho Chehab
37859a0bf528SMauro Carvalho Chehab
37869a0bf528SMauro Carvalho Chehab /* modulation */
37879a0bf528SMauro Carvalho Chehab switch (state->props.modulation) {
37889a0bf528SMauro Carvalho Chehab case QAM_AUTO:
37891cef3942SMauro Carvalho Chehab default: /* try first guess DRX_CONSTELLATION_QAM64 */
37909a0bf528SMauro Carvalho Chehab case QAM_64:
3791cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
37929a0bf528SMauro Carvalho Chehab break;
37939a0bf528SMauro Carvalho Chehab case QPSK:
3794cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
37959a0bf528SMauro Carvalho Chehab break;
37969a0bf528SMauro Carvalho Chehab case QAM_16:
3797cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
37989a0bf528SMauro Carvalho Chehab break;
37999a0bf528SMauro Carvalho Chehab }
38009a0bf528SMauro Carvalho Chehab #if 0
380139c1cb2bSJonathan McCrohan /* No hierarchical channels support in BDA */
38029a0bf528SMauro Carvalho Chehab /* Priority (only for hierarchical channels) */
38039a0bf528SMauro Carvalho Chehab switch (channel->priority) {
38049a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_LOW:
3805cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3806cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38079a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_LO);
38089a0bf528SMauro Carvalho Chehab break;
38099a0bf528SMauro Carvalho Chehab case DRX_PRIORITY_HIGH:
3810cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3811cd7a67a4SMauro Carvalho Chehab WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
38129a0bf528SMauro Carvalho Chehab OFDM_EC_SB_PRIOR_HI));
38139a0bf528SMauro Carvalho Chehab break;
3814df561f66SGustavo A. R. Silva case DRX_PRIORITY_UNKNOWN:
38159a0bf528SMauro Carvalho Chehab default:
38169a0bf528SMauro Carvalho Chehab status = -EINVAL;
38179a0bf528SMauro Carvalho Chehab goto error;
38189a0bf528SMauro Carvalho Chehab }
38199a0bf528SMauro Carvalho Chehab #else
3820868c9a17SMauro Carvalho Chehab /* Set Priority high */
3821cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
38229a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
38239a0bf528SMauro Carvalho Chehab if (status < 0)
38249a0bf528SMauro Carvalho Chehab goto error;
38259a0bf528SMauro Carvalho Chehab #endif
38269a0bf528SMauro Carvalho Chehab
38279a0bf528SMauro Carvalho Chehab /* coderate */
38289a0bf528SMauro Carvalho Chehab switch (state->props.code_rate_HP) {
38299a0bf528SMauro Carvalho Chehab case FEC_AUTO:
38301cef3942SMauro Carvalho Chehab default: /* try first guess DRX_CODERATE_2DIV3 */
38319a0bf528SMauro Carvalho Chehab case FEC_2_3:
3832cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
38339a0bf528SMauro Carvalho Chehab break;
38349a0bf528SMauro Carvalho Chehab case FEC_1_2:
3835cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
38369a0bf528SMauro Carvalho Chehab break;
38379a0bf528SMauro Carvalho Chehab case FEC_3_4:
3838cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
38399a0bf528SMauro Carvalho Chehab break;
38409a0bf528SMauro Carvalho Chehab case FEC_5_6:
3841cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
38429a0bf528SMauro Carvalho Chehab break;
38439a0bf528SMauro Carvalho Chehab case FEC_7_8:
3844cd7a67a4SMauro Carvalho Chehab transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
38459a0bf528SMauro Carvalho Chehab break;
38469a0bf528SMauro Carvalho Chehab }
38479a0bf528SMauro Carvalho Chehab
3848ab5060cdSMauro Carvalho Chehab /*
3849868c9a17SMauro Carvalho Chehab * SAW filter selection: normally not necessary, but if wanted
3850ab5060cdSMauro Carvalho Chehab * the application can select a SAW filter via the driver by
3851ab5060cdSMauro Carvalho Chehab * using UIOs
3852ab5060cdSMauro Carvalho Chehab */
3853ab5060cdSMauro Carvalho Chehab
38549a0bf528SMauro Carvalho Chehab /* First determine real bandwidth (Hz) */
38559a0bf528SMauro Carvalho Chehab /* Also set delay for impulse noise cruncher */
3856ab5060cdSMauro Carvalho Chehab /*
3857ab5060cdSMauro Carvalho Chehab * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
3858ab5060cdSMauro Carvalho Chehab * changed by SC for fix for some 8K,1/8 guard but is restored by
3859ab5060cdSMauro Carvalho Chehab * InitEC and ResetEC functions
3860ab5060cdSMauro Carvalho Chehab */
38619a0bf528SMauro Carvalho Chehab switch (state->props.bandwidth_hz) {
38629a0bf528SMauro Carvalho Chehab case 0:
38639a0bf528SMauro Carvalho Chehab state->props.bandwidth_hz = 8000000;
3864df561f66SGustavo A. R. Silva fallthrough;
38659a0bf528SMauro Carvalho Chehab case 8000000:
38669a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3867ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3868ab5060cdSMauro Carvalho Chehab 3052);
38699a0bf528SMauro Carvalho Chehab if (status < 0)
38709a0bf528SMauro Carvalho Chehab goto error;
38719a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 8 MHz */
3872ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3873ab5060cdSMauro Carvalho Chehab 7);
38749a0bf528SMauro Carvalho Chehab if (status < 0)
38759a0bf528SMauro Carvalho Chehab goto error;
3876ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3877ab5060cdSMauro Carvalho Chehab 7);
38789a0bf528SMauro Carvalho Chehab if (status < 0)
38799a0bf528SMauro Carvalho Chehab goto error;
3880ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3881ab5060cdSMauro Carvalho Chehab 7);
38829a0bf528SMauro Carvalho Chehab if (status < 0)
38839a0bf528SMauro Carvalho Chehab goto error;
3884ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3885ab5060cdSMauro Carvalho Chehab 1);
38869a0bf528SMauro Carvalho Chehab if (status < 0)
38879a0bf528SMauro Carvalho Chehab goto error;
38889a0bf528SMauro Carvalho Chehab break;
38899a0bf528SMauro Carvalho Chehab case 7000000:
38909a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3891ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3892ab5060cdSMauro Carvalho Chehab 3491);
38939a0bf528SMauro Carvalho Chehab if (status < 0)
38949a0bf528SMauro Carvalho Chehab goto error;
38959a0bf528SMauro Carvalho Chehab /* cochannel protection for PAL 7 MHz */
3896ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3897ab5060cdSMauro Carvalho Chehab 8);
38989a0bf528SMauro Carvalho Chehab if (status < 0)
38999a0bf528SMauro Carvalho Chehab goto error;
3900ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3901ab5060cdSMauro Carvalho Chehab 8);
39029a0bf528SMauro Carvalho Chehab if (status < 0)
39039a0bf528SMauro Carvalho Chehab goto error;
3904ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3905ab5060cdSMauro Carvalho Chehab 4);
39069a0bf528SMauro Carvalho Chehab if (status < 0)
39079a0bf528SMauro Carvalho Chehab goto error;
3908ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3909ab5060cdSMauro Carvalho Chehab 1);
39109a0bf528SMauro Carvalho Chehab if (status < 0)
39119a0bf528SMauro Carvalho Chehab goto error;
39129a0bf528SMauro Carvalho Chehab break;
39139a0bf528SMauro Carvalho Chehab case 6000000:
39149a0bf528SMauro Carvalho Chehab bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3915ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3916ab5060cdSMauro Carvalho Chehab 4073);
39179a0bf528SMauro Carvalho Chehab if (status < 0)
39189a0bf528SMauro Carvalho Chehab goto error;
39199a0bf528SMauro Carvalho Chehab /* cochannel protection for NTSC 6 MHz */
3920ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
3921ab5060cdSMauro Carvalho Chehab 19);
39229a0bf528SMauro Carvalho Chehab if (status < 0)
39239a0bf528SMauro Carvalho Chehab goto error;
3924ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
3925ab5060cdSMauro Carvalho Chehab 19);
39269a0bf528SMauro Carvalho Chehab if (status < 0)
39279a0bf528SMauro Carvalho Chehab goto error;
3928ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
3929ab5060cdSMauro Carvalho Chehab 14);
39309a0bf528SMauro Carvalho Chehab if (status < 0)
39319a0bf528SMauro Carvalho Chehab goto error;
3932ab5060cdSMauro Carvalho Chehab status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
3933ab5060cdSMauro Carvalho Chehab 1);
39349a0bf528SMauro Carvalho Chehab if (status < 0)
39359a0bf528SMauro Carvalho Chehab goto error;
39369a0bf528SMauro Carvalho Chehab break;
39379a0bf528SMauro Carvalho Chehab default:
39389a0bf528SMauro Carvalho Chehab status = -EINVAL;
39399a0bf528SMauro Carvalho Chehab goto error;
39409a0bf528SMauro Carvalho Chehab }
39419a0bf528SMauro Carvalho Chehab
3942cd7a67a4SMauro Carvalho Chehab if (iqm_rc_rate_ofs == 0) {
39439a0bf528SMauro Carvalho Chehab /* Now compute IQM_RC_RATE_OFS
39449a0bf528SMauro Carvalho Chehab (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
39459a0bf528SMauro Carvalho Chehab =>
39469a0bf528SMauro Carvalho Chehab ((SysFreq / BandWidth) * (2^21)) - (2^23)
39479a0bf528SMauro Carvalho Chehab */
39489a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^28) */
3949ab5060cdSMauro Carvalho Chehab /*
3950ab5060cdSMauro Carvalho Chehab * assert (MAX(sysClk)/MIN(bandwidth) < 16)
3951ab5060cdSMauro Carvalho Chehab * => assert(MAX(sysClk) < 16*MIN(bandwidth))
3952ab5060cdSMauro Carvalho Chehab * => assert(109714272 > 48000000) = true
3953ab5060cdSMauro Carvalho Chehab * so Frac 28 can be used
3954ab5060cdSMauro Carvalho Chehab */
3955cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = Frac28a((u32)
3956cd7a67a4SMauro Carvalho Chehab ((state->m_sys_clock_freq *
39579a0bf528SMauro Carvalho Chehab 1000) / 3), bandwidth);
39589a0bf528SMauro Carvalho Chehab /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
3959cd7a67a4SMauro Carvalho Chehab if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
3960cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs += 0x80L;
3961cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
39629a0bf528SMauro Carvalho Chehab /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
3963cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
39649a0bf528SMauro Carvalho Chehab }
39659a0bf528SMauro Carvalho Chehab
3966cd7a67a4SMauro Carvalho Chehab iqm_rc_rate_ofs &=
39679a0bf528SMauro Carvalho Chehab ((((u32) IQM_RC_RATE_OFS_HI__M) <<
39689a0bf528SMauro Carvalho Chehab IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
3969cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
39709a0bf528SMauro Carvalho Chehab if (status < 0)
39719a0bf528SMauro Carvalho Chehab goto error;
39729a0bf528SMauro Carvalho Chehab
39739a0bf528SMauro Carvalho Chehab /* Bandwidth setting done */
39749a0bf528SMauro Carvalho Chehab
39759a0bf528SMauro Carvalho Chehab #if 0
3976cd7a67a4SMauro Carvalho Chehab status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
39779a0bf528SMauro Carvalho Chehab if (status < 0)
39789a0bf528SMauro Carvalho Chehab goto error;
39799a0bf528SMauro Carvalho Chehab #endif
3980ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz,
3981ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true);
39829a0bf528SMauro Carvalho Chehab if (status < 0)
39839a0bf528SMauro Carvalho Chehab goto error;
39849a0bf528SMauro Carvalho Chehab
3985ab5060cdSMauro Carvalho Chehab /*== start SC, write channel settings to SC ==========================*/
39869a0bf528SMauro Carvalho Chehab
39879a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */
39889a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
39899a0bf528SMauro Carvalho Chehab if (status < 0)
39909a0bf528SMauro Carvalho Chehab goto error;
39919a0bf528SMauro Carvalho Chehab
39929a0bf528SMauro Carvalho Chehab /* Enable SC after setting all other parameters */
39939a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_STATE__A, 0);
39949a0bf528SMauro Carvalho Chehab if (status < 0)
39959a0bf528SMauro Carvalho Chehab goto error;
39969a0bf528SMauro Carvalho Chehab status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
39979a0bf528SMauro Carvalho Chehab if (status < 0)
39989a0bf528SMauro Carvalho Chehab goto error;
39999a0bf528SMauro Carvalho Chehab
40009a0bf528SMauro Carvalho Chehab
4001ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
4002ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START,
4003ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
40049a0bf528SMauro Carvalho Chehab if (status < 0)
40059a0bf528SMauro Carvalho Chehab goto error;
40069a0bf528SMauro Carvalho Chehab
40079a0bf528SMauro Carvalho Chehab /* Write SC parameter registers, set all AUTO flags in operation mode */
40089a0bf528SMauro Carvalho Chehab param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
40099a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
40109a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
40119a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
40129a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4013cd7a67a4SMauro Carvalho Chehab status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4014cd7a67a4SMauro Carvalho Chehab 0, transmission_params, param1, 0, 0, 0);
40159a0bf528SMauro Carvalho Chehab if (status < 0)
40169a0bf528SMauro Carvalho Chehab goto error;
40179a0bf528SMauro Carvalho Chehab
4018cd7a67a4SMauro Carvalho Chehab if (!state->m_drxk_a3_rom_code)
4019cd7a67a4SMauro Carvalho Chehab status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
40209a0bf528SMauro Carvalho Chehab error:
40219a0bf528SMauro Carvalho Chehab if (status < 0)
40223a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
40239a0bf528SMauro Carvalho Chehab
40249a0bf528SMauro Carvalho Chehab return status;
40259a0bf528SMauro Carvalho Chehab }
40269a0bf528SMauro Carvalho Chehab
40279a0bf528SMauro Carvalho Chehab
40289a0bf528SMauro Carvalho Chehab /*============================================================================*/
40299a0bf528SMauro Carvalho Chehab
403034eb9751SMauro Carvalho Chehab /*
403139c1cb2bSJonathan McCrohan * \brief Retrieve lock status .
40329a0bf528SMauro Carvalho Chehab * \param demod Pointer to demodulator instance.
40339a0bf528SMauro Carvalho Chehab * \param lockStat Pointer to lock status structure.
40349a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
40359a0bf528SMauro Carvalho Chehab *
40369a0bf528SMauro Carvalho Chehab */
get_dvbt_lock_status(struct drxk_state * state,u32 * p_lock_status)4037cd7a67a4SMauro Carvalho Chehab static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
40389a0bf528SMauro Carvalho Chehab {
40399a0bf528SMauro Carvalho Chehab int status;
40409a0bf528SMauro Carvalho Chehab const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
40419a0bf528SMauro Carvalho Chehab OFDM_SC_RA_RAM_LOCK_FEC__M);
40429a0bf528SMauro Carvalho Chehab const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
40439a0bf528SMauro Carvalho Chehab const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
40449a0bf528SMauro Carvalho Chehab
4045cd7a67a4SMauro Carvalho Chehab u16 sc_ra_ram_lock = 0;
4046cd7a67a4SMauro Carvalho Chehab u16 sc_comm_exec = 0;
40479a0bf528SMauro Carvalho Chehab
40489a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
40499a0bf528SMauro Carvalho Chehab
4050cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED;
40519a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */
40529a0bf528SMauro Carvalho Chehab /* Check if SC is running */
4053cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
40549a0bf528SMauro Carvalho Chehab if (status < 0)
40559a0bf528SMauro Carvalho Chehab goto end;
4056cd7a67a4SMauro Carvalho Chehab if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
40579a0bf528SMauro Carvalho Chehab goto end;
40589a0bf528SMauro Carvalho Chehab
4059cd7a67a4SMauro Carvalho Chehab status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
40609a0bf528SMauro Carvalho Chehab if (status < 0)
40619a0bf528SMauro Carvalho Chehab goto end;
40629a0bf528SMauro Carvalho Chehab
4063cd7a67a4SMauro Carvalho Chehab if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
4064cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK;
4065cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
4066cd7a67a4SMauro Carvalho Chehab *p_lock_status = FEC_LOCK;
4067cd7a67a4SMauro Carvalho Chehab else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
4068cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK;
4069cd7a67a4SMauro Carvalho Chehab else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4070cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK;
40719a0bf528SMauro Carvalho Chehab end:
40729a0bf528SMauro Carvalho Chehab if (status < 0)
40733a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
40749a0bf528SMauro Carvalho Chehab
40759a0bf528SMauro Carvalho Chehab return status;
40769a0bf528SMauro Carvalho Chehab }
40779a0bf528SMauro Carvalho Chehab
power_up_qam(struct drxk_state * state)4078cd7a67a4SMauro Carvalho Chehab static int power_up_qam(struct drxk_state *state)
40799a0bf528SMauro Carvalho Chehab {
4080cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
40819a0bf528SMauro Carvalho Chehab int status;
40829a0bf528SMauro Carvalho Chehab
40839a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
4084cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode);
40859a0bf528SMauro Carvalho Chehab if (status < 0)
40863a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
40879a0bf528SMauro Carvalho Chehab
40889a0bf528SMauro Carvalho Chehab return status;
40899a0bf528SMauro Carvalho Chehab }
40909a0bf528SMauro Carvalho Chehab
40919a0bf528SMauro Carvalho Chehab
409234eb9751SMauro Carvalho Chehab /* Power Down QAM */
power_down_qam(struct drxk_state * state)4093cd7a67a4SMauro Carvalho Chehab static int power_down_qam(struct drxk_state *state)
40949a0bf528SMauro Carvalho Chehab {
40959a0bf528SMauro Carvalho Chehab u16 data = 0;
4096cd7a67a4SMauro Carvalho Chehab u16 cmd_result;
40979a0bf528SMauro Carvalho Chehab int status = 0;
40989a0bf528SMauro Carvalho Chehab
40999a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
41009a0bf528SMauro Carvalho Chehab status = read16(state, SCU_COMM_EXEC__A, &data);
41019a0bf528SMauro Carvalho Chehab if (status < 0)
41029a0bf528SMauro Carvalho Chehab goto error;
41039a0bf528SMauro Carvalho Chehab if (data == SCU_COMM_EXEC_ACTIVE) {
41049a0bf528SMauro Carvalho Chehab /*
41059a0bf528SMauro Carvalho Chehab STOP demodulator
41069a0bf528SMauro Carvalho Chehab QAM and HW blocks
41079a0bf528SMauro Carvalho Chehab */
41089a0bf528SMauro Carvalho Chehab /* stop all comstate->m_exec */
41099a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
41109a0bf528SMauro Carvalho Chehab if (status < 0)
41119a0bf528SMauro Carvalho Chehab goto error;
4112ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
4113ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
4114ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
41159a0bf528SMauro Carvalho Chehab if (status < 0)
41169a0bf528SMauro Carvalho Chehab goto error;
41179a0bf528SMauro Carvalho Chehab }
41189a0bf528SMauro Carvalho Chehab /* powerdown AFE */
4119cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, false);
41209a0bf528SMauro Carvalho Chehab
41219a0bf528SMauro Carvalho Chehab error:
41229a0bf528SMauro Carvalho Chehab if (status < 0)
41233a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
41249a0bf528SMauro Carvalho Chehab
41259a0bf528SMauro Carvalho Chehab return status;
41269a0bf528SMauro Carvalho Chehab }
41279a0bf528SMauro Carvalho Chehab
41289a0bf528SMauro Carvalho Chehab /*============================================================================*/
41299a0bf528SMauro Carvalho Chehab
413034eb9751SMauro Carvalho Chehab /*
41319a0bf528SMauro Carvalho Chehab * \brief Setup of the QAM Measurement intervals for signal quality
41329a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
41339a0bf528SMauro Carvalho Chehab * \param modulation current modulation.
41349a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
41359a0bf528SMauro Carvalho Chehab *
41369a0bf528SMauro Carvalho Chehab * NOTE:
41379a0bf528SMauro Carvalho Chehab * Take into account that for certain settings the errorcounters can overflow.
41389a0bf528SMauro Carvalho Chehab * The implementation does not check this.
41399a0bf528SMauro Carvalho Chehab *
41409a0bf528SMauro Carvalho Chehab */
set_qam_measurement(struct drxk_state * state,enum e_drxk_constellation modulation,u32 symbol_rate)4141cd7a67a4SMauro Carvalho Chehab static int set_qam_measurement(struct drxk_state *state,
4142cd7a67a4SMauro Carvalho Chehab enum e_drxk_constellation modulation,
4143cd7a67a4SMauro Carvalho Chehab u32 symbol_rate)
41449a0bf528SMauro Carvalho Chehab {
4145cd7a67a4SMauro Carvalho Chehab u32 fec_bits_desired = 0; /* BER accounting period */
4146cd7a67a4SMauro Carvalho Chehab u32 fec_rs_period_total = 0; /* Total period */
4147cd7a67a4SMauro Carvalho Chehab u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
4148cd7a67a4SMauro Carvalho Chehab u16 fec_rs_period = 0; /* Value for corresponding I2C register */
41499a0bf528SMauro Carvalho Chehab int status = 0;
41509a0bf528SMauro Carvalho Chehab
41519a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
41529a0bf528SMauro Carvalho Chehab
4153cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1;
4154cd7a67a4SMauro Carvalho Chehab /* fec_bits_desired = symbol_rate [kHz] *
41559a0bf528SMauro Carvalho Chehab FrameLenght [ms] *
41569a0bf528SMauro Carvalho Chehab (modulation + 1) *
41579a0bf528SMauro Carvalho Chehab SyncLoss (== 1) *
41589a0bf528SMauro Carvalho Chehab ViterbiLoss (==1)
41599a0bf528SMauro Carvalho Chehab */
41609a0bf528SMauro Carvalho Chehab switch (modulation) {
41619a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM16:
4162cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 4 * symbol_rate;
41639a0bf528SMauro Carvalho Chehab break;
41649a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM32:
4165cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 5 * symbol_rate;
41669a0bf528SMauro Carvalho Chehab break;
41679a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM64:
4168cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 6 * symbol_rate;
41699a0bf528SMauro Carvalho Chehab break;
41709a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM128:
4171cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 7 * symbol_rate;
41729a0bf528SMauro Carvalho Chehab break;
41739a0bf528SMauro Carvalho Chehab case DRX_CONSTELLATION_QAM256:
4174cd7a67a4SMauro Carvalho Chehab fec_bits_desired = 8 * symbol_rate;
41759a0bf528SMauro Carvalho Chehab break;
41769a0bf528SMauro Carvalho Chehab default:
41779a0bf528SMauro Carvalho Chehab status = -EINVAL;
41789a0bf528SMauro Carvalho Chehab }
41799a0bf528SMauro Carvalho Chehab if (status < 0)
41809a0bf528SMauro Carvalho Chehab goto error;
41819a0bf528SMauro Carvalho Chehab
4182cd7a67a4SMauro Carvalho Chehab fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */
4183cd7a67a4SMauro Carvalho Chehab fec_bits_desired *= 500; /* meas. period [ms] */
41849a0bf528SMauro Carvalho Chehab
41859a0bf528SMauro Carvalho Chehab /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4186cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_bits_desired / 1632 */
4187cd7a67a4SMauro Carvalho Chehab fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */
41889a0bf528SMauro Carvalho Chehab
4189cd7a67a4SMauro Carvalho Chehab /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */
4190cd7a67a4SMauro Carvalho Chehab fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
4191cd7a67a4SMauro Carvalho Chehab if (fec_rs_prescale == 0) {
41929a0bf528SMauro Carvalho Chehab /* Divide by zero (though impossible) */
41939a0bf528SMauro Carvalho Chehab status = -EINVAL;
41949a0bf528SMauro Carvalho Chehab if (status < 0)
41959a0bf528SMauro Carvalho Chehab goto error;
41969a0bf528SMauro Carvalho Chehab }
4197cd7a67a4SMauro Carvalho Chehab fec_rs_period =
4198cd7a67a4SMauro Carvalho Chehab ((u16) fec_rs_period_total +
4199cd7a67a4SMauro Carvalho Chehab (fec_rs_prescale >> 1)) / fec_rs_prescale;
42009a0bf528SMauro Carvalho Chehab
42019a0bf528SMauro Carvalho Chehab /* write corresponding registers */
4202cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
42039a0bf528SMauro Carvalho Chehab if (status < 0)
42049a0bf528SMauro Carvalho Chehab goto error;
4205ab5060cdSMauro Carvalho Chehab status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
4206ab5060cdSMauro Carvalho Chehab fec_rs_prescale);
42079a0bf528SMauro Carvalho Chehab if (status < 0)
42089a0bf528SMauro Carvalho Chehab goto error;
4209cd7a67a4SMauro Carvalho Chehab status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
42109a0bf528SMauro Carvalho Chehab error:
42119a0bf528SMauro Carvalho Chehab if (status < 0)
42123a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
42139a0bf528SMauro Carvalho Chehab return status;
42149a0bf528SMauro Carvalho Chehab }
42159a0bf528SMauro Carvalho Chehab
set_qam16(struct drxk_state * state)4216cd7a67a4SMauro Carvalho Chehab static int set_qam16(struct drxk_state *state)
42179a0bf528SMauro Carvalho Chehab {
42189a0bf528SMauro Carvalho Chehab int status = 0;
42199a0bf528SMauro Carvalho Chehab
42209a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
42219a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */
42229a0bf528SMauro Carvalho Chehab /* Equalizer */
42239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
42249a0bf528SMauro Carvalho Chehab if (status < 0)
42259a0bf528SMauro Carvalho Chehab goto error;
42269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
42279a0bf528SMauro Carvalho Chehab if (status < 0)
42289a0bf528SMauro Carvalho Chehab goto error;
42299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
42309a0bf528SMauro Carvalho Chehab if (status < 0)
42319a0bf528SMauro Carvalho Chehab goto error;
42329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
42339a0bf528SMauro Carvalho Chehab if (status < 0)
42349a0bf528SMauro Carvalho Chehab goto error;
42359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
42369a0bf528SMauro Carvalho Chehab if (status < 0)
42379a0bf528SMauro Carvalho Chehab goto error;
42389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
42399a0bf528SMauro Carvalho Chehab if (status < 0)
42409a0bf528SMauro Carvalho Chehab goto error;
42419a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */
42429a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
42439a0bf528SMauro Carvalho Chehab if (status < 0)
42449a0bf528SMauro Carvalho Chehab goto error;
42459a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
42469a0bf528SMauro Carvalho Chehab if (status < 0)
42479a0bf528SMauro Carvalho Chehab goto error;
42489a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
42499a0bf528SMauro Carvalho Chehab if (status < 0)
42509a0bf528SMauro Carvalho Chehab goto error;
42519a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
42529a0bf528SMauro Carvalho Chehab if (status < 0)
42539a0bf528SMauro Carvalho Chehab goto error;
42549a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
42559a0bf528SMauro Carvalho Chehab if (status < 0)
42569a0bf528SMauro Carvalho Chehab goto error;
42579a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
42589a0bf528SMauro Carvalho Chehab if (status < 0)
42599a0bf528SMauro Carvalho Chehab goto error;
42609a0bf528SMauro Carvalho Chehab
42619a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5);
42629a0bf528SMauro Carvalho Chehab if (status < 0)
42639a0bf528SMauro Carvalho Chehab goto error;
42649a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4);
42659a0bf528SMauro Carvalho Chehab if (status < 0)
42669a0bf528SMauro Carvalho Chehab goto error;
42679a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3);
42689a0bf528SMauro Carvalho Chehab if (status < 0)
42699a0bf528SMauro Carvalho Chehab goto error;
42709a0bf528SMauro Carvalho Chehab
42719a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */
4272ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4273ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM16);
42749a0bf528SMauro Carvalho Chehab if (status < 0)
42759a0bf528SMauro Carvalho Chehab goto error;
42769a0bf528SMauro Carvalho Chehab
42779a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */
42789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
42799a0bf528SMauro Carvalho Chehab if (status < 0)
42809a0bf528SMauro Carvalho Chehab goto error;
42819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
42829a0bf528SMauro Carvalho Chehab if (status < 0)
42839a0bf528SMauro Carvalho Chehab goto error;
42849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
42859a0bf528SMauro Carvalho Chehab if (status < 0)
42869a0bf528SMauro Carvalho Chehab goto error;
42879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
42889a0bf528SMauro Carvalho Chehab if (status < 0)
42899a0bf528SMauro Carvalho Chehab goto error;
42909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
42919a0bf528SMauro Carvalho Chehab if (status < 0)
42929a0bf528SMauro Carvalho Chehab goto error;
42939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
42949a0bf528SMauro Carvalho Chehab if (status < 0)
42959a0bf528SMauro Carvalho Chehab goto error;
42969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
42979a0bf528SMauro Carvalho Chehab if (status < 0)
42989a0bf528SMauro Carvalho Chehab goto error;
42999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
43009a0bf528SMauro Carvalho Chehab if (status < 0)
43019a0bf528SMauro Carvalho Chehab goto error;
43029a0bf528SMauro Carvalho Chehab
43039a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
43049a0bf528SMauro Carvalho Chehab if (status < 0)
43059a0bf528SMauro Carvalho Chehab goto error;
43069a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
43079a0bf528SMauro Carvalho Chehab if (status < 0)
43089a0bf528SMauro Carvalho Chehab goto error;
43099a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
43109a0bf528SMauro Carvalho Chehab if (status < 0)
43119a0bf528SMauro Carvalho Chehab goto error;
43129a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
43139a0bf528SMauro Carvalho Chehab if (status < 0)
43149a0bf528SMauro Carvalho Chehab goto error;
43159a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
43169a0bf528SMauro Carvalho Chehab if (status < 0)
43179a0bf528SMauro Carvalho Chehab goto error;
43189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
43199a0bf528SMauro Carvalho Chehab if (status < 0)
43209a0bf528SMauro Carvalho Chehab goto error;
43219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
43229a0bf528SMauro Carvalho Chehab if (status < 0)
43239a0bf528SMauro Carvalho Chehab goto error;
43249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
43259a0bf528SMauro Carvalho Chehab if (status < 0)
43269a0bf528SMauro Carvalho Chehab goto error;
43279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
43289a0bf528SMauro Carvalho Chehab if (status < 0)
43299a0bf528SMauro Carvalho Chehab goto error;
43309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
43319a0bf528SMauro Carvalho Chehab if (status < 0)
43329a0bf528SMauro Carvalho Chehab goto error;
43339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
43349a0bf528SMauro Carvalho Chehab if (status < 0)
43359a0bf528SMauro Carvalho Chehab goto error;
43369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
43379a0bf528SMauro Carvalho Chehab if (status < 0)
43389a0bf528SMauro Carvalho Chehab goto error;
43399a0bf528SMauro Carvalho Chehab
43409a0bf528SMauro Carvalho Chehab
43419a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */
43429a0bf528SMauro Carvalho Chehab
43439a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
43449a0bf528SMauro Carvalho Chehab if (status < 0)
43459a0bf528SMauro Carvalho Chehab goto error;
43469a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
43479a0bf528SMauro Carvalho Chehab if (status < 0)
43489a0bf528SMauro Carvalho Chehab goto error;
43499a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
43509a0bf528SMauro Carvalho Chehab if (status < 0)
43519a0bf528SMauro Carvalho Chehab goto error;
43529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
43539a0bf528SMauro Carvalho Chehab if (status < 0)
43549a0bf528SMauro Carvalho Chehab goto error;
43559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
43569a0bf528SMauro Carvalho Chehab if (status < 0)
43579a0bf528SMauro Carvalho Chehab goto error;
43589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
43599a0bf528SMauro Carvalho Chehab if (status < 0)
43609a0bf528SMauro Carvalho Chehab goto error;
43619a0bf528SMauro Carvalho Chehab
43629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
43639a0bf528SMauro Carvalho Chehab if (status < 0)
43649a0bf528SMauro Carvalho Chehab goto error;
43659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
43669a0bf528SMauro Carvalho Chehab if (status < 0)
43679a0bf528SMauro Carvalho Chehab goto error;
43689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
43699a0bf528SMauro Carvalho Chehab if (status < 0)
43709a0bf528SMauro Carvalho Chehab goto error;
43719a0bf528SMauro Carvalho Chehab
43729a0bf528SMauro Carvalho Chehab
43739a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */
43749a0bf528SMauro Carvalho Chehab
43759a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
43769a0bf528SMauro Carvalho Chehab if (status < 0)
43779a0bf528SMauro Carvalho Chehab goto error;
43789a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
43799a0bf528SMauro Carvalho Chehab if (status < 0)
43809a0bf528SMauro Carvalho Chehab goto error;
43819a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
43829a0bf528SMauro Carvalho Chehab if (status < 0)
43839a0bf528SMauro Carvalho Chehab goto error;
43849a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
43859a0bf528SMauro Carvalho Chehab if (status < 0)
43869a0bf528SMauro Carvalho Chehab goto error;
43879a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
43889a0bf528SMauro Carvalho Chehab if (status < 0)
43899a0bf528SMauro Carvalho Chehab goto error;
43909a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
43919a0bf528SMauro Carvalho Chehab if (status < 0)
43929a0bf528SMauro Carvalho Chehab goto error;
43939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
43949a0bf528SMauro Carvalho Chehab if (status < 0)
43959a0bf528SMauro Carvalho Chehab goto error;
43969a0bf528SMauro Carvalho Chehab
43979a0bf528SMauro Carvalho Chehab error:
43989a0bf528SMauro Carvalho Chehab if (status < 0)
43993a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
44009a0bf528SMauro Carvalho Chehab return status;
44019a0bf528SMauro Carvalho Chehab }
44029a0bf528SMauro Carvalho Chehab
44039a0bf528SMauro Carvalho Chehab /*============================================================================*/
44049a0bf528SMauro Carvalho Chehab
440534eb9751SMauro Carvalho Chehab /*
44069a0bf528SMauro Carvalho Chehab * \brief QAM32 specific setup
44079a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
44089a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
44099a0bf528SMauro Carvalho Chehab */
set_qam32(struct drxk_state * state)4410cd7a67a4SMauro Carvalho Chehab static int set_qam32(struct drxk_state *state)
44119a0bf528SMauro Carvalho Chehab {
44129a0bf528SMauro Carvalho Chehab int status = 0;
44139a0bf528SMauro Carvalho Chehab
44149a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
44159a0bf528SMauro Carvalho Chehab
44169a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */
44179a0bf528SMauro Carvalho Chehab /* Equalizer */
44189a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
44199a0bf528SMauro Carvalho Chehab if (status < 0)
44209a0bf528SMauro Carvalho Chehab goto error;
44219a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
44229a0bf528SMauro Carvalho Chehab if (status < 0)
44239a0bf528SMauro Carvalho Chehab goto error;
44249a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
44259a0bf528SMauro Carvalho Chehab if (status < 0)
44269a0bf528SMauro Carvalho Chehab goto error;
44279a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
44289a0bf528SMauro Carvalho Chehab if (status < 0)
44299a0bf528SMauro Carvalho Chehab goto error;
44309a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
44319a0bf528SMauro Carvalho Chehab if (status < 0)
44329a0bf528SMauro Carvalho Chehab goto error;
44339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
44349a0bf528SMauro Carvalho Chehab if (status < 0)
44359a0bf528SMauro Carvalho Chehab goto error;
44369a0bf528SMauro Carvalho Chehab
44379a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */
44389a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
44399a0bf528SMauro Carvalho Chehab if (status < 0)
44409a0bf528SMauro Carvalho Chehab goto error;
44419a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
44429a0bf528SMauro Carvalho Chehab if (status < 0)
44439a0bf528SMauro Carvalho Chehab goto error;
44449a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
44459a0bf528SMauro Carvalho Chehab if (status < 0)
44469a0bf528SMauro Carvalho Chehab goto error;
44479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
44489a0bf528SMauro Carvalho Chehab if (status < 0)
44499a0bf528SMauro Carvalho Chehab goto error;
44509a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
44519a0bf528SMauro Carvalho Chehab if (status < 0)
44529a0bf528SMauro Carvalho Chehab goto error;
44539a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
44549a0bf528SMauro Carvalho Chehab if (status < 0)
44559a0bf528SMauro Carvalho Chehab goto error;
44569a0bf528SMauro Carvalho Chehab
44579a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6);
44589a0bf528SMauro Carvalho Chehab if (status < 0)
44599a0bf528SMauro Carvalho Chehab goto error;
44609a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5);
44619a0bf528SMauro Carvalho Chehab if (status < 0)
44629a0bf528SMauro Carvalho Chehab goto error;
44639a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3);
44649a0bf528SMauro Carvalho Chehab if (status < 0)
44659a0bf528SMauro Carvalho Chehab goto error;
44669a0bf528SMauro Carvalho Chehab
44679a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */
44689a0bf528SMauro Carvalho Chehab
4469ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4470ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM32);
44719a0bf528SMauro Carvalho Chehab if (status < 0)
44729a0bf528SMauro Carvalho Chehab goto error;
44739a0bf528SMauro Carvalho Chehab
44749a0bf528SMauro Carvalho Chehab
44759a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */
44769a0bf528SMauro Carvalho Chehab
44779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
44789a0bf528SMauro Carvalho Chehab if (status < 0)
44799a0bf528SMauro Carvalho Chehab goto error;
44809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
44819a0bf528SMauro Carvalho Chehab if (status < 0)
44829a0bf528SMauro Carvalho Chehab goto error;
44839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
44849a0bf528SMauro Carvalho Chehab if (status < 0)
44859a0bf528SMauro Carvalho Chehab goto error;
44869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
44879a0bf528SMauro Carvalho Chehab if (status < 0)
44889a0bf528SMauro Carvalho Chehab goto error;
44899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
44909a0bf528SMauro Carvalho Chehab if (status < 0)
44919a0bf528SMauro Carvalho Chehab goto error;
44929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
44939a0bf528SMauro Carvalho Chehab if (status < 0)
44949a0bf528SMauro Carvalho Chehab goto error;
44959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
44969a0bf528SMauro Carvalho Chehab if (status < 0)
44979a0bf528SMauro Carvalho Chehab goto error;
44989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
44999a0bf528SMauro Carvalho Chehab if (status < 0)
45009a0bf528SMauro Carvalho Chehab goto error;
45019a0bf528SMauro Carvalho Chehab
45029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
45039a0bf528SMauro Carvalho Chehab if (status < 0)
45049a0bf528SMauro Carvalho Chehab goto error;
45059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
45069a0bf528SMauro Carvalho Chehab if (status < 0)
45079a0bf528SMauro Carvalho Chehab goto error;
45089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
45099a0bf528SMauro Carvalho Chehab if (status < 0)
45109a0bf528SMauro Carvalho Chehab goto error;
45119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
45129a0bf528SMauro Carvalho Chehab if (status < 0)
45139a0bf528SMauro Carvalho Chehab goto error;
45149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
45159a0bf528SMauro Carvalho Chehab if (status < 0)
45169a0bf528SMauro Carvalho Chehab goto error;
45179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
45189a0bf528SMauro Carvalho Chehab if (status < 0)
45199a0bf528SMauro Carvalho Chehab goto error;
45209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
45219a0bf528SMauro Carvalho Chehab if (status < 0)
45229a0bf528SMauro Carvalho Chehab goto error;
45239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
45249a0bf528SMauro Carvalho Chehab if (status < 0)
45259a0bf528SMauro Carvalho Chehab goto error;
45269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
45279a0bf528SMauro Carvalho Chehab if (status < 0)
45289a0bf528SMauro Carvalho Chehab goto error;
45299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
45309a0bf528SMauro Carvalho Chehab if (status < 0)
45319a0bf528SMauro Carvalho Chehab goto error;
45329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
45339a0bf528SMauro Carvalho Chehab if (status < 0)
45349a0bf528SMauro Carvalho Chehab goto error;
45359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
45369a0bf528SMauro Carvalho Chehab if (status < 0)
45379a0bf528SMauro Carvalho Chehab goto error;
45389a0bf528SMauro Carvalho Chehab
45399a0bf528SMauro Carvalho Chehab
45409a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */
45419a0bf528SMauro Carvalho Chehab
45429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
45439a0bf528SMauro Carvalho Chehab if (status < 0)
45449a0bf528SMauro Carvalho Chehab goto error;
45459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
45469a0bf528SMauro Carvalho Chehab if (status < 0)
45479a0bf528SMauro Carvalho Chehab goto error;
45489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
45499a0bf528SMauro Carvalho Chehab if (status < 0)
45509a0bf528SMauro Carvalho Chehab goto error;
45519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
45529a0bf528SMauro Carvalho Chehab if (status < 0)
45539a0bf528SMauro Carvalho Chehab goto error;
45549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
45559a0bf528SMauro Carvalho Chehab if (status < 0)
45569a0bf528SMauro Carvalho Chehab goto error;
45579a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
45589a0bf528SMauro Carvalho Chehab if (status < 0)
45599a0bf528SMauro Carvalho Chehab goto error;
45609a0bf528SMauro Carvalho Chehab
45619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
45629a0bf528SMauro Carvalho Chehab if (status < 0)
45639a0bf528SMauro Carvalho Chehab goto error;
45649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
45659a0bf528SMauro Carvalho Chehab if (status < 0)
45669a0bf528SMauro Carvalho Chehab goto error;
45679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
45689a0bf528SMauro Carvalho Chehab if (status < 0)
45699a0bf528SMauro Carvalho Chehab goto error;
45709a0bf528SMauro Carvalho Chehab
45719a0bf528SMauro Carvalho Chehab
45729a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */
45739a0bf528SMauro Carvalho Chehab
45749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
45759a0bf528SMauro Carvalho Chehab if (status < 0)
45769a0bf528SMauro Carvalho Chehab goto error;
45779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
45789a0bf528SMauro Carvalho Chehab if (status < 0)
45799a0bf528SMauro Carvalho Chehab goto error;
45809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
45819a0bf528SMauro Carvalho Chehab if (status < 0)
45829a0bf528SMauro Carvalho Chehab goto error;
45839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
45849a0bf528SMauro Carvalho Chehab if (status < 0)
45859a0bf528SMauro Carvalho Chehab goto error;
45869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
45879a0bf528SMauro Carvalho Chehab if (status < 0)
45889a0bf528SMauro Carvalho Chehab goto error;
45899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
45909a0bf528SMauro Carvalho Chehab if (status < 0)
45919a0bf528SMauro Carvalho Chehab goto error;
45929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
45939a0bf528SMauro Carvalho Chehab error:
45949a0bf528SMauro Carvalho Chehab if (status < 0)
45953a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
45969a0bf528SMauro Carvalho Chehab return status;
45979a0bf528SMauro Carvalho Chehab }
45989a0bf528SMauro Carvalho Chehab
45999a0bf528SMauro Carvalho Chehab /*============================================================================*/
46009a0bf528SMauro Carvalho Chehab
460134eb9751SMauro Carvalho Chehab /*
46029a0bf528SMauro Carvalho Chehab * \brief QAM64 specific setup
46039a0bf528SMauro Carvalho Chehab * \param demod instance of demod.
46049a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
46059a0bf528SMauro Carvalho Chehab */
set_qam64(struct drxk_state * state)4606cd7a67a4SMauro Carvalho Chehab static int set_qam64(struct drxk_state *state)
46079a0bf528SMauro Carvalho Chehab {
46089a0bf528SMauro Carvalho Chehab int status = 0;
46099a0bf528SMauro Carvalho Chehab
46109a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
46119a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */
46129a0bf528SMauro Carvalho Chehab /* Equalizer */
46139a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
46149a0bf528SMauro Carvalho Chehab if (status < 0)
46159a0bf528SMauro Carvalho Chehab goto error;
46169a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
46179a0bf528SMauro Carvalho Chehab if (status < 0)
46189a0bf528SMauro Carvalho Chehab goto error;
46199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
46209a0bf528SMauro Carvalho Chehab if (status < 0)
46219a0bf528SMauro Carvalho Chehab goto error;
46229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
46239a0bf528SMauro Carvalho Chehab if (status < 0)
46249a0bf528SMauro Carvalho Chehab goto error;
46259a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
46269a0bf528SMauro Carvalho Chehab if (status < 0)
46279a0bf528SMauro Carvalho Chehab goto error;
46289a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
46299a0bf528SMauro Carvalho Chehab if (status < 0)
46309a0bf528SMauro Carvalho Chehab goto error;
46319a0bf528SMauro Carvalho Chehab
46329a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */
46339a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
46349a0bf528SMauro Carvalho Chehab if (status < 0)
46359a0bf528SMauro Carvalho Chehab goto error;
46369a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
46379a0bf528SMauro Carvalho Chehab if (status < 0)
46389a0bf528SMauro Carvalho Chehab goto error;
46399a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
46409a0bf528SMauro Carvalho Chehab if (status < 0)
46419a0bf528SMauro Carvalho Chehab goto error;
46429a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
46439a0bf528SMauro Carvalho Chehab if (status < 0)
46449a0bf528SMauro Carvalho Chehab goto error;
46459a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
46469a0bf528SMauro Carvalho Chehab if (status < 0)
46479a0bf528SMauro Carvalho Chehab goto error;
46489a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
46499a0bf528SMauro Carvalho Chehab if (status < 0)
46509a0bf528SMauro Carvalho Chehab goto error;
46519a0bf528SMauro Carvalho Chehab
46529a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5);
46539a0bf528SMauro Carvalho Chehab if (status < 0)
46549a0bf528SMauro Carvalho Chehab goto error;
46559a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4);
46569a0bf528SMauro Carvalho Chehab if (status < 0)
46579a0bf528SMauro Carvalho Chehab goto error;
46589a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3);
46599a0bf528SMauro Carvalho Chehab if (status < 0)
46609a0bf528SMauro Carvalho Chehab goto error;
46619a0bf528SMauro Carvalho Chehab
46629a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */
4663ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4664ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM64);
46659a0bf528SMauro Carvalho Chehab if (status < 0)
46669a0bf528SMauro Carvalho Chehab goto error;
46679a0bf528SMauro Carvalho Chehab
46689a0bf528SMauro Carvalho Chehab
46699a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */
46709a0bf528SMauro Carvalho Chehab
46719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
46729a0bf528SMauro Carvalho Chehab if (status < 0)
46739a0bf528SMauro Carvalho Chehab goto error;
46749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
46759a0bf528SMauro Carvalho Chehab if (status < 0)
46769a0bf528SMauro Carvalho Chehab goto error;
46779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
46789a0bf528SMauro Carvalho Chehab if (status < 0)
46799a0bf528SMauro Carvalho Chehab goto error;
46809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
46819a0bf528SMauro Carvalho Chehab if (status < 0)
46829a0bf528SMauro Carvalho Chehab goto error;
46839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
46849a0bf528SMauro Carvalho Chehab if (status < 0)
46859a0bf528SMauro Carvalho Chehab goto error;
46869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
46879a0bf528SMauro Carvalho Chehab if (status < 0)
46889a0bf528SMauro Carvalho Chehab goto error;
46899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
46909a0bf528SMauro Carvalho Chehab if (status < 0)
46919a0bf528SMauro Carvalho Chehab goto error;
46929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
46939a0bf528SMauro Carvalho Chehab if (status < 0)
46949a0bf528SMauro Carvalho Chehab goto error;
46959a0bf528SMauro Carvalho Chehab
46969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
46979a0bf528SMauro Carvalho Chehab if (status < 0)
46989a0bf528SMauro Carvalho Chehab goto error;
46999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
47009a0bf528SMauro Carvalho Chehab if (status < 0)
47019a0bf528SMauro Carvalho Chehab goto error;
47029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
47039a0bf528SMauro Carvalho Chehab if (status < 0)
47049a0bf528SMauro Carvalho Chehab goto error;
47059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
47069a0bf528SMauro Carvalho Chehab if (status < 0)
47079a0bf528SMauro Carvalho Chehab goto error;
47089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
47099a0bf528SMauro Carvalho Chehab if (status < 0)
47109a0bf528SMauro Carvalho Chehab goto error;
47119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
47129a0bf528SMauro Carvalho Chehab if (status < 0)
47139a0bf528SMauro Carvalho Chehab goto error;
47149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
47159a0bf528SMauro Carvalho Chehab if (status < 0)
47169a0bf528SMauro Carvalho Chehab goto error;
47179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
47189a0bf528SMauro Carvalho Chehab if (status < 0)
47199a0bf528SMauro Carvalho Chehab goto error;
47209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
47219a0bf528SMauro Carvalho Chehab if (status < 0)
47229a0bf528SMauro Carvalho Chehab goto error;
47239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
47249a0bf528SMauro Carvalho Chehab if (status < 0)
47259a0bf528SMauro Carvalho Chehab goto error;
47269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
47279a0bf528SMauro Carvalho Chehab if (status < 0)
47289a0bf528SMauro Carvalho Chehab goto error;
47299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
47309a0bf528SMauro Carvalho Chehab if (status < 0)
47319a0bf528SMauro Carvalho Chehab goto error;
47329a0bf528SMauro Carvalho Chehab
47339a0bf528SMauro Carvalho Chehab
47349a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */
47359a0bf528SMauro Carvalho Chehab
47369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
47379a0bf528SMauro Carvalho Chehab if (status < 0)
47389a0bf528SMauro Carvalho Chehab goto error;
47399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
47409a0bf528SMauro Carvalho Chehab if (status < 0)
47419a0bf528SMauro Carvalho Chehab goto error;
47429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
47439a0bf528SMauro Carvalho Chehab if (status < 0)
47449a0bf528SMauro Carvalho Chehab goto error;
47459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
47469a0bf528SMauro Carvalho Chehab if (status < 0)
47479a0bf528SMauro Carvalho Chehab goto error;
47489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
47499a0bf528SMauro Carvalho Chehab if (status < 0)
47509a0bf528SMauro Carvalho Chehab goto error;
47519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
47529a0bf528SMauro Carvalho Chehab if (status < 0)
47539a0bf528SMauro Carvalho Chehab goto error;
47549a0bf528SMauro Carvalho Chehab
47559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
47569a0bf528SMauro Carvalho Chehab if (status < 0)
47579a0bf528SMauro Carvalho Chehab goto error;
47589a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
47599a0bf528SMauro Carvalho Chehab if (status < 0)
47609a0bf528SMauro Carvalho Chehab goto error;
47619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
47629a0bf528SMauro Carvalho Chehab if (status < 0)
47639a0bf528SMauro Carvalho Chehab goto error;
47649a0bf528SMauro Carvalho Chehab
47659a0bf528SMauro Carvalho Chehab
47669a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */
47679a0bf528SMauro Carvalho Chehab
47689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
47699a0bf528SMauro Carvalho Chehab if (status < 0)
47709a0bf528SMauro Carvalho Chehab goto error;
47719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
47729a0bf528SMauro Carvalho Chehab if (status < 0)
47739a0bf528SMauro Carvalho Chehab goto error;
47749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
47759a0bf528SMauro Carvalho Chehab if (status < 0)
47769a0bf528SMauro Carvalho Chehab goto error;
47779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
47789a0bf528SMauro Carvalho Chehab if (status < 0)
47799a0bf528SMauro Carvalho Chehab goto error;
47809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
47819a0bf528SMauro Carvalho Chehab if (status < 0)
47829a0bf528SMauro Carvalho Chehab goto error;
47839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
47849a0bf528SMauro Carvalho Chehab if (status < 0)
47859a0bf528SMauro Carvalho Chehab goto error;
47869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
47879a0bf528SMauro Carvalho Chehab error:
47889a0bf528SMauro Carvalho Chehab if (status < 0)
47893a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
47909a0bf528SMauro Carvalho Chehab
47919a0bf528SMauro Carvalho Chehab return status;
47929a0bf528SMauro Carvalho Chehab }
47939a0bf528SMauro Carvalho Chehab
47949a0bf528SMauro Carvalho Chehab /*============================================================================*/
47959a0bf528SMauro Carvalho Chehab
479634eb9751SMauro Carvalho Chehab /*
47979a0bf528SMauro Carvalho Chehab * \brief QAM128 specific setup
47989a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
47999a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
48009a0bf528SMauro Carvalho Chehab */
set_qam128(struct drxk_state * state)4801cd7a67a4SMauro Carvalho Chehab static int set_qam128(struct drxk_state *state)
48029a0bf528SMauro Carvalho Chehab {
48039a0bf528SMauro Carvalho Chehab int status = 0;
48049a0bf528SMauro Carvalho Chehab
48059a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
48069a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */
48079a0bf528SMauro Carvalho Chehab /* Equalizer */
48089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
48099a0bf528SMauro Carvalho Chehab if (status < 0)
48109a0bf528SMauro Carvalho Chehab goto error;
48119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
48129a0bf528SMauro Carvalho Chehab if (status < 0)
48139a0bf528SMauro Carvalho Chehab goto error;
48149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
48159a0bf528SMauro Carvalho Chehab if (status < 0)
48169a0bf528SMauro Carvalho Chehab goto error;
48179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
48189a0bf528SMauro Carvalho Chehab if (status < 0)
48199a0bf528SMauro Carvalho Chehab goto error;
48209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
48219a0bf528SMauro Carvalho Chehab if (status < 0)
48229a0bf528SMauro Carvalho Chehab goto error;
48239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
48249a0bf528SMauro Carvalho Chehab if (status < 0)
48259a0bf528SMauro Carvalho Chehab goto error;
48269a0bf528SMauro Carvalho Chehab
48279a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */
48289a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
48299a0bf528SMauro Carvalho Chehab if (status < 0)
48309a0bf528SMauro Carvalho Chehab goto error;
48319a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
48329a0bf528SMauro Carvalho Chehab if (status < 0)
48339a0bf528SMauro Carvalho Chehab goto error;
48349a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
48359a0bf528SMauro Carvalho Chehab if (status < 0)
48369a0bf528SMauro Carvalho Chehab goto error;
48379a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
48389a0bf528SMauro Carvalho Chehab if (status < 0)
48399a0bf528SMauro Carvalho Chehab goto error;
48409a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
48419a0bf528SMauro Carvalho Chehab if (status < 0)
48429a0bf528SMauro Carvalho Chehab goto error;
48439a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
48449a0bf528SMauro Carvalho Chehab if (status < 0)
48459a0bf528SMauro Carvalho Chehab goto error;
48469a0bf528SMauro Carvalho Chehab
48479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 6);
48489a0bf528SMauro Carvalho Chehab if (status < 0)
48499a0bf528SMauro Carvalho Chehab goto error;
48509a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 5);
48519a0bf528SMauro Carvalho Chehab if (status < 0)
48529a0bf528SMauro Carvalho Chehab goto error;
48539a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3);
48549a0bf528SMauro Carvalho Chehab if (status < 0)
48559a0bf528SMauro Carvalho Chehab goto error;
48569a0bf528SMauro Carvalho Chehab
48579a0bf528SMauro Carvalho Chehab
48589a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */
48599a0bf528SMauro Carvalho Chehab
4860ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
4861ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM128);
48629a0bf528SMauro Carvalho Chehab if (status < 0)
48639a0bf528SMauro Carvalho Chehab goto error;
48649a0bf528SMauro Carvalho Chehab
48659a0bf528SMauro Carvalho Chehab
48669a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */
48679a0bf528SMauro Carvalho Chehab
48689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
48699a0bf528SMauro Carvalho Chehab if (status < 0)
48709a0bf528SMauro Carvalho Chehab goto error;
48719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
48729a0bf528SMauro Carvalho Chehab if (status < 0)
48739a0bf528SMauro Carvalho Chehab goto error;
48749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
48759a0bf528SMauro Carvalho Chehab if (status < 0)
48769a0bf528SMauro Carvalho Chehab goto error;
48779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
48789a0bf528SMauro Carvalho Chehab if (status < 0)
48799a0bf528SMauro Carvalho Chehab goto error;
48809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
48819a0bf528SMauro Carvalho Chehab if (status < 0)
48829a0bf528SMauro Carvalho Chehab goto error;
48839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
48849a0bf528SMauro Carvalho Chehab if (status < 0)
48859a0bf528SMauro Carvalho Chehab goto error;
48869a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
48879a0bf528SMauro Carvalho Chehab if (status < 0)
48889a0bf528SMauro Carvalho Chehab goto error;
48899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
48909a0bf528SMauro Carvalho Chehab if (status < 0)
48919a0bf528SMauro Carvalho Chehab goto error;
48929a0bf528SMauro Carvalho Chehab
48939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
48949a0bf528SMauro Carvalho Chehab if (status < 0)
48959a0bf528SMauro Carvalho Chehab goto error;
48969a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
48979a0bf528SMauro Carvalho Chehab if (status < 0)
48989a0bf528SMauro Carvalho Chehab goto error;
48999a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
49009a0bf528SMauro Carvalho Chehab if (status < 0)
49019a0bf528SMauro Carvalho Chehab goto error;
49029a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
49039a0bf528SMauro Carvalho Chehab if (status < 0)
49049a0bf528SMauro Carvalho Chehab goto error;
49059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
49069a0bf528SMauro Carvalho Chehab if (status < 0)
49079a0bf528SMauro Carvalho Chehab goto error;
49089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
49099a0bf528SMauro Carvalho Chehab if (status < 0)
49109a0bf528SMauro Carvalho Chehab goto error;
49119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
49129a0bf528SMauro Carvalho Chehab if (status < 0)
49139a0bf528SMauro Carvalho Chehab goto error;
49149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
49159a0bf528SMauro Carvalho Chehab if (status < 0)
49169a0bf528SMauro Carvalho Chehab goto error;
49179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
49189a0bf528SMauro Carvalho Chehab if (status < 0)
49199a0bf528SMauro Carvalho Chehab goto error;
49209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
49219a0bf528SMauro Carvalho Chehab if (status < 0)
49229a0bf528SMauro Carvalho Chehab goto error;
49239a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
49249a0bf528SMauro Carvalho Chehab if (status < 0)
49259a0bf528SMauro Carvalho Chehab goto error;
49269a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
49279a0bf528SMauro Carvalho Chehab if (status < 0)
49289a0bf528SMauro Carvalho Chehab goto error;
49299a0bf528SMauro Carvalho Chehab
49309a0bf528SMauro Carvalho Chehab
49319a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */
49329a0bf528SMauro Carvalho Chehab
49339a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
49349a0bf528SMauro Carvalho Chehab if (status < 0)
49359a0bf528SMauro Carvalho Chehab goto error;
49369a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
49379a0bf528SMauro Carvalho Chehab if (status < 0)
49389a0bf528SMauro Carvalho Chehab goto error;
49399a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
49409a0bf528SMauro Carvalho Chehab if (status < 0)
49419a0bf528SMauro Carvalho Chehab goto error;
49429a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
49439a0bf528SMauro Carvalho Chehab if (status < 0)
49449a0bf528SMauro Carvalho Chehab goto error;
49459a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
49469a0bf528SMauro Carvalho Chehab if (status < 0)
49479a0bf528SMauro Carvalho Chehab goto error;
49489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
49499a0bf528SMauro Carvalho Chehab if (status < 0)
49509a0bf528SMauro Carvalho Chehab goto error;
49519a0bf528SMauro Carvalho Chehab
49529a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
49539a0bf528SMauro Carvalho Chehab if (status < 0)
49549a0bf528SMauro Carvalho Chehab goto error;
49559a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
49569a0bf528SMauro Carvalho Chehab if (status < 0)
49579a0bf528SMauro Carvalho Chehab goto error;
49589a0bf528SMauro Carvalho Chehab
49599a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
49609a0bf528SMauro Carvalho Chehab if (status < 0)
49619a0bf528SMauro Carvalho Chehab goto error;
49629a0bf528SMauro Carvalho Chehab
49639a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */
49649a0bf528SMauro Carvalho Chehab
49659a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
49669a0bf528SMauro Carvalho Chehab if (status < 0)
49679a0bf528SMauro Carvalho Chehab goto error;
49689a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
49699a0bf528SMauro Carvalho Chehab if (status < 0)
49709a0bf528SMauro Carvalho Chehab goto error;
49719a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
49729a0bf528SMauro Carvalho Chehab if (status < 0)
49739a0bf528SMauro Carvalho Chehab goto error;
49749a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
49759a0bf528SMauro Carvalho Chehab if (status < 0)
49769a0bf528SMauro Carvalho Chehab goto error;
49779a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
49789a0bf528SMauro Carvalho Chehab if (status < 0)
49799a0bf528SMauro Carvalho Chehab goto error;
49809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
49819a0bf528SMauro Carvalho Chehab if (status < 0)
49829a0bf528SMauro Carvalho Chehab goto error;
49839a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
49849a0bf528SMauro Carvalho Chehab error:
49859a0bf528SMauro Carvalho Chehab if (status < 0)
49863a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
49879a0bf528SMauro Carvalho Chehab
49889a0bf528SMauro Carvalho Chehab return status;
49899a0bf528SMauro Carvalho Chehab }
49909a0bf528SMauro Carvalho Chehab
49919a0bf528SMauro Carvalho Chehab /*============================================================================*/
49929a0bf528SMauro Carvalho Chehab
499334eb9751SMauro Carvalho Chehab /*
49949a0bf528SMauro Carvalho Chehab * \brief QAM256 specific setup
49959a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
49969a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
49979a0bf528SMauro Carvalho Chehab */
set_qam256(struct drxk_state * state)4998cd7a67a4SMauro Carvalho Chehab static int set_qam256(struct drxk_state *state)
49999a0bf528SMauro Carvalho Chehab {
50009a0bf528SMauro Carvalho Chehab int status = 0;
50019a0bf528SMauro Carvalho Chehab
50029a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
50039a0bf528SMauro Carvalho Chehab /* QAM Equalizer Setup */
50049a0bf528SMauro Carvalho Chehab /* Equalizer */
50059a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
50069a0bf528SMauro Carvalho Chehab if (status < 0)
50079a0bf528SMauro Carvalho Chehab goto error;
50089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
50099a0bf528SMauro Carvalho Chehab if (status < 0)
50109a0bf528SMauro Carvalho Chehab goto error;
50119a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
50129a0bf528SMauro Carvalho Chehab if (status < 0)
50139a0bf528SMauro Carvalho Chehab goto error;
50149a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
50159a0bf528SMauro Carvalho Chehab if (status < 0)
50169a0bf528SMauro Carvalho Chehab goto error;
50179a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
50189a0bf528SMauro Carvalho Chehab if (status < 0)
50199a0bf528SMauro Carvalho Chehab goto error;
50209a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
50219a0bf528SMauro Carvalho Chehab if (status < 0)
50229a0bf528SMauro Carvalho Chehab goto error;
50239a0bf528SMauro Carvalho Chehab
50249a0bf528SMauro Carvalho Chehab /* Decision Feedback Equalizer */
50259a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
50269a0bf528SMauro Carvalho Chehab if (status < 0)
50279a0bf528SMauro Carvalho Chehab goto error;
50289a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
50299a0bf528SMauro Carvalho Chehab if (status < 0)
50309a0bf528SMauro Carvalho Chehab goto error;
50319a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
50329a0bf528SMauro Carvalho Chehab if (status < 0)
50339a0bf528SMauro Carvalho Chehab goto error;
50349a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
50359a0bf528SMauro Carvalho Chehab if (status < 0)
50369a0bf528SMauro Carvalho Chehab goto error;
50379a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
50389a0bf528SMauro Carvalho Chehab if (status < 0)
50399a0bf528SMauro Carvalho Chehab goto error;
50409a0bf528SMauro Carvalho Chehab status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
50419a0bf528SMauro Carvalho Chehab if (status < 0)
50429a0bf528SMauro Carvalho Chehab goto error;
50439a0bf528SMauro Carvalho Chehab
50449a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_HWM__A, 5);
50459a0bf528SMauro Carvalho Chehab if (status < 0)
50469a0bf528SMauro Carvalho Chehab goto error;
50479a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_AWM__A, 4);
50489a0bf528SMauro Carvalho Chehab if (status < 0)
50499a0bf528SMauro Carvalho Chehab goto error;
50509a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_SYNC_LWM__A, 3);
50519a0bf528SMauro Carvalho Chehab if (status < 0)
50529a0bf528SMauro Carvalho Chehab goto error;
50539a0bf528SMauro Carvalho Chehab
50549a0bf528SMauro Carvalho Chehab /* QAM Slicer Settings */
50559a0bf528SMauro Carvalho Chehab
5056ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
5057ab5060cdSMauro Carvalho Chehab DRXK_QAM_SL_SIG_POWER_QAM256);
50589a0bf528SMauro Carvalho Chehab if (status < 0)
50599a0bf528SMauro Carvalho Chehab goto error;
50609a0bf528SMauro Carvalho Chehab
50619a0bf528SMauro Carvalho Chehab
50629a0bf528SMauro Carvalho Chehab /* QAM Loop Controller Coeficients */
50639a0bf528SMauro Carvalho Chehab
50649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
50659a0bf528SMauro Carvalho Chehab if (status < 0)
50669a0bf528SMauro Carvalho Chehab goto error;
50679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
50689a0bf528SMauro Carvalho Chehab if (status < 0)
50699a0bf528SMauro Carvalho Chehab goto error;
50709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
50719a0bf528SMauro Carvalho Chehab if (status < 0)
50729a0bf528SMauro Carvalho Chehab goto error;
50739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
50749a0bf528SMauro Carvalho Chehab if (status < 0)
50759a0bf528SMauro Carvalho Chehab goto error;
50769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
50779a0bf528SMauro Carvalho Chehab if (status < 0)
50789a0bf528SMauro Carvalho Chehab goto error;
50799a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
50809a0bf528SMauro Carvalho Chehab if (status < 0)
50819a0bf528SMauro Carvalho Chehab goto error;
50829a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
50839a0bf528SMauro Carvalho Chehab if (status < 0)
50849a0bf528SMauro Carvalho Chehab goto error;
50859a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
50869a0bf528SMauro Carvalho Chehab if (status < 0)
50879a0bf528SMauro Carvalho Chehab goto error;
50889a0bf528SMauro Carvalho Chehab
50899a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
50909a0bf528SMauro Carvalho Chehab if (status < 0)
50919a0bf528SMauro Carvalho Chehab goto error;
50929a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
50939a0bf528SMauro Carvalho Chehab if (status < 0)
50949a0bf528SMauro Carvalho Chehab goto error;
50959a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
50969a0bf528SMauro Carvalho Chehab if (status < 0)
50979a0bf528SMauro Carvalho Chehab goto error;
50989a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
50999a0bf528SMauro Carvalho Chehab if (status < 0)
51009a0bf528SMauro Carvalho Chehab goto error;
51019a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
51029a0bf528SMauro Carvalho Chehab if (status < 0)
51039a0bf528SMauro Carvalho Chehab goto error;
51049a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
51059a0bf528SMauro Carvalho Chehab if (status < 0)
51069a0bf528SMauro Carvalho Chehab goto error;
51079a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
51089a0bf528SMauro Carvalho Chehab if (status < 0)
51099a0bf528SMauro Carvalho Chehab goto error;
51109a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
51119a0bf528SMauro Carvalho Chehab if (status < 0)
51129a0bf528SMauro Carvalho Chehab goto error;
51139a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
51149a0bf528SMauro Carvalho Chehab if (status < 0)
51159a0bf528SMauro Carvalho Chehab goto error;
51169a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
51179a0bf528SMauro Carvalho Chehab if (status < 0)
51189a0bf528SMauro Carvalho Chehab goto error;
51199a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
51209a0bf528SMauro Carvalho Chehab if (status < 0)
51219a0bf528SMauro Carvalho Chehab goto error;
51229a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
51239a0bf528SMauro Carvalho Chehab if (status < 0)
51249a0bf528SMauro Carvalho Chehab goto error;
51259a0bf528SMauro Carvalho Chehab
51269a0bf528SMauro Carvalho Chehab
51279a0bf528SMauro Carvalho Chehab /* QAM State Machine (FSM) Thresholds */
51289a0bf528SMauro Carvalho Chehab
51299a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
51309a0bf528SMauro Carvalho Chehab if (status < 0)
51319a0bf528SMauro Carvalho Chehab goto error;
51329a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
51339a0bf528SMauro Carvalho Chehab if (status < 0)
51349a0bf528SMauro Carvalho Chehab goto error;
51359a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
51369a0bf528SMauro Carvalho Chehab if (status < 0)
51379a0bf528SMauro Carvalho Chehab goto error;
51389a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
51399a0bf528SMauro Carvalho Chehab if (status < 0)
51409a0bf528SMauro Carvalho Chehab goto error;
51419a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
51429a0bf528SMauro Carvalho Chehab if (status < 0)
51439a0bf528SMauro Carvalho Chehab goto error;
51449a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
51459a0bf528SMauro Carvalho Chehab if (status < 0)
51469a0bf528SMauro Carvalho Chehab goto error;
51479a0bf528SMauro Carvalho Chehab
51489a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
51499a0bf528SMauro Carvalho Chehab if (status < 0)
51509a0bf528SMauro Carvalho Chehab goto error;
51519a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
51529a0bf528SMauro Carvalho Chehab if (status < 0)
51539a0bf528SMauro Carvalho Chehab goto error;
51549a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
51559a0bf528SMauro Carvalho Chehab if (status < 0)
51569a0bf528SMauro Carvalho Chehab goto error;
51579a0bf528SMauro Carvalho Chehab
51589a0bf528SMauro Carvalho Chehab
51599a0bf528SMauro Carvalho Chehab /* QAM FSM Tracking Parameters */
51609a0bf528SMauro Carvalho Chehab
51619a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
51629a0bf528SMauro Carvalho Chehab if (status < 0)
51639a0bf528SMauro Carvalho Chehab goto error;
51649a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
51659a0bf528SMauro Carvalho Chehab if (status < 0)
51669a0bf528SMauro Carvalho Chehab goto error;
51679a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
51689a0bf528SMauro Carvalho Chehab if (status < 0)
51699a0bf528SMauro Carvalho Chehab goto error;
51709a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
51719a0bf528SMauro Carvalho Chehab if (status < 0)
51729a0bf528SMauro Carvalho Chehab goto error;
51739a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
51749a0bf528SMauro Carvalho Chehab if (status < 0)
51759a0bf528SMauro Carvalho Chehab goto error;
51769a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
51779a0bf528SMauro Carvalho Chehab if (status < 0)
51789a0bf528SMauro Carvalho Chehab goto error;
51799a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
51809a0bf528SMauro Carvalho Chehab error:
51819a0bf528SMauro Carvalho Chehab if (status < 0)
51823a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
51839a0bf528SMauro Carvalho Chehab return status;
51849a0bf528SMauro Carvalho Chehab }
51859a0bf528SMauro Carvalho Chehab
51869a0bf528SMauro Carvalho Chehab
51879a0bf528SMauro Carvalho Chehab /*============================================================================*/
518834eb9751SMauro Carvalho Chehab /*
51899a0bf528SMauro Carvalho Chehab * \brief Reset QAM block.
51909a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
51919a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
51929a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
51939a0bf528SMauro Carvalho Chehab */
qam_reset_qam(struct drxk_state * state)5194cd7a67a4SMauro Carvalho Chehab static int qam_reset_qam(struct drxk_state *state)
51959a0bf528SMauro Carvalho Chehab {
51969a0bf528SMauro Carvalho Chehab int status;
5197cd7a67a4SMauro Carvalho Chehab u16 cmd_result;
51989a0bf528SMauro Carvalho Chehab
51999a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
52009a0bf528SMauro Carvalho Chehab /* Stop QAM comstate->m_exec */
52019a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
52029a0bf528SMauro Carvalho Chehab if (status < 0)
52039a0bf528SMauro Carvalho Chehab goto error;
52049a0bf528SMauro Carvalho Chehab
5205ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5206ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
5207ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
52089a0bf528SMauro Carvalho Chehab error:
52099a0bf528SMauro Carvalho Chehab if (status < 0)
52103a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
52119a0bf528SMauro Carvalho Chehab return status;
52129a0bf528SMauro Carvalho Chehab }
52139a0bf528SMauro Carvalho Chehab
52149a0bf528SMauro Carvalho Chehab /*============================================================================*/
52159a0bf528SMauro Carvalho Chehab
521634eb9751SMauro Carvalho Chehab /*
52179a0bf528SMauro Carvalho Chehab * \brief Set QAM symbolrate.
52189a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
52199a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52209a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52219a0bf528SMauro Carvalho Chehab */
qam_set_symbolrate(struct drxk_state * state)5222cd7a67a4SMauro Carvalho Chehab static int qam_set_symbolrate(struct drxk_state *state)
52239a0bf528SMauro Carvalho Chehab {
5224cd7a67a4SMauro Carvalho Chehab u32 adc_frequency = 0;
5225cd7a67a4SMauro Carvalho Chehab u32 symb_freq = 0;
5226cd7a67a4SMauro Carvalho Chehab u32 iqm_rc_rate = 0;
52279a0bf528SMauro Carvalho Chehab u16 ratesel = 0;
5228cd7a67a4SMauro Carvalho Chehab u32 lc_symb_rate = 0;
52299a0bf528SMauro Carvalho Chehab int status;
52309a0bf528SMauro Carvalho Chehab
52319a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
52329a0bf528SMauro Carvalho Chehab /* Select & calculate correct IQM rate */
5233cd7a67a4SMauro Carvalho Chehab adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
52349a0bf528SMauro Carvalho Chehab ratesel = 0;
52359a0bf528SMauro Carvalho Chehab if (state->props.symbol_rate <= 1188750)
52369a0bf528SMauro Carvalho Chehab ratesel = 3;
52379a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 2377500)
52389a0bf528SMauro Carvalho Chehab ratesel = 2;
52399a0bf528SMauro Carvalho Chehab else if (state->props.symbol_rate <= 4755000)
52409a0bf528SMauro Carvalho Chehab ratesel = 1;
52419a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FD_RATESEL__A, ratesel);
52429a0bf528SMauro Carvalho Chehab if (status < 0)
52439a0bf528SMauro Carvalho Chehab goto error;
52449a0bf528SMauro Carvalho Chehab
52459a0bf528SMauro Carvalho Chehab /*
52469a0bf528SMauro Carvalho Chehab IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
52479a0bf528SMauro Carvalho Chehab */
5248cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate * (1 << ratesel);
5249cd7a67a4SMauro Carvalho Chehab if (symb_freq == 0) {
52509a0bf528SMauro Carvalho Chehab /* Divide by zero */
52519a0bf528SMauro Carvalho Chehab status = -EINVAL;
52529a0bf528SMauro Carvalho Chehab goto error;
52539a0bf528SMauro Carvalho Chehab }
5254cd7a67a4SMauro Carvalho Chehab iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
5255cd7a67a4SMauro Carvalho Chehab (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
52569a0bf528SMauro Carvalho Chehab (1 << 23);
5257cd7a67a4SMauro Carvalho Chehab status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
52589a0bf528SMauro Carvalho Chehab if (status < 0)
52599a0bf528SMauro Carvalho Chehab goto error;
5260cd7a67a4SMauro Carvalho Chehab state->m_iqm_rc_rate = iqm_rc_rate;
52619a0bf528SMauro Carvalho Chehab /*
5262cd7a67a4SMauro Carvalho Chehab LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15))
52639a0bf528SMauro Carvalho Chehab */
5264cd7a67a4SMauro Carvalho Chehab symb_freq = state->props.symbol_rate;
5265cd7a67a4SMauro Carvalho Chehab if (adc_frequency == 0) {
52669a0bf528SMauro Carvalho Chehab /* Divide by zero */
52679a0bf528SMauro Carvalho Chehab status = -EINVAL;
52689a0bf528SMauro Carvalho Chehab goto error;
52699a0bf528SMauro Carvalho Chehab }
5270cd7a67a4SMauro Carvalho Chehab lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
5271cd7a67a4SMauro Carvalho Chehab (Frac28a((symb_freq % adc_frequency), adc_frequency) >>
52729a0bf528SMauro Carvalho Chehab 16);
5273cd7a67a4SMauro Carvalho Chehab if (lc_symb_rate > 511)
5274cd7a67a4SMauro Carvalho Chehab lc_symb_rate = 511;
5275cd7a67a4SMauro Carvalho Chehab status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
52769a0bf528SMauro Carvalho Chehab
52779a0bf528SMauro Carvalho Chehab error:
52789a0bf528SMauro Carvalho Chehab if (status < 0)
52793a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
52809a0bf528SMauro Carvalho Chehab return status;
52819a0bf528SMauro Carvalho Chehab }
52829a0bf528SMauro Carvalho Chehab
52839a0bf528SMauro Carvalho Chehab /*============================================================================*/
52849a0bf528SMauro Carvalho Chehab
528534eb9751SMauro Carvalho Chehab /*
52869a0bf528SMauro Carvalho Chehab * \brief Get QAM lock status.
52879a0bf528SMauro Carvalho Chehab * \param demod: instance of demod.
52889a0bf528SMauro Carvalho Chehab * \param channel: pointer to channel data.
52899a0bf528SMauro Carvalho Chehab * \return DRXStatus_t.
52909a0bf528SMauro Carvalho Chehab */
52919a0bf528SMauro Carvalho Chehab
get_qam_lock_status(struct drxk_state * state,u32 * p_lock_status)5292cd7a67a4SMauro Carvalho Chehab static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
52939a0bf528SMauro Carvalho Chehab {
52949a0bf528SMauro Carvalho Chehab int status;
5295cd7a67a4SMauro Carvalho Chehab u16 result[2] = { 0, 0 };
52969a0bf528SMauro Carvalho Chehab
52979a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
5298cd7a67a4SMauro Carvalho Chehab *p_lock_status = NOT_LOCKED;
52999a0bf528SMauro Carvalho Chehab status = scu_command(state,
53009a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM |
53019a0bf528SMauro Carvalho Chehab SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5302cd7a67a4SMauro Carvalho Chehab result);
53039a0bf528SMauro Carvalho Chehab if (status < 0)
53043a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
53059a0bf528SMauro Carvalho Chehab
5306cd7a67a4SMauro Carvalho Chehab if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
53079a0bf528SMauro Carvalho Chehab /* 0x0000 NOT LOCKED */
5308cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
53099a0bf528SMauro Carvalho Chehab /* 0x4000 DEMOD LOCKED */
5310cd7a67a4SMauro Carvalho Chehab *p_lock_status = DEMOD_LOCK;
5311cd7a67a4SMauro Carvalho Chehab } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
53129a0bf528SMauro Carvalho Chehab /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5313cd7a67a4SMauro Carvalho Chehab *p_lock_status = MPEG_LOCK;
53149a0bf528SMauro Carvalho Chehab } else {
53159a0bf528SMauro Carvalho Chehab /* 0xC000 NEVER LOCKED */
53169a0bf528SMauro Carvalho Chehab /* (system will never be able to lock to the signal) */
5317ab5060cdSMauro Carvalho Chehab /*
5318ab5060cdSMauro Carvalho Chehab * TODO: check this, intermediate & standard specific lock
5319ab5060cdSMauro Carvalho Chehab * states are not taken into account here
5320ab5060cdSMauro Carvalho Chehab */
5321cd7a67a4SMauro Carvalho Chehab *p_lock_status = NEVER_LOCK;
53229a0bf528SMauro Carvalho Chehab }
53239a0bf528SMauro Carvalho Chehab return status;
53249a0bf528SMauro Carvalho Chehab }
53259a0bf528SMauro Carvalho Chehab
53269a0bf528SMauro Carvalho Chehab #define QAM_MIRROR__M 0x03
53279a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_NORMAL 0x00
53289a0bf528SMauro Carvalho Chehab #define QAM_MIRRORED 0x01
53299a0bf528SMauro Carvalho Chehab #define QAM_MIRROR_AUTO_ON 0x02
53309a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE__M 0x10
53319a0bf528SMauro Carvalho Chehab #define QAM_LOCKRANGE_NORMAL 0x10
53329a0bf528SMauro Carvalho Chehab
qam_demodulator_command(struct drxk_state * state,int number_of_parameters)5333cd7a67a4SMauro Carvalho Chehab static int qam_demodulator_command(struct drxk_state *state,
5334cd7a67a4SMauro Carvalho Chehab int number_of_parameters)
53359a0bf528SMauro Carvalho Chehab {
53369a0bf528SMauro Carvalho Chehab int status;
5337cd7a67a4SMauro Carvalho Chehab u16 cmd_result;
5338cd7a67a4SMauro Carvalho Chehab u16 set_param_parameters[4] = { 0, 0, 0, 0 };
53399a0bf528SMauro Carvalho Chehab
5340cd7a67a4SMauro Carvalho Chehab set_param_parameters[0] = state->m_constellation; /* modulation */
5341cd7a67a4SMauro Carvalho Chehab set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
53429a0bf528SMauro Carvalho Chehab
5343cd7a67a4SMauro Carvalho Chehab if (number_of_parameters == 2) {
5344cd7a67a4SMauro Carvalho Chehab u16 set_env_parameters[1] = { 0 };
53459a0bf528SMauro Carvalho Chehab
5346cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C)
5347cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_C;
53489a0bf528SMauro Carvalho Chehab else
5349cd7a67a4SMauro Carvalho Chehab set_env_parameters[0] = QAM_TOP_ANNEX_A;
53509a0bf528SMauro Carvalho Chehab
53519a0bf528SMauro Carvalho Chehab status = scu_command(state,
5352ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM
5353ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5354cd7a67a4SMauro Carvalho Chehab 1, set_env_parameters, 1, &cmd_result);
53559a0bf528SMauro Carvalho Chehab if (status < 0)
53569a0bf528SMauro Carvalho Chehab goto error;
53579a0bf528SMauro Carvalho Chehab
53589a0bf528SMauro Carvalho Chehab status = scu_command(state,
5359ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM
5360ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5361cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters,
5362cd7a67a4SMauro Carvalho Chehab 1, &cmd_result);
5363cd7a67a4SMauro Carvalho Chehab } else if (number_of_parameters == 4) {
5364cd7a67a4SMauro Carvalho Chehab if (state->m_operation_mode == OM_QAM_ITU_C)
5365cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_C;
53669a0bf528SMauro Carvalho Chehab else
5367cd7a67a4SMauro Carvalho Chehab set_param_parameters[2] = QAM_TOP_ANNEX_A;
53689a0bf528SMauro Carvalho Chehab
5369cd7a67a4SMauro Carvalho Chehab set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
53709a0bf528SMauro Carvalho Chehab /* Env parameters */
5371868c9a17SMauro Carvalho Chehab /* check for LOCKRANGE Extended */
5372cd7a67a4SMauro Carvalho Chehab /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
53739a0bf528SMauro Carvalho Chehab
53749a0bf528SMauro Carvalho Chehab status = scu_command(state,
5375ab5060cdSMauro Carvalho Chehab SCU_RAM_COMMAND_STANDARD_QAM
5376ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5377cd7a67a4SMauro Carvalho Chehab number_of_parameters, set_param_parameters,
5378cd7a67a4SMauro Carvalho Chehab 1, &cmd_result);
53799a0bf528SMauro Carvalho Chehab } else {
53803a4398f5SMauro Carvalho Chehab pr_warn("Unknown QAM demodulator parameter count %d\n",
53813a4398f5SMauro Carvalho Chehab number_of_parameters);
538294af1b63SMauro Carvalho Chehab status = -EINVAL;
53839a0bf528SMauro Carvalho Chehab }
53849a0bf528SMauro Carvalho Chehab
53859a0bf528SMauro Carvalho Chehab error:
53869a0bf528SMauro Carvalho Chehab if (status < 0)
53873a4398f5SMauro Carvalho Chehab pr_warn("Warning %d on %s\n", status, __func__);
53889a0bf528SMauro Carvalho Chehab return status;
53899a0bf528SMauro Carvalho Chehab }
53909a0bf528SMauro Carvalho Chehab
set_qam(struct drxk_state * state,u16 intermediate_freqk_hz,s32 tuner_freq_offset)5391cd7a67a4SMauro Carvalho Chehab static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
5392cd7a67a4SMauro Carvalho Chehab s32 tuner_freq_offset)
53939a0bf528SMauro Carvalho Chehab {
53949a0bf528SMauro Carvalho Chehab int status;
5395cd7a67a4SMauro Carvalho Chehab u16 cmd_result;
5396cd7a67a4SMauro Carvalho Chehab int qam_demod_param_count = state->qam_demod_parameter_count;
53979a0bf528SMauro Carvalho Chehab
53989a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
53999a0bf528SMauro Carvalho Chehab /*
54009a0bf528SMauro Carvalho Chehab * STEP 1: reset demodulator
54019a0bf528SMauro Carvalho Chehab * resets FEC DI and FEC RS
54029a0bf528SMauro Carvalho Chehab * resets QAM block
54039a0bf528SMauro Carvalho Chehab * resets SCU variables
54049a0bf528SMauro Carvalho Chehab */
54059a0bf528SMauro Carvalho Chehab status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
54069a0bf528SMauro Carvalho Chehab if (status < 0)
54079a0bf528SMauro Carvalho Chehab goto error;
54089a0bf528SMauro Carvalho Chehab status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
54099a0bf528SMauro Carvalho Chehab if (status < 0)
54109a0bf528SMauro Carvalho Chehab goto error;
5411cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state);
54129a0bf528SMauro Carvalho Chehab if (status < 0)
54139a0bf528SMauro Carvalho Chehab goto error;
54149a0bf528SMauro Carvalho Chehab
54159a0bf528SMauro Carvalho Chehab /*
54169a0bf528SMauro Carvalho Chehab * STEP 2: configure demodulator
54179a0bf528SMauro Carvalho Chehab * -set params; resets IQM,QAM,FEC HW; initializes some
54189a0bf528SMauro Carvalho Chehab * SCU variables
54199a0bf528SMauro Carvalho Chehab */
5420cd7a67a4SMauro Carvalho Chehab status = qam_set_symbolrate(state);
54219a0bf528SMauro Carvalho Chehab if (status < 0)
54229a0bf528SMauro Carvalho Chehab goto error;
54239a0bf528SMauro Carvalho Chehab
54249a0bf528SMauro Carvalho Chehab /* Set params */
54259a0bf528SMauro Carvalho Chehab switch (state->props.modulation) {
54269a0bf528SMauro Carvalho Chehab case QAM_256:
5427cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM256;
54289a0bf528SMauro Carvalho Chehab break;
54299a0bf528SMauro Carvalho Chehab case QAM_AUTO:
54309a0bf528SMauro Carvalho Chehab case QAM_64:
5431cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM64;
54329a0bf528SMauro Carvalho Chehab break;
54339a0bf528SMauro Carvalho Chehab case QAM_16:
5434cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM16;
54359a0bf528SMauro Carvalho Chehab break;
54369a0bf528SMauro Carvalho Chehab case QAM_32:
5437cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM32;
54389a0bf528SMauro Carvalho Chehab break;
54399a0bf528SMauro Carvalho Chehab case QAM_128:
5440cd7a67a4SMauro Carvalho Chehab state->m_constellation = DRX_CONSTELLATION_QAM128;
54419a0bf528SMauro Carvalho Chehab break;
54429a0bf528SMauro Carvalho Chehab default:
54439a0bf528SMauro Carvalho Chehab status = -EINVAL;
54449a0bf528SMauro Carvalho Chehab break;
54459a0bf528SMauro Carvalho Chehab }
54469a0bf528SMauro Carvalho Chehab if (status < 0)
54479a0bf528SMauro Carvalho Chehab goto error;
54489a0bf528SMauro Carvalho Chehab
54499a0bf528SMauro Carvalho Chehab /* Use the 4-parameter if it's requested or we're probing for
54509a0bf528SMauro Carvalho Chehab * the correct command. */
54519a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 4
54529a0bf528SMauro Carvalho Chehab || !state->qam_demod_parameter_count) {
5453cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 4;
5454cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count);
54559a0bf528SMauro Carvalho Chehab }
54569a0bf528SMauro Carvalho Chehab
54579a0bf528SMauro Carvalho Chehab /* Use the 2-parameter command if it was requested or if we're
54589a0bf528SMauro Carvalho Chehab * probing for the correct command and the 4-parameter command
54599a0bf528SMauro Carvalho Chehab * failed. */
54609a0bf528SMauro Carvalho Chehab if (state->qam_demod_parameter_count == 2
54619a0bf528SMauro Carvalho Chehab || (!state->qam_demod_parameter_count && status < 0)) {
5462cd7a67a4SMauro Carvalho Chehab qam_demod_param_count = 2;
5463cd7a67a4SMauro Carvalho Chehab status = qam_demodulator_command(state, qam_demod_param_count);
54649a0bf528SMauro Carvalho Chehab }
54659a0bf528SMauro Carvalho Chehab
54669a0bf528SMauro Carvalho Chehab if (status < 0) {
54670fb220f2SMauro Carvalho Chehab dprintk(1, "Could not set demodulator parameters.\n");
54680fb220f2SMauro Carvalho Chehab dprintk(1,
54690fb220f2SMauro Carvalho Chehab "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
54709a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count,
54719a0bf528SMauro Carvalho Chehab state->microcode_name);
54729a0bf528SMauro Carvalho Chehab goto error;
54739a0bf528SMauro Carvalho Chehab } else if (!state->qam_demod_parameter_count) {
54740fb220f2SMauro Carvalho Chehab dprintk(1,
54750fb220f2SMauro Carvalho Chehab "Auto-probing the QAM command parameters was successful - using %d parameters.\n",
5476cd7a67a4SMauro Carvalho Chehab qam_demod_param_count);
54779a0bf528SMauro Carvalho Chehab
54789a0bf528SMauro Carvalho Chehab /*
54799a0bf528SMauro Carvalho Chehab * One of our commands was successful. We don't need to
54809a0bf528SMauro Carvalho Chehab * auto-probe anymore, now that we got the correct command.
54819a0bf528SMauro Carvalho Chehab */
5482cd7a67a4SMauro Carvalho Chehab state->qam_demod_parameter_count = qam_demod_param_count;
54839a0bf528SMauro Carvalho Chehab }
54849a0bf528SMauro Carvalho Chehab
54859a0bf528SMauro Carvalho Chehab /*
54869a0bf528SMauro Carvalho Chehab * STEP 3: enable the system in a mode where the ADC provides valid
54879a0bf528SMauro Carvalho Chehab * signal setup modulation independent registers
54889a0bf528SMauro Carvalho Chehab */
54899a0bf528SMauro Carvalho Chehab #if 0
5490cd7a67a4SMauro Carvalho Chehab status = set_frequency(channel, tuner_freq_offset));
54919a0bf528SMauro Carvalho Chehab if (status < 0)
54929a0bf528SMauro Carvalho Chehab goto error;
54939a0bf528SMauro Carvalho Chehab #endif
5494ab5060cdSMauro Carvalho Chehab status = set_frequency_shifter(state, intermediate_freqk_hz,
5495ab5060cdSMauro Carvalho Chehab tuner_freq_offset, true);
54969a0bf528SMauro Carvalho Chehab if (status < 0)
54979a0bf528SMauro Carvalho Chehab goto error;
54989a0bf528SMauro Carvalho Chehab
54999a0bf528SMauro Carvalho Chehab /* Setup BER measurement */
5500ab5060cdSMauro Carvalho Chehab status = set_qam_measurement(state, state->m_constellation,
5501ab5060cdSMauro Carvalho Chehab state->props.symbol_rate);
55029a0bf528SMauro Carvalho Chehab if (status < 0)
55039a0bf528SMauro Carvalho Chehab goto error;
55049a0bf528SMauro Carvalho Chehab
55059a0bf528SMauro Carvalho Chehab /* Reset default values */
55069a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
55079a0bf528SMauro Carvalho Chehab if (status < 0)
55089a0bf528SMauro Carvalho Chehab goto error;
55099a0bf528SMauro Carvalho Chehab status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
55109a0bf528SMauro Carvalho Chehab if (status < 0)
55119a0bf528SMauro Carvalho Chehab goto error;
55129a0bf528SMauro Carvalho Chehab
55139a0bf528SMauro Carvalho Chehab /* Reset default LC values */
55149a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
55159a0bf528SMauro Carvalho Chehab if (status < 0)
55169a0bf528SMauro Carvalho Chehab goto error;
55179a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
55189a0bf528SMauro Carvalho Chehab if (status < 0)
55199a0bf528SMauro Carvalho Chehab goto error;
55209a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
55219a0bf528SMauro Carvalho Chehab if (status < 0)
55229a0bf528SMauro Carvalho Chehab goto error;
55239a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_MODE__A, 7);
55249a0bf528SMauro Carvalho Chehab if (status < 0)
55259a0bf528SMauro Carvalho Chehab goto error;
55269a0bf528SMauro Carvalho Chehab
55279a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
55289a0bf528SMauro Carvalho Chehab if (status < 0)
55299a0bf528SMauro Carvalho Chehab goto error;
55309a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
55319a0bf528SMauro Carvalho Chehab if (status < 0)
55329a0bf528SMauro Carvalho Chehab goto error;
55339a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
55349a0bf528SMauro Carvalho Chehab if (status < 0)
55359a0bf528SMauro Carvalho Chehab goto error;
55369a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
55379a0bf528SMauro Carvalho Chehab if (status < 0)
55389a0bf528SMauro Carvalho Chehab goto error;
55399a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
55409a0bf528SMauro Carvalho Chehab if (status < 0)
55419a0bf528SMauro Carvalho Chehab goto error;
55429a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
55439a0bf528SMauro Carvalho Chehab if (status < 0)
55449a0bf528SMauro Carvalho Chehab goto error;
55459a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
55469a0bf528SMauro Carvalho Chehab if (status < 0)
55479a0bf528SMauro Carvalho Chehab goto error;
55489a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
55499a0bf528SMauro Carvalho Chehab if (status < 0)
55509a0bf528SMauro Carvalho Chehab goto error;
55519a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
55529a0bf528SMauro Carvalho Chehab if (status < 0)
55539a0bf528SMauro Carvalho Chehab goto error;
55549a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
55559a0bf528SMauro Carvalho Chehab if (status < 0)
55569a0bf528SMauro Carvalho Chehab goto error;
55579a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
55589a0bf528SMauro Carvalho Chehab if (status < 0)
55599a0bf528SMauro Carvalho Chehab goto error;
55609a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
55619a0bf528SMauro Carvalho Chehab if (status < 0)
55629a0bf528SMauro Carvalho Chehab goto error;
55639a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
55649a0bf528SMauro Carvalho Chehab if (status < 0)
55659a0bf528SMauro Carvalho Chehab goto error;
55669a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
55679a0bf528SMauro Carvalho Chehab if (status < 0)
55689a0bf528SMauro Carvalho Chehab goto error;
55699a0bf528SMauro Carvalho Chehab status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
55709a0bf528SMauro Carvalho Chehab if (status < 0)
55719a0bf528SMauro Carvalho Chehab goto error;
55729a0bf528SMauro Carvalho Chehab
55739a0bf528SMauro Carvalho Chehab /* Mirroring, QAM-block starting point not inverted */
5574ab5060cdSMauro Carvalho Chehab status = write16(state, QAM_SY_SP_INV__A,
5575ab5060cdSMauro Carvalho Chehab QAM_SY_SP_INV_SPECTRUM_INV_DIS);
55769a0bf528SMauro Carvalho Chehab if (status < 0)
55779a0bf528SMauro Carvalho Chehab goto error;
55789a0bf528SMauro Carvalho Chehab
55799a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */
55809a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
55819a0bf528SMauro Carvalho Chehab if (status < 0)
55829a0bf528SMauro Carvalho Chehab goto error;
55839a0bf528SMauro Carvalho Chehab
55849a0bf528SMauro Carvalho Chehab /* STEP 4: modulation specific setup */
55859a0bf528SMauro Carvalho Chehab switch (state->props.modulation) {
55869a0bf528SMauro Carvalho Chehab case QAM_16:
5587cd7a67a4SMauro Carvalho Chehab status = set_qam16(state);
55889a0bf528SMauro Carvalho Chehab break;
55899a0bf528SMauro Carvalho Chehab case QAM_32:
5590cd7a67a4SMauro Carvalho Chehab status = set_qam32(state);
55919a0bf528SMauro Carvalho Chehab break;
55929a0bf528SMauro Carvalho Chehab case QAM_AUTO:
55939a0bf528SMauro Carvalho Chehab case QAM_64:
5594cd7a67a4SMauro Carvalho Chehab status = set_qam64(state);
55959a0bf528SMauro Carvalho Chehab break;
55969a0bf528SMauro Carvalho Chehab case QAM_128:
5597cd7a67a4SMauro Carvalho Chehab status = set_qam128(state);
55989a0bf528SMauro Carvalho Chehab break;
55999a0bf528SMauro Carvalho Chehab case QAM_256:
5600cd7a67a4SMauro Carvalho Chehab status = set_qam256(state);
56019a0bf528SMauro Carvalho Chehab break;
56029a0bf528SMauro Carvalho Chehab default:
56039a0bf528SMauro Carvalho Chehab status = -EINVAL;
56049a0bf528SMauro Carvalho Chehab break;
56059a0bf528SMauro Carvalho Chehab }
56069a0bf528SMauro Carvalho Chehab if (status < 0)
56079a0bf528SMauro Carvalho Chehab goto error;
56089a0bf528SMauro Carvalho Chehab
56099a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */
56109a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
56119a0bf528SMauro Carvalho Chehab if (status < 0)
56129a0bf528SMauro Carvalho Chehab goto error;
56139a0bf528SMauro Carvalho Chehab
56149a0bf528SMauro Carvalho Chehab /* Re-configure MPEG output, requires knowledge of channel bitrate */
56159a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.modulation = channel->modulation; */
56169a0bf528SMauro Carvalho Chehab /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5617cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_setup(state, state->m_operation_mode);
56189a0bf528SMauro Carvalho Chehab if (status < 0)
56199a0bf528SMauro Carvalho Chehab goto error;
56209a0bf528SMauro Carvalho Chehab
5621cd7a67a4SMauro Carvalho Chehab /* start processes */
5622cd7a67a4SMauro Carvalho Chehab status = mpegts_start(state);
56239a0bf528SMauro Carvalho Chehab if (status < 0)
56249a0bf528SMauro Carvalho Chehab goto error;
56259a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
56269a0bf528SMauro Carvalho Chehab if (status < 0)
56279a0bf528SMauro Carvalho Chehab goto error;
56289a0bf528SMauro Carvalho Chehab status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
56299a0bf528SMauro Carvalho Chehab if (status < 0)
56309a0bf528SMauro Carvalho Chehab goto error;
56319a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
56329a0bf528SMauro Carvalho Chehab if (status < 0)
56339a0bf528SMauro Carvalho Chehab goto error;
56349a0bf528SMauro Carvalho Chehab
56359a0bf528SMauro Carvalho Chehab /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5636ab5060cdSMauro Carvalho Chehab status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
5637ab5060cdSMauro Carvalho Chehab | SCU_RAM_COMMAND_CMD_DEMOD_START,
5638ab5060cdSMauro Carvalho Chehab 0, NULL, 1, &cmd_result);
56399a0bf528SMauro Carvalho Chehab if (status < 0)
56409a0bf528SMauro Carvalho Chehab goto error;
56419a0bf528SMauro Carvalho Chehab
56429a0bf528SMauro Carvalho Chehab /* update global DRXK data container */
56439a0bf528SMauro Carvalho Chehab /*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
56449a0bf528SMauro Carvalho Chehab
56459a0bf528SMauro Carvalho Chehab error:
56469a0bf528SMauro Carvalho Chehab if (status < 0)
56473a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
56489a0bf528SMauro Carvalho Chehab return status;
56499a0bf528SMauro Carvalho Chehab }
56509a0bf528SMauro Carvalho Chehab
set_qam_standard(struct drxk_state * state,enum operation_mode o_mode)5651cd7a67a4SMauro Carvalho Chehab static int set_qam_standard(struct drxk_state *state,
5652cd7a67a4SMauro Carvalho Chehab enum operation_mode o_mode)
56539a0bf528SMauro Carvalho Chehab {
56549a0bf528SMauro Carvalho Chehab int status;
56559a0bf528SMauro Carvalho Chehab #ifdef DRXK_QAM_TAPS
56569a0bf528SMauro Carvalho Chehab #define DRXK_QAMA_TAPS_SELECT
56579a0bf528SMauro Carvalho Chehab #include "drxk_filters.h"
56589a0bf528SMauro Carvalho Chehab #undef DRXK_QAMA_TAPS_SELECT
56599a0bf528SMauro Carvalho Chehab #endif
56609a0bf528SMauro Carvalho Chehab
56619a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
56629a0bf528SMauro Carvalho Chehab
56639a0bf528SMauro Carvalho Chehab /* added antenna switch */
5664cd7a67a4SMauro Carvalho Chehab switch_antenna_to_qam(state);
56659a0bf528SMauro Carvalho Chehab
56669a0bf528SMauro Carvalho Chehab /* Ensure correct power-up mode */
5667cd7a67a4SMauro Carvalho Chehab status = power_up_qam(state);
56689a0bf528SMauro Carvalho Chehab if (status < 0)
56699a0bf528SMauro Carvalho Chehab goto error;
56709a0bf528SMauro Carvalho Chehab /* Reset QAM block */
5671cd7a67a4SMauro Carvalho Chehab status = qam_reset_qam(state);
56729a0bf528SMauro Carvalho Chehab if (status < 0)
56739a0bf528SMauro Carvalho Chehab goto error;
56749a0bf528SMauro Carvalho Chehab
56759a0bf528SMauro Carvalho Chehab /* Setup IQM */
56769a0bf528SMauro Carvalho Chehab
56779a0bf528SMauro Carvalho Chehab status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
56789a0bf528SMauro Carvalho Chehab if (status < 0)
56799a0bf528SMauro Carvalho Chehab goto error;
56809a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
56819a0bf528SMauro Carvalho Chehab if (status < 0)
56829a0bf528SMauro Carvalho Chehab goto error;
56839a0bf528SMauro Carvalho Chehab
56849a0bf528SMauro Carvalho Chehab /* Upload IQM Channel Filter settings by
56859a0bf528SMauro Carvalho Chehab boot loader from ROM table */
5686cd7a67a4SMauro Carvalho Chehab switch (o_mode) {
56879a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_A:
5688ab5060cdSMauro Carvalho Chehab status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
5689ab5060cdSMauro Carvalho Chehab DRXK_BLCC_NR_ELEMENTS_TAPS,
5690ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT);
56919a0bf528SMauro Carvalho Chehab break;
56929a0bf528SMauro Carvalho Chehab case OM_QAM_ITU_C:
5693ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
5694ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5695ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS,
5696ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT);
56979a0bf528SMauro Carvalho Chehab if (status < 0)
56989a0bf528SMauro Carvalho Chehab goto error;
5699ab5060cdSMauro Carvalho Chehab status = bl_direct_cmd(state,
5700ab5060cdSMauro Carvalho Chehab IQM_CF_TAP_IM0__A,
5701ab5060cdSMauro Carvalho Chehab DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
5702ab5060cdSMauro Carvalho Chehab DRXK_BLDC_NR_ELEMENTS_TAPS,
5703ab5060cdSMauro Carvalho Chehab DRXK_BLC_TIMEOUT);
57049a0bf528SMauro Carvalho Chehab break;
57059a0bf528SMauro Carvalho Chehab default:
57069a0bf528SMauro Carvalho Chehab status = -EINVAL;
57079a0bf528SMauro Carvalho Chehab }
57089a0bf528SMauro Carvalho Chehab if (status < 0)
57099a0bf528SMauro Carvalho Chehab goto error;
57109a0bf528SMauro Carvalho Chehab
5711ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
57129a0bf528SMauro Carvalho Chehab if (status < 0)
57139a0bf528SMauro Carvalho Chehab goto error;
57149a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_SYMMETRIC__A, 0);
57159a0bf528SMauro Carvalho Chehab if (status < 0)
57169a0bf528SMauro Carvalho Chehab goto error;
5717ab5060cdSMauro Carvalho Chehab status = write16(state, IQM_CF_MIDTAP__A,
5718ab5060cdSMauro Carvalho Chehab ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
57199a0bf528SMauro Carvalho Chehab if (status < 0)
57209a0bf528SMauro Carvalho Chehab goto error;
57219a0bf528SMauro Carvalho Chehab
57229a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_STRETCH__A, 21);
57239a0bf528SMauro Carvalho Chehab if (status < 0)
57249a0bf528SMauro Carvalho Chehab goto error;
57259a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_LEN__A, 0);
57269a0bf528SMauro Carvalho Chehab if (status < 0)
57279a0bf528SMauro Carvalho Chehab goto error;
57289a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_CLP_TH__A, 448);
57299a0bf528SMauro Carvalho Chehab if (status < 0)
57309a0bf528SMauro Carvalho Chehab goto error;
57319a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_SNS_LEN__A, 0);
57329a0bf528SMauro Carvalho Chehab if (status < 0)
57339a0bf528SMauro Carvalho Chehab goto error;
57349a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
57359a0bf528SMauro Carvalho Chehab if (status < 0)
57369a0bf528SMauro Carvalho Chehab goto error;
57379a0bf528SMauro Carvalho Chehab
57389a0bf528SMauro Carvalho Chehab status = write16(state, IQM_FS_ADJ_SEL__A, 1);
57399a0bf528SMauro Carvalho Chehab if (status < 0)
57409a0bf528SMauro Carvalho Chehab goto error;
57419a0bf528SMauro Carvalho Chehab status = write16(state, IQM_RC_ADJ_SEL__A, 1);
57429a0bf528SMauro Carvalho Chehab if (status < 0)
57439a0bf528SMauro Carvalho Chehab goto error;
57449a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_ADJ_SEL__A, 1);
57459a0bf528SMauro Carvalho Chehab if (status < 0)
57469a0bf528SMauro Carvalho Chehab goto error;
57479a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_UPD_SEL__A, 0);
57489a0bf528SMauro Carvalho Chehab if (status < 0)
57499a0bf528SMauro Carvalho Chehab goto error;
57509a0bf528SMauro Carvalho Chehab
57519a0bf528SMauro Carvalho Chehab /* IQM Impulse Noise Processing Unit */
57529a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_CLP_VAL__A, 500);
57539a0bf528SMauro Carvalho Chehab if (status < 0)
57549a0bf528SMauro Carvalho Chehab goto error;
57559a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DATATH__A, 1000);
57569a0bf528SMauro Carvalho Chehab if (status < 0)
57579a0bf528SMauro Carvalho Chehab goto error;
57589a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_BYPASSDET__A, 1);
57599a0bf528SMauro Carvalho Chehab if (status < 0)
57609a0bf528SMauro Carvalho Chehab goto error;
57619a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_DET_LCT__A, 0);
57629a0bf528SMauro Carvalho Chehab if (status < 0)
57639a0bf528SMauro Carvalho Chehab goto error;
57649a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_WND_LEN__A, 1);
57659a0bf528SMauro Carvalho Chehab if (status < 0)
57669a0bf528SMauro Carvalho Chehab goto error;
57679a0bf528SMauro Carvalho Chehab status = write16(state, IQM_CF_PKDTH__A, 1);
57689a0bf528SMauro Carvalho Chehab if (status < 0)
57699a0bf528SMauro Carvalho Chehab goto error;
57709a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_INC_BYPASS__A, 1);
57719a0bf528SMauro Carvalho Chehab if (status < 0)
57729a0bf528SMauro Carvalho Chehab goto error;
57739a0bf528SMauro Carvalho Chehab
57749a0bf528SMauro Carvalho Chehab /* turn on IQMAF. Must be done before setAgc**() */
5775cd7a67a4SMauro Carvalho Chehab status = set_iqm_af(state, true);
57769a0bf528SMauro Carvalho Chehab if (status < 0)
57779a0bf528SMauro Carvalho Chehab goto error;
57789a0bf528SMauro Carvalho Chehab status = write16(state, IQM_AF_START_LOCK__A, 0x01);
57799a0bf528SMauro Carvalho Chehab if (status < 0)
57809a0bf528SMauro Carvalho Chehab goto error;
57819a0bf528SMauro Carvalho Chehab
57829a0bf528SMauro Carvalho Chehab /* IQM will not be reset from here, sync ADC and update/init AGC */
5783cd7a67a4SMauro Carvalho Chehab status = adc_synchronization(state);
57849a0bf528SMauro Carvalho Chehab if (status < 0)
57859a0bf528SMauro Carvalho Chehab goto error;
57869a0bf528SMauro Carvalho Chehab
57879a0bf528SMauro Carvalho Chehab /* Set the FSM step period */
57889a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
57899a0bf528SMauro Carvalho Chehab if (status < 0)
57909a0bf528SMauro Carvalho Chehab goto error;
57919a0bf528SMauro Carvalho Chehab
57929a0bf528SMauro Carvalho Chehab /* Halt SCU to enable safe non-atomic accesses */
57939a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
57949a0bf528SMauro Carvalho Chehab if (status < 0)
57959a0bf528SMauro Carvalho Chehab goto error;
57969a0bf528SMauro Carvalho Chehab
57979a0bf528SMauro Carvalho Chehab /* No more resets of the IQM, current standard correctly set =>
57989a0bf528SMauro Carvalho Chehab now AGCs can be configured. */
57999a0bf528SMauro Carvalho Chehab
5800cd7a67a4SMauro Carvalho Chehab status = init_agc(state, true);
58019a0bf528SMauro Carvalho Chehab if (status < 0)
58029a0bf528SMauro Carvalho Chehab goto error;
5803cd7a67a4SMauro Carvalho Chehab status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
58049a0bf528SMauro Carvalho Chehab if (status < 0)
58059a0bf528SMauro Carvalho Chehab goto error;
58069a0bf528SMauro Carvalho Chehab
58079a0bf528SMauro Carvalho Chehab /* Configure AGC's */
5808cd7a67a4SMauro Carvalho Chehab status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
58099a0bf528SMauro Carvalho Chehab if (status < 0)
58109a0bf528SMauro Carvalho Chehab goto error;
5811cd7a67a4SMauro Carvalho Chehab status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
58129a0bf528SMauro Carvalho Chehab if (status < 0)
58139a0bf528SMauro Carvalho Chehab goto error;
58149a0bf528SMauro Carvalho Chehab
58159a0bf528SMauro Carvalho Chehab /* Activate SCU to enable SCU commands */
58169a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
58179a0bf528SMauro Carvalho Chehab error:
58189a0bf528SMauro Carvalho Chehab if (status < 0)
58193a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
58209a0bf528SMauro Carvalho Chehab return status;
58219a0bf528SMauro Carvalho Chehab }
58229a0bf528SMauro Carvalho Chehab
write_gpio(struct drxk_state * state)5823cd7a67a4SMauro Carvalho Chehab static int write_gpio(struct drxk_state *state)
58249a0bf528SMauro Carvalho Chehab {
58259a0bf528SMauro Carvalho Chehab int status;
58269a0bf528SMauro Carvalho Chehab u16 value = 0;
58279a0bf528SMauro Carvalho Chehab
58289a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
58299a0bf528SMauro Carvalho Chehab /* stop lock indicator process */
5830ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
5831ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
58329a0bf528SMauro Carvalho Chehab if (status < 0)
58339a0bf528SMauro Carvalho Chehab goto error;
58349a0bf528SMauro Carvalho Chehab
58359a0bf528SMauro Carvalho Chehab /* Write magic word to enable pdr reg write */
58369a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
58379a0bf528SMauro Carvalho Chehab if (status < 0)
58389a0bf528SMauro Carvalho Chehab goto error;
58399a0bf528SMauro Carvalho Chehab
5840cd7a67a4SMauro Carvalho Chehab if (state->m_has_sawsw) {
5841cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0001) { /* UIO-1 */
58429a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */
5843ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_TX_CFG__A,
5844ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg);
58459a0bf528SMauro Carvalho Chehab if (status < 0)
58469a0bf528SMauro Carvalho Chehab goto error;
58479a0bf528SMauro Carvalho Chehab
58489a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */
58499a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58509a0bf528SMauro Carvalho Chehab if (status < 0)
58519a0bf528SMauro Carvalho Chehab goto error;
5852cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0001) == 0)
58539a0bf528SMauro Carvalho Chehab value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
58549a0bf528SMauro Carvalho Chehab else
58559a0bf528SMauro Carvalho Chehab value |= 0x8000; /* write one to 15th bit - 1st UIO */
58569a0bf528SMauro Carvalho Chehab /* write back to io data output register */
58579a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58589a0bf528SMauro Carvalho Chehab if (status < 0)
58599a0bf528SMauro Carvalho Chehab goto error;
58609a0bf528SMauro Carvalho Chehab }
5861cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0002) { /* UIO-2 */
58629a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */
5863ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_SMA_RX_CFG__A,
5864ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg);
58659a0bf528SMauro Carvalho Chehab if (status < 0)
58669a0bf528SMauro Carvalho Chehab goto error;
58679a0bf528SMauro Carvalho Chehab
58689a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */
58699a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58709a0bf528SMauro Carvalho Chehab if (status < 0)
58719a0bf528SMauro Carvalho Chehab goto error;
5872cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0002) == 0)
58739a0bf528SMauro Carvalho Chehab value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
58749a0bf528SMauro Carvalho Chehab else
58759a0bf528SMauro Carvalho Chehab value |= 0x4000; /* write one to 14th bit - 2st UIO */
58769a0bf528SMauro Carvalho Chehab /* write back to io data output register */
58779a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58789a0bf528SMauro Carvalho Chehab if (status < 0)
58799a0bf528SMauro Carvalho Chehab goto error;
58809a0bf528SMauro Carvalho Chehab }
5881cd7a67a4SMauro Carvalho Chehab if (state->uio_mask & 0x0004) { /* UIO-3 */
58829a0bf528SMauro Carvalho Chehab /* write to io pad configuration register - output mode */
5883ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_PDR_GPIO_CFG__A,
5884ab5060cdSMauro Carvalho Chehab state->m_gpio_cfg);
58859a0bf528SMauro Carvalho Chehab if (status < 0)
58869a0bf528SMauro Carvalho Chehab goto error;
58879a0bf528SMauro Carvalho Chehab
58889a0bf528SMauro Carvalho Chehab /* use corresponding bit in io data output registar */
58899a0bf528SMauro Carvalho Chehab status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
58909a0bf528SMauro Carvalho Chehab if (status < 0)
58919a0bf528SMauro Carvalho Chehab goto error;
5892cd7a67a4SMauro Carvalho Chehab if ((state->m_gpio & 0x0004) == 0)
58939a0bf528SMauro Carvalho Chehab value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
58949a0bf528SMauro Carvalho Chehab else
58959a0bf528SMauro Carvalho Chehab value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
58969a0bf528SMauro Carvalho Chehab /* write back to io data output register */
58979a0bf528SMauro Carvalho Chehab status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
58989a0bf528SMauro Carvalho Chehab if (status < 0)
58999a0bf528SMauro Carvalho Chehab goto error;
59009a0bf528SMauro Carvalho Chehab }
59019a0bf528SMauro Carvalho Chehab }
59029a0bf528SMauro Carvalho Chehab /* Write magic word to disable pdr reg write */
59039a0bf528SMauro Carvalho Chehab status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
59049a0bf528SMauro Carvalho Chehab error:
59059a0bf528SMauro Carvalho Chehab if (status < 0)
59063a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
59079a0bf528SMauro Carvalho Chehab return status;
59089a0bf528SMauro Carvalho Chehab }
59099a0bf528SMauro Carvalho Chehab
switch_antenna_to_qam(struct drxk_state * state)5910cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_qam(struct drxk_state *state)
59119a0bf528SMauro Carvalho Chehab {
59129a0bf528SMauro Carvalho Chehab int status = 0;
59139a0bf528SMauro Carvalho Chehab bool gpio_state;
59149a0bf528SMauro Carvalho Chehab
59159a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
59169a0bf528SMauro Carvalho Chehab
59179a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio)
59189a0bf528SMauro Carvalho Chehab return 0;
59199a0bf528SMauro Carvalho Chehab
5920cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio;
59219a0bf528SMauro Carvalho Chehab
59229a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt ^ gpio_state) {
59239a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-T mode. Switch */
59249a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt)
5925cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio;
59269a0bf528SMauro Carvalho Chehab else
5927cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio;
5928cd7a67a4SMauro Carvalho Chehab status = write_gpio(state);
59299a0bf528SMauro Carvalho Chehab }
59309a0bf528SMauro Carvalho Chehab if (status < 0)
59313a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
59329a0bf528SMauro Carvalho Chehab return status;
59339a0bf528SMauro Carvalho Chehab }
59349a0bf528SMauro Carvalho Chehab
switch_antenna_to_dvbt(struct drxk_state * state)5935cd7a67a4SMauro Carvalho Chehab static int switch_antenna_to_dvbt(struct drxk_state *state)
59369a0bf528SMauro Carvalho Chehab {
59379a0bf528SMauro Carvalho Chehab int status = 0;
59389a0bf528SMauro Carvalho Chehab bool gpio_state;
59399a0bf528SMauro Carvalho Chehab
59409a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
59419a0bf528SMauro Carvalho Chehab
59429a0bf528SMauro Carvalho Chehab if (!state->antenna_gpio)
59439a0bf528SMauro Carvalho Chehab return 0;
59449a0bf528SMauro Carvalho Chehab
5945cd7a67a4SMauro Carvalho Chehab gpio_state = state->m_gpio & state->antenna_gpio;
59469a0bf528SMauro Carvalho Chehab
59479a0bf528SMauro Carvalho Chehab if (!(state->antenna_dvbt ^ gpio_state)) {
59489a0bf528SMauro Carvalho Chehab /* Antenna is on DVB-C mode. Switch */
59499a0bf528SMauro Carvalho Chehab if (state->antenna_dvbt)
5950cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio;
59519a0bf528SMauro Carvalho Chehab else
5952cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio;
5953cd7a67a4SMauro Carvalho Chehab status = write_gpio(state);
59549a0bf528SMauro Carvalho Chehab }
59559a0bf528SMauro Carvalho Chehab if (status < 0)
59563a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
59579a0bf528SMauro Carvalho Chehab return status;
59589a0bf528SMauro Carvalho Chehab }
59599a0bf528SMauro Carvalho Chehab
59609a0bf528SMauro Carvalho Chehab
power_down_device(struct drxk_state * state)5961cd7a67a4SMauro Carvalho Chehab static int power_down_device(struct drxk_state *state)
59629a0bf528SMauro Carvalho Chehab {
59639a0bf528SMauro Carvalho Chehab /* Power down to requested mode */
59649a0bf528SMauro Carvalho Chehab /* Backup some register settings */
59659a0bf528SMauro Carvalho Chehab /* Set pins with possible pull-ups connected to them in input mode */
59669a0bf528SMauro Carvalho Chehab /* Analog power down */
59679a0bf528SMauro Carvalho Chehab /* ADC power down */
59689a0bf528SMauro Carvalho Chehab /* Power down device */
59699a0bf528SMauro Carvalho Chehab int status;
59709a0bf528SMauro Carvalho Chehab
59719a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
5972cd7a67a4SMauro Carvalho Chehab if (state->m_b_p_down_open_bridge) {
59739a0bf528SMauro Carvalho Chehab /* Open I2C bridge before power down of DRXK */
59749a0bf528SMauro Carvalho Chehab status = ConfigureI2CBridge(state, true);
59759a0bf528SMauro Carvalho Chehab if (status < 0)
59769a0bf528SMauro Carvalho Chehab goto error;
59779a0bf528SMauro Carvalho Chehab }
59789a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */
5979cd7a67a4SMauro Carvalho Chehab status = dvbt_enable_ofdm_token_ring(state, false);
59809a0bf528SMauro Carvalho Chehab if (status < 0)
59819a0bf528SMauro Carvalho Chehab goto error;
59829a0bf528SMauro Carvalho Chehab
5983ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_PWD_MODE__A,
5984ab5060cdSMauro Carvalho Chehab SIO_CC_PWD_MODE_LEVEL_CLOCK);
59859a0bf528SMauro Carvalho Chehab if (status < 0)
59869a0bf528SMauro Carvalho Chehab goto error;
59879a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
59889a0bf528SMauro Carvalho Chehab if (status < 0)
59899a0bf528SMauro Carvalho Chehab goto error;
5990cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5991cd7a67a4SMauro Carvalho Chehab status = hi_cfg_command(state);
59929a0bf528SMauro Carvalho Chehab error:
59939a0bf528SMauro Carvalho Chehab if (status < 0)
59943a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
59959a0bf528SMauro Carvalho Chehab
59969a0bf528SMauro Carvalho Chehab return status;
59979a0bf528SMauro Carvalho Chehab }
59989a0bf528SMauro Carvalho Chehab
init_drxk(struct drxk_state * state)59999a0bf528SMauro Carvalho Chehab static int init_drxk(struct drxk_state *state)
60009a0bf528SMauro Carvalho Chehab {
60019a0bf528SMauro Carvalho Chehab int status = 0, n = 0;
6002cd7a67a4SMauro Carvalho Chehab enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
6003cd7a67a4SMauro Carvalho Chehab u16 driver_version;
60049a0bf528SMauro Carvalho Chehab
60059a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
60067369bbf2SNick Desaulniers if (state->m_drxk_state == DRXK_UNINITIALIZED) {
60079a0bf528SMauro Carvalho Chehab drxk_i2c_lock(state);
6008cd7a67a4SMauro Carvalho Chehab status = power_up_device(state);
60099a0bf528SMauro Carvalho Chehab if (status < 0)
60109a0bf528SMauro Carvalho Chehab goto error;
6011cd7a67a4SMauro Carvalho Chehab status = drxx_open(state);
60129a0bf528SMauro Carvalho Chehab if (status < 0)
60139a0bf528SMauro Carvalho Chehab goto error;
60149a0bf528SMauro Carvalho Chehab /* Soft reset of OFDM-, sys- and osc-clockdomain */
6015ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_CC_SOFT_RST__A,
6016ab5060cdSMauro Carvalho Chehab SIO_CC_SOFT_RST_OFDM__M
6017ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_SYS__M
6018ab5060cdSMauro Carvalho Chehab | SIO_CC_SOFT_RST_OSC__M);
60199a0bf528SMauro Carvalho Chehab if (status < 0)
60209a0bf528SMauro Carvalho Chehab goto error;
60219a0bf528SMauro Carvalho Chehab status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
60229a0bf528SMauro Carvalho Chehab if (status < 0)
60239a0bf528SMauro Carvalho Chehab goto error;
6024ab5060cdSMauro Carvalho Chehab /*
6025ab5060cdSMauro Carvalho Chehab * TODO is this needed? If yes, how much delay in
6026ab5060cdSMauro Carvalho Chehab * worst case scenario
6027ab5060cdSMauro Carvalho Chehab */
6028b72852baSMauro Carvalho Chehab usleep_range(1000, 2000);
6029cd7a67a4SMauro Carvalho Chehab state->m_drxk_a3_patch_code = true;
6030cd7a67a4SMauro Carvalho Chehab status = get_device_capabilities(state);
60319a0bf528SMauro Carvalho Chehab if (status < 0)
60329a0bf528SMauro Carvalho Chehab goto error;
60339a0bf528SMauro Carvalho Chehab
60349a0bf528SMauro Carvalho Chehab /* Bridge delay, uses oscilator clock */
60359a0bf528SMauro Carvalho Chehab /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
60369a0bf528SMauro Carvalho Chehab /* SDA brdige delay */
6037cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay =
6038cd7a67a4SMauro Carvalho Chehab (u16) ((state->m_osc_clock_freq / 1000) *
60399a0bf528SMauro Carvalho Chehab HI_I2C_BRIDGE_DELAY) / 1000;
60409a0bf528SMauro Carvalho Chehab /* Clipping */
6041cd7a67a4SMauro Carvalho Chehab if (state->m_hi_cfg_bridge_delay >
60429a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6043cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay =
60449a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
60459a0bf528SMauro Carvalho Chehab }
60469a0bf528SMauro Carvalho Chehab /* SCL bridge delay, same as SDA for now */
6047cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay +=
6048cd7a67a4SMauro Carvalho Chehab state->m_hi_cfg_bridge_delay <<
60499a0bf528SMauro Carvalho Chehab SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
60509a0bf528SMauro Carvalho Chehab
6051cd7a67a4SMauro Carvalho Chehab status = init_hi(state);
60529a0bf528SMauro Carvalho Chehab if (status < 0)
60539a0bf528SMauro Carvalho Chehab goto error;
60549a0bf528SMauro Carvalho Chehab /* disable various processes */
60559a0bf528SMauro Carvalho Chehab #if NOA1ROM
60569a0bf528SMauro Carvalho Chehab if (!(state->m_DRXK_A1_ROM_CODE)
60579a0bf528SMauro Carvalho Chehab && !(state->m_DRXK_A2_ROM_CODE))
60589a0bf528SMauro Carvalho Chehab #endif
60599a0bf528SMauro Carvalho Chehab {
6060ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_GPIO__A,
6061ab5060cdSMauro Carvalho Chehab SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
60629a0bf528SMauro Carvalho Chehab if (status < 0)
60639a0bf528SMauro Carvalho Chehab goto error;
60649a0bf528SMauro Carvalho Chehab }
60659a0bf528SMauro Carvalho Chehab
60669a0bf528SMauro Carvalho Chehab /* disable MPEG port */
6067cd7a67a4SMauro Carvalho Chehab status = mpegts_disable(state);
60689a0bf528SMauro Carvalho Chehab if (status < 0)
60699a0bf528SMauro Carvalho Chehab goto error;
60709a0bf528SMauro Carvalho Chehab
60719a0bf528SMauro Carvalho Chehab /* Stop AUD and SCU */
60729a0bf528SMauro Carvalho Chehab status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
60739a0bf528SMauro Carvalho Chehab if (status < 0)
60749a0bf528SMauro Carvalho Chehab goto error;
60759a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
60769a0bf528SMauro Carvalho Chehab if (status < 0)
60779a0bf528SMauro Carvalho Chehab goto error;
60789a0bf528SMauro Carvalho Chehab
60799a0bf528SMauro Carvalho Chehab /* enable token-ring bus through OFDM block for possible ucode upload */
6080ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6081ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
60829a0bf528SMauro Carvalho Chehab if (status < 0)
60839a0bf528SMauro Carvalho Chehab goto error;
60849a0bf528SMauro Carvalho Chehab
60859a0bf528SMauro Carvalho Chehab /* include boot loader section */
6086ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_BL_COMM_EXEC__A,
6087ab5060cdSMauro Carvalho Chehab SIO_BL_COMM_EXEC_ACTIVE);
60889a0bf528SMauro Carvalho Chehab if (status < 0)
60899a0bf528SMauro Carvalho Chehab goto error;
6090cd7a67a4SMauro Carvalho Chehab status = bl_chain_cmd(state, 0, 6, 100);
60919a0bf528SMauro Carvalho Chehab if (status < 0)
60929a0bf528SMauro Carvalho Chehab goto error;
60939a0bf528SMauro Carvalho Chehab
60949a0bf528SMauro Carvalho Chehab if (state->fw) {
6095cd7a67a4SMauro Carvalho Chehab status = download_microcode(state, state->fw->data,
60969a0bf528SMauro Carvalho Chehab state->fw->size);
60979a0bf528SMauro Carvalho Chehab if (status < 0)
60989a0bf528SMauro Carvalho Chehab goto error;
60999a0bf528SMauro Carvalho Chehab }
61009a0bf528SMauro Carvalho Chehab
61019a0bf528SMauro Carvalho Chehab /* disable token-ring bus through OFDM block for possible ucode upload */
6102ab5060cdSMauro Carvalho Chehab status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
6103ab5060cdSMauro Carvalho Chehab SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
61049a0bf528SMauro Carvalho Chehab if (status < 0)
61059a0bf528SMauro Carvalho Chehab goto error;
61069a0bf528SMauro Carvalho Chehab
61079a0bf528SMauro Carvalho Chehab /* Run SCU for a little while to initialize microcode version numbers */
61089a0bf528SMauro Carvalho Chehab status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
61099a0bf528SMauro Carvalho Chehab if (status < 0)
61109a0bf528SMauro Carvalho Chehab goto error;
6111cd7a67a4SMauro Carvalho Chehab status = drxx_open(state);
61129a0bf528SMauro Carvalho Chehab if (status < 0)
61139a0bf528SMauro Carvalho Chehab goto error;
61149a0bf528SMauro Carvalho Chehab /* added for test */
61159a0bf528SMauro Carvalho Chehab msleep(30);
61169a0bf528SMauro Carvalho Chehab
6117cd7a67a4SMauro Carvalho Chehab power_mode = DRXK_POWER_DOWN_OFDM;
6118cd7a67a4SMauro Carvalho Chehab status = ctrl_power_mode(state, &power_mode);
61199a0bf528SMauro Carvalho Chehab if (status < 0)
61209a0bf528SMauro Carvalho Chehab goto error;
61219a0bf528SMauro Carvalho Chehab
61229a0bf528SMauro Carvalho Chehab /* Stamp driver version number in SCU data RAM in BCD code
612339c1cb2bSJonathan McCrohan Done to enable field application engineers to retrieve drxdriver version
61249a0bf528SMauro Carvalho Chehab via I2C from SCU RAM.
61259a0bf528SMauro Carvalho Chehab Not using SCU command interface for SCU register access since no
61269a0bf528SMauro Carvalho Chehab microcode may be present.
61279a0bf528SMauro Carvalho Chehab */
6128cd7a67a4SMauro Carvalho Chehab driver_version =
61299a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
61309a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
61319a0bf528SMauro Carvalho Chehab ((DRXK_VERSION_MAJOR % 10) << 4) +
61329a0bf528SMauro Carvalho Chehab (DRXK_VERSION_MINOR % 10);
6133ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
6134ab5060cdSMauro Carvalho Chehab driver_version);
61359a0bf528SMauro Carvalho Chehab if (status < 0)
61369a0bf528SMauro Carvalho Chehab goto error;
6137cd7a67a4SMauro Carvalho Chehab driver_version =
61389a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
61399a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
61409a0bf528SMauro Carvalho Chehab (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
61419a0bf528SMauro Carvalho Chehab (DRXK_VERSION_PATCH % 10);
6142ab5060cdSMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
6143ab5060cdSMauro Carvalho Chehab driver_version);
61449a0bf528SMauro Carvalho Chehab if (status < 0)
61459a0bf528SMauro Carvalho Chehab goto error;
61469a0bf528SMauro Carvalho Chehab
61473a4398f5SMauro Carvalho Chehab pr_info("DRXK driver version %d.%d.%d\n",
61489a0bf528SMauro Carvalho Chehab DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
61499a0bf528SMauro Carvalho Chehab DRXK_VERSION_PATCH);
61509a0bf528SMauro Carvalho Chehab
6151ab5060cdSMauro Carvalho Chehab /*
6152ab5060cdSMauro Carvalho Chehab * Dirty fix of default values for ROM/PATCH microcode
6153ab5060cdSMauro Carvalho Chehab * Dirty because this fix makes it impossible to setup
6154ab5060cdSMauro Carvalho Chehab * suitable values before calling DRX_Open. This solution
6155ab5060cdSMauro Carvalho Chehab * requires changes to RF AGC speed to be done via the CTRL
6156ab5060cdSMauro Carvalho Chehab * function after calling DRX_Open
6157ab5060cdSMauro Carvalho Chehab */
61589a0bf528SMauro Carvalho Chehab
6159cd7a67a4SMauro Carvalho Chehab /* m_dvbt_rf_agc_cfg.speed = 3; */
61609a0bf528SMauro Carvalho Chehab
61619a0bf528SMauro Carvalho Chehab /* Reset driver debug flags to 0 */
61629a0bf528SMauro Carvalho Chehab status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
61639a0bf528SMauro Carvalho Chehab if (status < 0)
61649a0bf528SMauro Carvalho Chehab goto error;
61659a0bf528SMauro Carvalho Chehab /* driver 0.9.0 */
61669a0bf528SMauro Carvalho Chehab /* Setup FEC OC:
61679a0bf528SMauro Carvalho Chehab NOTE: No more full FEC resets allowed afterwards!! */
61689a0bf528SMauro Carvalho Chehab status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
61699a0bf528SMauro Carvalho Chehab if (status < 0)
61709a0bf528SMauro Carvalho Chehab goto error;
61719a0bf528SMauro Carvalho Chehab /* MPEGTS functions are still the same */
6172cd7a67a4SMauro Carvalho Chehab status = mpegts_dto_init(state);
61739a0bf528SMauro Carvalho Chehab if (status < 0)
61749a0bf528SMauro Carvalho Chehab goto error;
6175cd7a67a4SMauro Carvalho Chehab status = mpegts_stop(state);
61769a0bf528SMauro Carvalho Chehab if (status < 0)
61779a0bf528SMauro Carvalho Chehab goto error;
6178cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_polarity(state);
61799a0bf528SMauro Carvalho Chehab if (status < 0)
61809a0bf528SMauro Carvalho Chehab goto error;
6181cd7a67a4SMauro Carvalho Chehab status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
61829a0bf528SMauro Carvalho Chehab if (status < 0)
61839a0bf528SMauro Carvalho Chehab goto error;
61849a0bf528SMauro Carvalho Chehab /* added: configure GPIO */
6185cd7a67a4SMauro Carvalho Chehab status = write_gpio(state);
61869a0bf528SMauro Carvalho Chehab if (status < 0)
61879a0bf528SMauro Carvalho Chehab goto error;
61889a0bf528SMauro Carvalho Chehab
6189cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED;
61909a0bf528SMauro Carvalho Chehab
6191cd7a67a4SMauro Carvalho Chehab if (state->m_b_power_down) {
6192cd7a67a4SMauro Carvalho Chehab status = power_down_device(state);
61939a0bf528SMauro Carvalho Chehab if (status < 0)
61949a0bf528SMauro Carvalho Chehab goto error;
6195cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_POWERED_DOWN;
61969a0bf528SMauro Carvalho Chehab } else
6197cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_STOPPED;
61989a0bf528SMauro Carvalho Chehab
61999a0bf528SMauro Carvalho Chehab /* Initialize the supported delivery systems */
62009a0bf528SMauro Carvalho Chehab n = 0;
6201cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbc) {
62029a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
62039a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
62049a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-C",
62059a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name));
62069a0bf528SMauro Carvalho Chehab }
6207cd7a67a4SMauro Carvalho Chehab if (state->m_has_dvbt) {
62089a0bf528SMauro Carvalho Chehab state->frontend.ops.delsys[n++] = SYS_DVBT;
62099a0bf528SMauro Carvalho Chehab strlcat(state->frontend.ops.info.name, " DVB-T",
62109a0bf528SMauro Carvalho Chehab sizeof(state->frontend.ops.info.name));
62119a0bf528SMauro Carvalho Chehab }
62129a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state);
62139a0bf528SMauro Carvalho Chehab }
62149a0bf528SMauro Carvalho Chehab error:
62159a0bf528SMauro Carvalho Chehab if (status < 0) {
6216cd7a67a4SMauro Carvalho Chehab state->m_drxk_state = DRXK_NO_DEV;
62179a0bf528SMauro Carvalho Chehab drxk_i2c_unlock(state);
62183a4398f5SMauro Carvalho Chehab pr_err("Error %d on %s\n", status, __func__);
62199a0bf528SMauro Carvalho Chehab }
62209a0bf528SMauro Carvalho Chehab
62219a0bf528SMauro Carvalho Chehab return status;
62229a0bf528SMauro Carvalho Chehab }
62239a0bf528SMauro Carvalho Chehab
load_firmware_cb(const struct firmware * fw,void * context)62249a0bf528SMauro Carvalho Chehab static void load_firmware_cb(const struct firmware *fw,
62259a0bf528SMauro Carvalho Chehab void *context)
62269a0bf528SMauro Carvalho Chehab {
62279a0bf528SMauro Carvalho Chehab struct drxk_state *state = context;
62289a0bf528SMauro Carvalho Chehab
62299a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
62309a0bf528SMauro Carvalho Chehab if (!fw) {
62313a4398f5SMauro Carvalho Chehab pr_err("Could not load firmware file %s.\n",
62329a0bf528SMauro Carvalho Chehab state->microcode_name);
62333a4398f5SMauro Carvalho Chehab pr_info("Copy %s to your hotplug directory!\n",
62349a0bf528SMauro Carvalho Chehab state->microcode_name);
62359a0bf528SMauro Carvalho Chehab state->microcode_name = NULL;
62369a0bf528SMauro Carvalho Chehab
62379a0bf528SMauro Carvalho Chehab /*
62389a0bf528SMauro Carvalho Chehab * As firmware is now load asynchronous, it is not possible
62399a0bf528SMauro Carvalho Chehab * anymore to fail at frontend attach. We might silently
62409a0bf528SMauro Carvalho Chehab * return here, and hope that the driver won't crash.
62419a0bf528SMauro Carvalho Chehab * We might also change all DVB callbacks to return -ENODEV
62429a0bf528SMauro Carvalho Chehab * if the device is not initialized.
62439a0bf528SMauro Carvalho Chehab * As the DRX-K devices have their own internal firmware,
62449a0bf528SMauro Carvalho Chehab * let's just hope that it will match a firmware revision
62459a0bf528SMauro Carvalho Chehab * compatible with this driver and proceed.
62469a0bf528SMauro Carvalho Chehab */
62479a0bf528SMauro Carvalho Chehab }
62489a0bf528SMauro Carvalho Chehab state->fw = fw;
62499a0bf528SMauro Carvalho Chehab
62509a0bf528SMauro Carvalho Chehab init_drxk(state);
62519a0bf528SMauro Carvalho Chehab }
62529a0bf528SMauro Carvalho Chehab
drxk_release(struct dvb_frontend * fe)62539a0bf528SMauro Carvalho Chehab static void drxk_release(struct dvb_frontend *fe)
62549a0bf528SMauro Carvalho Chehab {
62559a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
62569a0bf528SMauro Carvalho Chehab
62579a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
62589a0bf528SMauro Carvalho Chehab release_firmware(state->fw);
62599a0bf528SMauro Carvalho Chehab
62609a0bf528SMauro Carvalho Chehab kfree(state);
62619a0bf528SMauro Carvalho Chehab }
62629a0bf528SMauro Carvalho Chehab
drxk_sleep(struct dvb_frontend * fe)62639a0bf528SMauro Carvalho Chehab static int drxk_sleep(struct dvb_frontend *fe)
62649a0bf528SMauro Carvalho Chehab {
62659a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
62669a0bf528SMauro Carvalho Chehab
62679a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
62689a0bf528SMauro Carvalho Chehab
6269cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
62709a0bf528SMauro Carvalho Chehab return -ENODEV;
6271cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
62729a0bf528SMauro Carvalho Chehab return 0;
62739a0bf528SMauro Carvalho Chehab
6274cd7a67a4SMauro Carvalho Chehab shut_down(state);
62759a0bf528SMauro Carvalho Chehab return 0;
62769a0bf528SMauro Carvalho Chehab }
62779a0bf528SMauro Carvalho Chehab
drxk_gate_ctrl(struct dvb_frontend * fe,int enable)62789a0bf528SMauro Carvalho Chehab static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
62799a0bf528SMauro Carvalho Chehab {
62809a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
62819a0bf528SMauro Carvalho Chehab
62829a0bf528SMauro Carvalho Chehab dprintk(1, ": %s\n", enable ? "enable" : "disable");
62839a0bf528SMauro Carvalho Chehab
6284cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
62859a0bf528SMauro Carvalho Chehab return -ENODEV;
62869a0bf528SMauro Carvalho Chehab
62879a0bf528SMauro Carvalho Chehab return ConfigureI2CBridge(state, enable ? true : false);
62889a0bf528SMauro Carvalho Chehab }
62899a0bf528SMauro Carvalho Chehab
drxk_set_parameters(struct dvb_frontend * fe)62909a0bf528SMauro Carvalho Chehab static int drxk_set_parameters(struct dvb_frontend *fe)
62919a0bf528SMauro Carvalho Chehab {
62929a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
62939a0bf528SMauro Carvalho Chehab u32 delsys = p->delivery_system, old_delsys;
62949a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
62959a0bf528SMauro Carvalho Chehab u32 IF;
62969a0bf528SMauro Carvalho Chehab
62979a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
62989a0bf528SMauro Carvalho Chehab
6299cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
63009a0bf528SMauro Carvalho Chehab return -ENODEV;
63019a0bf528SMauro Carvalho Chehab
6302cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
63039a0bf528SMauro Carvalho Chehab return -EAGAIN;
63049a0bf528SMauro Carvalho Chehab
63059a0bf528SMauro Carvalho Chehab if (!fe->ops.tuner_ops.get_if_frequency) {
63063a4398f5SMauro Carvalho Chehab pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
63079a0bf528SMauro Carvalho Chehab return -EINVAL;
63089a0bf528SMauro Carvalho Chehab }
63099a0bf528SMauro Carvalho Chehab
63109a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
63119a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
63129a0bf528SMauro Carvalho Chehab if (fe->ops.tuner_ops.set_params)
63139a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe);
63149a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
63159a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 0);
63169a0bf528SMauro Carvalho Chehab
63179a0bf528SMauro Carvalho Chehab old_delsys = state->props.delivery_system;
63189a0bf528SMauro Carvalho Chehab state->props = *p;
63199a0bf528SMauro Carvalho Chehab
63209a0bf528SMauro Carvalho Chehab if (old_delsys != delsys) {
6321cd7a67a4SMauro Carvalho Chehab shut_down(state);
63229a0bf528SMauro Carvalho Chehab switch (delsys) {
63239a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A:
63249a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C:
6325cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbc)
63269a0bf528SMauro Carvalho Chehab return -EINVAL;
6327ab5060cdSMauro Carvalho Chehab state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
6328ab5060cdSMauro Carvalho Chehab true : false;
63299a0bf528SMauro Carvalho Chehab if (state->m_itut_annex_c)
6330cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_C);
63319a0bf528SMauro Carvalho Chehab else
6332cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_QAM_ITU_A);
63339a0bf528SMauro Carvalho Chehab break;
63349a0bf528SMauro Carvalho Chehab case SYS_DVBT:
6335cd7a67a4SMauro Carvalho Chehab if (!state->m_has_dvbt)
63369a0bf528SMauro Carvalho Chehab return -EINVAL;
6337cd7a67a4SMauro Carvalho Chehab setoperation_mode(state, OM_DVBT);
63389a0bf528SMauro Carvalho Chehab break;
63399a0bf528SMauro Carvalho Chehab default:
63409a0bf528SMauro Carvalho Chehab return -EINVAL;
63419a0bf528SMauro Carvalho Chehab }
63429a0bf528SMauro Carvalho Chehab }
63439a0bf528SMauro Carvalho Chehab
63449a0bf528SMauro Carvalho Chehab fe->ops.tuner_ops.get_if_frequency(fe, &IF);
6345cd7a67a4SMauro Carvalho Chehab start(state, 0, IF);
63469a0bf528SMauro Carvalho Chehab
634739c1cb2bSJonathan McCrohan /* After set_frontend, stats aren't available */
63488f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE;
63498f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63508f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63518f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63528f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63538f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63548f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63558f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
63568f3741e0SMauro Carvalho Chehab
63579a0bf528SMauro Carvalho Chehab /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
63589a0bf528SMauro Carvalho Chehab
63599a0bf528SMauro Carvalho Chehab return 0;
63609a0bf528SMauro Carvalho Chehab }
63619a0bf528SMauro Carvalho Chehab
get_strength(struct drxk_state * state,u64 * strength)636259a7a23cSMauro Carvalho Chehab static int get_strength(struct drxk_state *state, u64 *strength)
636359a7a23cSMauro Carvalho Chehab {
636459a7a23cSMauro Carvalho Chehab int status;
6365cd7a67a4SMauro Carvalho Chehab struct s_cfg_agc rf_agc, if_agc;
6366cd7a67a4SMauro Carvalho Chehab u32 total_gain = 0;
636759a7a23cSMauro Carvalho Chehab u32 atten = 0;
6368cd7a67a4SMauro Carvalho Chehab u32 agc_range = 0;
636959a7a23cSMauro Carvalho Chehab u16 scu_lvl = 0;
637059a7a23cSMauro Carvalho Chehab u16 scu_coc = 0;
637159a7a23cSMauro Carvalho Chehab /* FIXME: those are part of the tuner presets */
6372cd7a67a4SMauro Carvalho Chehab u16 tuner_rf_gain = 50; /* Default value on az6007 driver */
6373cd7a67a4SMauro Carvalho Chehab u16 tuner_if_gain = 40; /* Default value on az6007 driver */
637459a7a23cSMauro Carvalho Chehab
637559a7a23cSMauro Carvalho Chehab *strength = 0;
637659a7a23cSMauro Carvalho Chehab
6377cd7a67a4SMauro Carvalho Chehab if (is_dvbt(state)) {
6378cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_dvbt_rf_agc_cfg;
6379cd7a67a4SMauro Carvalho Chehab if_agc = state->m_dvbt_if_agc_cfg;
6380cd7a67a4SMauro Carvalho Chehab } else if (is_qam(state)) {
6381cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_qam_rf_agc_cfg;
6382cd7a67a4SMauro Carvalho Chehab if_agc = state->m_qam_if_agc_cfg;
638359a7a23cSMauro Carvalho Chehab } else {
6384cd7a67a4SMauro Carvalho Chehab rf_agc = state->m_atv_rf_agc_cfg;
6385cd7a67a4SMauro Carvalho Chehab if_agc = state->m_atv_if_agc_cfg;
638659a7a23cSMauro Carvalho Chehab }
638759a7a23cSMauro Carvalho Chehab
6388cd7a67a4SMauro Carvalho Chehab if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
6389cd7a67a4SMauro Carvalho Chehab /* SCU output_level */
639059a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
639159a7a23cSMauro Carvalho Chehab if (status < 0)
639259a7a23cSMauro Carvalho Chehab return status;
639359a7a23cSMauro Carvalho Chehab
639459a7a23cSMauro Carvalho Chehab /* SCU c.o.c. */
6395d259a5eeSChristophe JAILLET status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
639659a7a23cSMauro Carvalho Chehab if (status < 0)
639759a7a23cSMauro Carvalho Chehab return status;
639859a7a23cSMauro Carvalho Chehab
639959a7a23cSMauro Carvalho Chehab if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
6400cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = scu_lvl + scu_coc;
640159a7a23cSMauro Carvalho Chehab else
6402cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = 0xffff;
640359a7a23cSMauro Carvalho Chehab
640459a7a23cSMauro Carvalho Chehab /* Take RF gain into account */
6405cd7a67a4SMauro Carvalho Chehab total_gain += tuner_rf_gain;
640659a7a23cSMauro Carvalho Chehab
640759a7a23cSMauro Carvalho Chehab /* clip output value */
6408cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level < rf_agc.min_output_level)
6409cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.min_output_level;
6410cd7a67a4SMauro Carvalho Chehab if (rf_agc.output_level > rf_agc.max_output_level)
6411cd7a67a4SMauro Carvalho Chehab rf_agc.output_level = rf_agc.max_output_level;
641259a7a23cSMauro Carvalho Chehab
6413cd7a67a4SMauro Carvalho Chehab agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
6414cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) {
641559a7a23cSMauro Carvalho Chehab atten += 100UL *
6416cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_rf_gain)) *
6417cd7a67a4SMauro Carvalho Chehab ((u32)(rf_agc.output_level - rf_agc.min_output_level))
6418cd7a67a4SMauro Carvalho Chehab / agc_range;
641959a7a23cSMauro Carvalho Chehab }
642059a7a23cSMauro Carvalho Chehab }
642159a7a23cSMauro Carvalho Chehab
6422cd7a67a4SMauro Carvalho Chehab if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
642359a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
6424cd7a67a4SMauro Carvalho Chehab &if_agc.output_level);
642559a7a23cSMauro Carvalho Chehab if (status < 0)
642659a7a23cSMauro Carvalho Chehab return status;
642759a7a23cSMauro Carvalho Chehab
642859a7a23cSMauro Carvalho Chehab status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
6429cd7a67a4SMauro Carvalho Chehab &if_agc.top);
643059a7a23cSMauro Carvalho Chehab if (status < 0)
643159a7a23cSMauro Carvalho Chehab return status;
643259a7a23cSMauro Carvalho Chehab
643359a7a23cSMauro Carvalho Chehab /* Take IF gain into account */
6434cd7a67a4SMauro Carvalho Chehab total_gain += (u32) tuner_if_gain;
643559a7a23cSMauro Carvalho Chehab
643659a7a23cSMauro Carvalho Chehab /* clip output value */
6437cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level < if_agc.min_output_level)
6438cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.min_output_level;
6439cd7a67a4SMauro Carvalho Chehab if (if_agc.output_level > if_agc.max_output_level)
6440cd7a67a4SMauro Carvalho Chehab if_agc.output_level = if_agc.max_output_level;
644159a7a23cSMauro Carvalho Chehab
6442cd7a67a4SMauro Carvalho Chehab agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level);
6443cd7a67a4SMauro Carvalho Chehab if (agc_range > 0) {
644459a7a23cSMauro Carvalho Chehab atten += 100UL *
6445cd7a67a4SMauro Carvalho Chehab ((u32)(tuner_if_gain)) *
6446cd7a67a4SMauro Carvalho Chehab ((u32)(if_agc.output_level - if_agc.min_output_level))
6447cd7a67a4SMauro Carvalho Chehab / agc_range;
644859a7a23cSMauro Carvalho Chehab }
644959a7a23cSMauro Carvalho Chehab }
645059a7a23cSMauro Carvalho Chehab
645159a7a23cSMauro Carvalho Chehab /*
645259a7a23cSMauro Carvalho Chehab * Convert to 0..65535 scale.
645359a7a23cSMauro Carvalho Chehab * If it can't be measured (AGC is disabled), just show 100%.
645459a7a23cSMauro Carvalho Chehab */
6455cd7a67a4SMauro Carvalho Chehab if (total_gain > 0)
6456cd7a67a4SMauro Carvalho Chehab *strength = (65535UL * atten / total_gain / 100);
645759a7a23cSMauro Carvalho Chehab else
645859a7a23cSMauro Carvalho Chehab *strength = 65535;
645959a7a23cSMauro Carvalho Chehab
646059a7a23cSMauro Carvalho Chehab return 0;
646159a7a23cSMauro Carvalho Chehab }
646259a7a23cSMauro Carvalho Chehab
drxk_get_stats(struct dvb_frontend * fe)64638f3741e0SMauro Carvalho Chehab static int drxk_get_stats(struct dvb_frontend *fe)
64649a0bf528SMauro Carvalho Chehab {
64658f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache;
64669a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
64678f3741e0SMauro Carvalho Chehab int status;
64689a0bf528SMauro Carvalho Chehab u32 stat;
64698f3741e0SMauro Carvalho Chehab u16 reg16;
64708f3741e0SMauro Carvalho Chehab u32 post_bit_count;
64718f3741e0SMauro Carvalho Chehab u32 post_bit_err_count;
64728f3741e0SMauro Carvalho Chehab u32 post_bit_error_scale;
64738f3741e0SMauro Carvalho Chehab u32 pre_bit_err_count;
64748f3741e0SMauro Carvalho Chehab u32 pre_bit_count;
64758f3741e0SMauro Carvalho Chehab u32 pkt_count;
64768f3741e0SMauro Carvalho Chehab u32 pkt_error_count;
647759a7a23cSMauro Carvalho Chehab s32 cnr;
64789a0bf528SMauro Carvalho Chehab
6479cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
64809a0bf528SMauro Carvalho Chehab return -ENODEV;
6481cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
64829a0bf528SMauro Carvalho Chehab return -EAGAIN;
64839a0bf528SMauro Carvalho Chehab
64848f3741e0SMauro Carvalho Chehab /* get status */
64858f3741e0SMauro Carvalho Chehab state->fe_status = 0;
6486cd7a67a4SMauro Carvalho Chehab get_lock_status(state, &stat);
64879a0bf528SMauro Carvalho Chehab if (stat == MPEG_LOCK)
64888f3741e0SMauro Carvalho Chehab state->fe_status |= 0x1f;
64899a0bf528SMauro Carvalho Chehab if (stat == FEC_LOCK)
64908f3741e0SMauro Carvalho Chehab state->fe_status |= 0x0f;
64919a0bf528SMauro Carvalho Chehab if (stat == DEMOD_LOCK)
64928f3741e0SMauro Carvalho Chehab state->fe_status |= 0x07;
64938f3741e0SMauro Carvalho Chehab
649459a7a23cSMauro Carvalho Chehab /*
649559a7a23cSMauro Carvalho Chehab * Estimate signal strength from AGC
649659a7a23cSMauro Carvalho Chehab */
649759a7a23cSMauro Carvalho Chehab get_strength(state, &c->strength.stat[0].uvalue);
649859a7a23cSMauro Carvalho Chehab c->strength.stat[0].scale = FE_SCALE_RELATIVE;
649959a7a23cSMauro Carvalho Chehab
650059a7a23cSMauro Carvalho Chehab
65018f3741e0SMauro Carvalho Chehab if (stat >= DEMOD_LOCK) {
6502cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &cnr);
65038f3741e0SMauro Carvalho Chehab c->cnr.stat[0].svalue = cnr * 100;
65048f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
65058f3741e0SMauro Carvalho Chehab } else {
65068f3741e0SMauro Carvalho Chehab c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65078f3741e0SMauro Carvalho Chehab }
65088f3741e0SMauro Carvalho Chehab
65098f3741e0SMauro Carvalho Chehab if (stat < FEC_LOCK) {
65108f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65118f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65128f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65138f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65148f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65158f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
65168f3741e0SMauro Carvalho Chehab return 0;
65178f3741e0SMauro Carvalho Chehab }
65188f3741e0SMauro Carvalho Chehab
65198f3741e0SMauro Carvalho Chehab /* Get post BER */
65208f3741e0SMauro Carvalho Chehab
65218f3741e0SMauro Carvalho Chehab /* BER measurement is valid if at least FEC lock is achieved */
65228f3741e0SMauro Carvalho Chehab
6523ab5060cdSMauro Carvalho Chehab /*
6524ab5060cdSMauro Carvalho Chehab * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
6525ab5060cdSMauro Carvalho Chehab * written to set nr of symbols or bits over which to measure
6526ab5060cdSMauro Carvalho Chehab * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
6527ab5060cdSMauro Carvalho Chehab */
65288f3741e0SMauro Carvalho Chehab
65298f3741e0SMauro Carvalho Chehab /* Read registers for post/preViterbi BER calculation */
65308f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16);
65318f3741e0SMauro Carvalho Chehab if (status < 0)
65328f3741e0SMauro Carvalho Chehab goto error;
65338f3741e0SMauro Carvalho Chehab pre_bit_err_count = reg16;
65348f3741e0SMauro Carvalho Chehab
65358f3741e0SMauro Carvalho Chehab status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16);
65368f3741e0SMauro Carvalho Chehab if (status < 0)
65378f3741e0SMauro Carvalho Chehab goto error;
65388f3741e0SMauro Carvalho Chehab pre_bit_count = reg16;
65398f3741e0SMauro Carvalho Chehab
65408f3741e0SMauro Carvalho Chehab /* Number of bit-errors */
65418f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16);
65428f3741e0SMauro Carvalho Chehab if (status < 0)
65438f3741e0SMauro Carvalho Chehab goto error;
65448f3741e0SMauro Carvalho Chehab post_bit_err_count = reg16;
65458f3741e0SMauro Carvalho Chehab
65468f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16);
65478f3741e0SMauro Carvalho Chehab if (status < 0)
65488f3741e0SMauro Carvalho Chehab goto error;
65498f3741e0SMauro Carvalho Chehab post_bit_error_scale = reg16;
65508f3741e0SMauro Carvalho Chehab
65518f3741e0SMauro Carvalho Chehab status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16);
65528f3741e0SMauro Carvalho Chehab if (status < 0)
65538f3741e0SMauro Carvalho Chehab goto error;
65548f3741e0SMauro Carvalho Chehab pkt_count = reg16;
65558f3741e0SMauro Carvalho Chehab
65568f3741e0SMauro Carvalho Chehab status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16);
65578f3741e0SMauro Carvalho Chehab if (status < 0)
65588f3741e0SMauro Carvalho Chehab goto error;
65598f3741e0SMauro Carvalho Chehab pkt_error_count = reg16;
65608f3741e0SMauro Carvalho Chehab write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
65618f3741e0SMauro Carvalho Chehab
65628f3741e0SMauro Carvalho Chehab post_bit_err_count *= post_bit_error_scale;
65638f3741e0SMauro Carvalho Chehab
65648f3741e0SMauro Carvalho Chehab post_bit_count = pkt_count * 204 * 8;
65658f3741e0SMauro Carvalho Chehab
65668f3741e0SMauro Carvalho Chehab /* Store the results */
65678f3741e0SMauro Carvalho Chehab c->block_error.stat[0].scale = FE_SCALE_COUNTER;
65688f3741e0SMauro Carvalho Chehab c->block_error.stat[0].uvalue += pkt_error_count;
65698f3741e0SMauro Carvalho Chehab c->block_count.stat[0].scale = FE_SCALE_COUNTER;
65708f3741e0SMauro Carvalho Chehab c->block_count.stat[0].uvalue += pkt_count;
65718f3741e0SMauro Carvalho Chehab
65728f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
65738f3741e0SMauro Carvalho Chehab c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
65748f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
65758f3741e0SMauro Carvalho Chehab c->pre_bit_count.stat[0].uvalue += pre_bit_count;
65768f3741e0SMauro Carvalho Chehab
65778f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
65788f3741e0SMauro Carvalho Chehab c->post_bit_error.stat[0].uvalue += post_bit_err_count;
65798f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
65808f3741e0SMauro Carvalho Chehab c->post_bit_count.stat[0].uvalue += post_bit_count;
65818f3741e0SMauro Carvalho Chehab
65828f3741e0SMauro Carvalho Chehab error:
65838f3741e0SMauro Carvalho Chehab return status;
65848f3741e0SMauro Carvalho Chehab }
65858f3741e0SMauro Carvalho Chehab
65868f3741e0SMauro Carvalho Chehab
drxk_read_status(struct dvb_frontend * fe,enum fe_status * status)65870df289a2SMauro Carvalho Chehab static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status)
65888f3741e0SMauro Carvalho Chehab {
65898f3741e0SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
65908f3741e0SMauro Carvalho Chehab int rc;
65918f3741e0SMauro Carvalho Chehab
65928f3741e0SMauro Carvalho Chehab dprintk(1, "\n");
65938f3741e0SMauro Carvalho Chehab
65948f3741e0SMauro Carvalho Chehab rc = drxk_get_stats(fe);
65958f3741e0SMauro Carvalho Chehab if (rc < 0)
65968f3741e0SMauro Carvalho Chehab return rc;
65978f3741e0SMauro Carvalho Chehab
65988f3741e0SMauro Carvalho Chehab *status = state->fe_status;
65998f3741e0SMauro Carvalho Chehab
66009a0bf528SMauro Carvalho Chehab return 0;
66019a0bf528SMauro Carvalho Chehab }
66029a0bf528SMauro Carvalho Chehab
drxk_read_signal_strength(struct dvb_frontend * fe,u16 * strength)66039a0bf528SMauro Carvalho Chehab static int drxk_read_signal_strength(struct dvb_frontend *fe,
66049a0bf528SMauro Carvalho Chehab u16 *strength)
66059a0bf528SMauro Carvalho Chehab {
66069a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
6607340e7696SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache;
66089a0bf528SMauro Carvalho Chehab
66099a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
66109a0bf528SMauro Carvalho Chehab
6611cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
66129a0bf528SMauro Carvalho Chehab return -ENODEV;
6613cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
66149a0bf528SMauro Carvalho Chehab return -EAGAIN;
66159a0bf528SMauro Carvalho Chehab
6616340e7696SMauro Carvalho Chehab *strength = c->strength.stat[0].uvalue;
66179a0bf528SMauro Carvalho Chehab return 0;
66189a0bf528SMauro Carvalho Chehab }
66199a0bf528SMauro Carvalho Chehab
drxk_read_snr(struct dvb_frontend * fe,u16 * snr)66209a0bf528SMauro Carvalho Chehab static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
66219a0bf528SMauro Carvalho Chehab {
66229a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
66239a0bf528SMauro Carvalho Chehab s32 snr2;
66249a0bf528SMauro Carvalho Chehab
66259a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
66269a0bf528SMauro Carvalho Chehab
6627cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
66289a0bf528SMauro Carvalho Chehab return -ENODEV;
6629cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
66309a0bf528SMauro Carvalho Chehab return -EAGAIN;
66319a0bf528SMauro Carvalho Chehab
6632cd7a67a4SMauro Carvalho Chehab get_signal_to_noise(state, &snr2);
66338f3741e0SMauro Carvalho Chehab
66348f3741e0SMauro Carvalho Chehab /* No negative SNR, clip to zero */
66358f3741e0SMauro Carvalho Chehab if (snr2 < 0)
66368f3741e0SMauro Carvalho Chehab snr2 = 0;
66379a0bf528SMauro Carvalho Chehab *snr = snr2 & 0xffff;
66389a0bf528SMauro Carvalho Chehab return 0;
66399a0bf528SMauro Carvalho Chehab }
66409a0bf528SMauro Carvalho Chehab
drxk_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)66419a0bf528SMauro Carvalho Chehab static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
66429a0bf528SMauro Carvalho Chehab {
66439a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
664420694e96SHans Verkuil u16 err = 0;
66459a0bf528SMauro Carvalho Chehab
66469a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
66479a0bf528SMauro Carvalho Chehab
6648cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
66499a0bf528SMauro Carvalho Chehab return -ENODEV;
6650cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
66519a0bf528SMauro Carvalho Chehab return -EAGAIN;
66529a0bf528SMauro Carvalho Chehab
6653cd7a67a4SMauro Carvalho Chehab dvbtqam_get_acc_pkt_err(state, &err);
66549a0bf528SMauro Carvalho Chehab *ucblocks = (u32) err;
66559a0bf528SMauro Carvalho Chehab return 0;
66569a0bf528SMauro Carvalho Chehab }
66579a0bf528SMauro Carvalho Chehab
drxk_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * sets)6658ab5060cdSMauro Carvalho Chehab static int drxk_get_tune_settings(struct dvb_frontend *fe,
6659ab5060cdSMauro Carvalho Chehab struct dvb_frontend_tune_settings *sets)
66609a0bf528SMauro Carvalho Chehab {
66619a0bf528SMauro Carvalho Chehab struct drxk_state *state = fe->demodulator_priv;
66629a0bf528SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
66639a0bf528SMauro Carvalho Chehab
66649a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
66659a0bf528SMauro Carvalho Chehab
6666cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_NO_DEV)
66679a0bf528SMauro Carvalho Chehab return -ENODEV;
6668cd7a67a4SMauro Carvalho Chehab if (state->m_drxk_state == DRXK_UNINITIALIZED)
66699a0bf528SMauro Carvalho Chehab return -EAGAIN;
66709a0bf528SMauro Carvalho Chehab
66719a0bf528SMauro Carvalho Chehab switch (p->delivery_system) {
66729a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A:
66739a0bf528SMauro Carvalho Chehab case SYS_DVBC_ANNEX_C:
66749a0bf528SMauro Carvalho Chehab case SYS_DVBT:
66759a0bf528SMauro Carvalho Chehab sets->min_delay_ms = 3000;
66769a0bf528SMauro Carvalho Chehab sets->max_drift = 0;
66779a0bf528SMauro Carvalho Chehab sets->step_size = 0;
66789a0bf528SMauro Carvalho Chehab return 0;
66799a0bf528SMauro Carvalho Chehab default:
66809a0bf528SMauro Carvalho Chehab return -EINVAL;
66819a0bf528SMauro Carvalho Chehab }
66829a0bf528SMauro Carvalho Chehab }
66839a0bf528SMauro Carvalho Chehab
6684bd336e63SMax Kellermann static const struct dvb_frontend_ops drxk_ops = {
66859a0bf528SMauro Carvalho Chehab /* .delsys will be filled dynamically */
66869a0bf528SMauro Carvalho Chehab .info = {
66879a0bf528SMauro Carvalho Chehab .name = "DRXK",
6688f1b1eabfSMauro Carvalho Chehab .frequency_min_hz = 47 * MHz,
6689f1b1eabfSMauro Carvalho Chehab .frequency_max_hz = 865 * MHz,
66909a0bf528SMauro Carvalho Chehab /* For DVB-C */
66919a0bf528SMauro Carvalho Chehab .symbol_rate_min = 870000,
66929a0bf528SMauro Carvalho Chehab .symbol_rate_max = 11700000,
66939a0bf528SMauro Carvalho Chehab /* For DVB-T */
6694f1b1eabfSMauro Carvalho Chehab .frequency_stepsize_hz = 166667,
66959a0bf528SMauro Carvalho Chehab
66969a0bf528SMauro Carvalho Chehab .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
66979a0bf528SMauro Carvalho Chehab FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
66989a0bf528SMauro Carvalho Chehab FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
66999a0bf528SMauro Carvalho Chehab FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
67009a0bf528SMauro Carvalho Chehab FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
67019a0bf528SMauro Carvalho Chehab FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
67029a0bf528SMauro Carvalho Chehab },
67039a0bf528SMauro Carvalho Chehab
67049a0bf528SMauro Carvalho Chehab .release = drxk_release,
67059a0bf528SMauro Carvalho Chehab .sleep = drxk_sleep,
67069a0bf528SMauro Carvalho Chehab .i2c_gate_ctrl = drxk_gate_ctrl,
67079a0bf528SMauro Carvalho Chehab
67089a0bf528SMauro Carvalho Chehab .set_frontend = drxk_set_parameters,
67099a0bf528SMauro Carvalho Chehab .get_tune_settings = drxk_get_tune_settings,
67109a0bf528SMauro Carvalho Chehab
67119a0bf528SMauro Carvalho Chehab .read_status = drxk_read_status,
67129a0bf528SMauro Carvalho Chehab .read_signal_strength = drxk_read_signal_strength,
67139a0bf528SMauro Carvalho Chehab .read_snr = drxk_read_snr,
67149a0bf528SMauro Carvalho Chehab .read_ucblocks = drxk_read_ucblocks,
67159a0bf528SMauro Carvalho Chehab };
67169a0bf528SMauro Carvalho Chehab
drxk_attach(const struct drxk_config * config,struct i2c_adapter * i2c)67179a0bf528SMauro Carvalho Chehab struct dvb_frontend *drxk_attach(const struct drxk_config *config,
67189a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c)
67199a0bf528SMauro Carvalho Chehab {
67208f3741e0SMauro Carvalho Chehab struct dtv_frontend_properties *p;
67219a0bf528SMauro Carvalho Chehab struct drxk_state *state = NULL;
67229a0bf528SMauro Carvalho Chehab u8 adr = config->adr;
67239a0bf528SMauro Carvalho Chehab int status;
67249a0bf528SMauro Carvalho Chehab
67259a0bf528SMauro Carvalho Chehab dprintk(1, "\n");
67269a0bf528SMauro Carvalho Chehab state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
67279a0bf528SMauro Carvalho Chehab if (!state)
67289a0bf528SMauro Carvalho Chehab return NULL;
67299a0bf528SMauro Carvalho Chehab
67309a0bf528SMauro Carvalho Chehab state->i2c = i2c;
67319a0bf528SMauro Carvalho Chehab state->demod_address = adr;
67329a0bf528SMauro Carvalho Chehab state->single_master = config->single_master;
67339a0bf528SMauro Carvalho Chehab state->microcode_name = config->microcode_name;
67349a0bf528SMauro Carvalho Chehab state->qam_demod_parameter_count = config->qam_demod_parameter_count;
67359a0bf528SMauro Carvalho Chehab state->no_i2c_bridge = config->no_i2c_bridge;
67369a0bf528SMauro Carvalho Chehab state->antenna_gpio = config->antenna_gpio;
67379a0bf528SMauro Carvalho Chehab state->antenna_dvbt = config->antenna_dvbt;
6738cd7a67a4SMauro Carvalho Chehab state->m_chunk_size = config->chunk_size;
67399a0bf528SMauro Carvalho Chehab state->enable_merr_cfg = config->enable_merr_cfg;
67409a0bf528SMauro Carvalho Chehab
67419a0bf528SMauro Carvalho Chehab if (config->dynamic_clk) {
67425a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = false;
67435a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = false;
67449a0bf528SMauro Carvalho Chehab } else {
67455a7f7b79SMauro Carvalho Chehab state->m_dvbt_static_clk = true;
67465a7f7b79SMauro Carvalho Chehab state->m_dvbc_static_clk = true;
67479a0bf528SMauro Carvalho Chehab }
67489a0bf528SMauro Carvalho Chehab
67499a0bf528SMauro Carvalho Chehab
67509a0bf528SMauro Carvalho Chehab if (config->mpeg_out_clk_strength)
6751cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
67529a0bf528SMauro Carvalho Chehab else
6753cd7a67a4SMauro Carvalho Chehab state->m_ts_clockk_strength = 0x06;
67549a0bf528SMauro Carvalho Chehab
67559a0bf528SMauro Carvalho Chehab if (config->parallel_ts)
6756cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = true;
67579a0bf528SMauro Carvalho Chehab else
6758cd7a67a4SMauro Carvalho Chehab state->m_enable_parallel = false;
67599a0bf528SMauro Carvalho Chehab
67609a0bf528SMauro Carvalho Chehab /* NOTE: as more UIO bits will be used, add them to the mask */
6761cd7a67a4SMauro Carvalho Chehab state->uio_mask = config->antenna_gpio;
67629a0bf528SMauro Carvalho Chehab
67639a0bf528SMauro Carvalho Chehab /* Default gpio to DVB-C */
67649a0bf528SMauro Carvalho Chehab if (!state->antenna_dvbt && state->antenna_gpio)
6765cd7a67a4SMauro Carvalho Chehab state->m_gpio |= state->antenna_gpio;
67669a0bf528SMauro Carvalho Chehab else
6767cd7a67a4SMauro Carvalho Chehab state->m_gpio &= ~state->antenna_gpio;
67689a0bf528SMauro Carvalho Chehab
67699a0bf528SMauro Carvalho Chehab mutex_init(&state->mutex);
67709a0bf528SMauro Carvalho Chehab
67719a0bf528SMauro Carvalho Chehab memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
67729a0bf528SMauro Carvalho Chehab state->frontend.demodulator_priv = state;
67739a0bf528SMauro Carvalho Chehab
67749a0bf528SMauro Carvalho Chehab init_state(state);
67759a0bf528SMauro Carvalho Chehab
67769a0bf528SMauro Carvalho Chehab /* Load firmware and initialize DRX-K */
67779a0bf528SMauro Carvalho Chehab if (state->microcode_name) {
67788e30783bSMauro Carvalho Chehab const struct firmware *fw = NULL;
67798e30783bSMauro Carvalho Chehab
67808e30783bSMauro Carvalho Chehab status = request_firmware(&fw, state->microcode_name,
67818e30783bSMauro Carvalho Chehab state->i2c->dev.parent);
67828e30783bSMauro Carvalho Chehab if (status < 0)
67838e30783bSMauro Carvalho Chehab fw = NULL;
67848e30783bSMauro Carvalho Chehab load_firmware_cb(fw, state);
67859a0bf528SMauro Carvalho Chehab } else if (init_drxk(state) < 0)
67869a0bf528SMauro Carvalho Chehab goto error;
67879a0bf528SMauro Carvalho Chehab
67888f3741e0SMauro Carvalho Chehab
67898f3741e0SMauro Carvalho Chehab /* Initialize stats */
67908f3741e0SMauro Carvalho Chehab p = &state->frontend.dtv_property_cache;
67918f3741e0SMauro Carvalho Chehab p->strength.len = 1;
67928f3741e0SMauro Carvalho Chehab p->cnr.len = 1;
67938f3741e0SMauro Carvalho Chehab p->block_error.len = 1;
67948f3741e0SMauro Carvalho Chehab p->block_count.len = 1;
67958f3741e0SMauro Carvalho Chehab p->pre_bit_error.len = 1;
67968f3741e0SMauro Carvalho Chehab p->pre_bit_count.len = 1;
67978f3741e0SMauro Carvalho Chehab p->post_bit_error.len = 1;
67988f3741e0SMauro Carvalho Chehab p->post_bit_count.len = 1;
67998f3741e0SMauro Carvalho Chehab
68008f3741e0SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE;
68018f3741e0SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68028f3741e0SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68038f3741e0SMauro Carvalho Chehab p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68048f3741e0SMauro Carvalho Chehab p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68058f3741e0SMauro Carvalho Chehab p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68068f3741e0SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68078f3741e0SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
68088f3741e0SMauro Carvalho Chehab
68093a4398f5SMauro Carvalho Chehab pr_info("frontend initialized.\n");
68109a0bf528SMauro Carvalho Chehab return &state->frontend;
68119a0bf528SMauro Carvalho Chehab
68129a0bf528SMauro Carvalho Chehab error:
68133a4398f5SMauro Carvalho Chehab pr_err("not found\n");
68149a0bf528SMauro Carvalho Chehab kfree(state);
68159a0bf528SMauro Carvalho Chehab return NULL;
68169a0bf528SMauro Carvalho Chehab }
6817*86495af1SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(drxk_attach);
68189a0bf528SMauro Carvalho Chehab
68199a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("DRX-K driver");
68209a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Ralph Metzler");
68219a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
6822