diff options
Diffstat (limited to 'drivers/media/dvb/frontends/drxk_hard.c')
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.c | 6637 |
1 files changed, 0 insertions, 6637 deletions
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c deleted file mode 100644 index 1ab8154542da..000000000000 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ /dev/null @@ -1,6637 +0,0 @@ -/* - * drxk_hard: DRX-K DVB-C/T demodulator driver - * - * Copyright (C) 2010-2011 Digital Devices GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 only, as published by the Free Software Foundation. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/firmware.h> -#include <linux/i2c.h> -#include <linux/hardirq.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "drxk.h" -#include "drxk_hard.h" - -static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode); -static int PowerDownQAM(struct drxk_state *state); -static int SetDVBTStandard(struct drxk_state *state, - enum OperationMode oMode); -static int SetQAMStandard(struct drxk_state *state, - enum OperationMode oMode); -static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, - s32 tunerFreqOffset); -static int SetDVBTStandard(struct drxk_state *state, - enum OperationMode oMode); -static int DVBTStart(struct drxk_state *state); -static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, - s32 tunerFreqOffset); -static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus); -static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus); -static int SwitchAntennaToQAM(struct drxk_state *state); -static int SwitchAntennaToDVBT(struct drxk_state *state); - -static bool IsDVBT(struct drxk_state *state) -{ - return state->m_OperationMode == OM_DVBT; -} - -static bool IsQAM(struct drxk_state *state) -{ - return state->m_OperationMode == OM_QAM_ITU_A || - state->m_OperationMode == OM_QAM_ITU_B || - state->m_OperationMode == OM_QAM_ITU_C; -} - -bool IsA1WithPatchCode(struct drxk_state *state) -{ - return state->m_DRXK_A1_PATCH_CODE; -} - -bool IsA1WithRomCode(struct drxk_state *state) -{ - return state->m_DRXK_A1_ROM_CODE; -} - -#define NOA1ROM 0 - -#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0) -#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0) - -#define DEFAULT_MER_83 165 -#define DEFAULT_MER_93 250 - -#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH -#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02) -#endif - -#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH -#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) -#endif - -#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 -#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 - -#ifndef DRXK_KI_RAGC_ATV -#define DRXK_KI_RAGC_ATV 4 -#endif -#ifndef DRXK_KI_IAGC_ATV -#define DRXK_KI_IAGC_ATV 6 -#endif -#ifndef DRXK_KI_DAGC_ATV -#define DRXK_KI_DAGC_ATV 7 -#endif - -#ifndef DRXK_KI_RAGC_QAM -#define DRXK_KI_RAGC_QAM 3 -#endif -#ifndef DRXK_KI_IAGC_QAM -#define DRXK_KI_IAGC_QAM 4 -#endif -#ifndef DRXK_KI_DAGC_QAM -#define DRXK_KI_DAGC_QAM 7 -#endif -#ifndef DRXK_KI_RAGC_DVBT -#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2) -#endif -#ifndef DRXK_KI_IAGC_DVBT -#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2) -#endif -#ifndef DRXK_KI_DAGC_DVBT -#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7) -#endif - -#ifndef DRXK_AGC_DAC_OFFSET -#define DRXK_AGC_DAC_OFFSET (0x800) -#endif - -#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ -#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L) -#endif - -#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ -#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L) -#endif - -#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ -#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L) -#endif - -#ifndef DRXK_QAM_SYMBOLRATE_MAX -#define DRXK_QAM_SYMBOLRATE_MAX (7233000) -#endif - -#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56 -#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64 -#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0 -#define DRXK_BL_ROM_OFFSET_TAPS_BG 24 -#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32 -#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40 -#define DRXK_BL_ROM_OFFSET_TAPS_FM 48 -#define DRXK_BL_ROM_OFFSET_UCODE 0 - -#define DRXK_BLC_TIMEOUT 100 - -#define DRXK_BLCC_NR_ELEMENTS_TAPS 2 -#define DRXK_BLCC_NR_ELEMENTS_UCODE 6 - -#define DRXK_BLDC_NR_ELEMENTS_TAPS 28 - -#ifndef DRXK_OFDM_NE_NOTCH_WIDTH -#define DRXK_OFDM_NE_NOTCH_WIDTH (4) -#endif - -#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960) -#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480) -#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008) -#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992) -#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520) - -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); - -#define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ - printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \ -} while (0) - - -static inline u32 MulDiv32(u32 a, u32 b, u32 c) -{ - u64 tmp64; - - tmp64 = (u64) a * (u64) b; - do_div(tmp64, c); - - return (u32) tmp64; -} - -inline u32 Frac28a(u32 a, u32 c) -{ - int i = 0; - u32 Q1 = 0; - u32 R0 = 0; - - R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ - Q1 = a / c; /* integer part, only the 4 least significant bits - will be visible in the result */ - - /* division using radix 16, 7 nibbles in the result */ - for (i = 0; i < 7; i++) { - Q1 = (Q1 << 4) | (R0 / c); - R0 = (R0 % c) << 4; - } - /* rounding */ - if ((R0 >> 3) >= c) - Q1++; - - return Q1; -} - -static u32 Log10Times100(u32 x) -{ - static const u8 scale = 15; - static const u8 indexWidth = 5; - u8 i = 0; - u32 y = 0; - u32 d = 0; - u32 k = 0; - u32 r = 0; - /* - log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n)) - 0 <= n < ((1<<INDEXWIDTH)+1) - */ - - static const u32 log2lut[] = { - 0, /* 0.000000 */ - 290941, /* 290941.300628 */ - 573196, /* 573196.476418 */ - 847269, /* 847269.179851 */ - 1113620, /* 1113620.489452 */ - 1372674, /* 1372673.576986 */ - 1624818, /* 1624817.752104 */ - 1870412, /* 1870411.981536 */ - 2109788, /* 2109787.962654 */ - 2343253, /* 2343252.817465 */ - 2571091, /* 2571091.461923 */ - 2793569, /* 2793568.696416 */ - 3010931, /* 3010931.055901 */ - 3223408, /* 3223408.452106 */ - 3431216, /* 3431215.635215 */ - 3634553, /* 3634553.498355 */ - 3833610, /* 3833610.244726 */ - 4028562, /* 4028562.434393 */ - 4219576, /* 4219575.925308 */ - 4406807, /* 4406806.721144 */ - 4590402, /* 4590401.736809 */ - 4770499, /* 4770499.491025 */ - 4947231, /* 4947230.734179 */ - 5120719, /* 5120719.018555 */ - 5291081, /* 5291081.217197 */ - 5458428, /* 5458427.996830 */ - 5622864, /* 5622864.249668 */ - 5784489, /* 5784489.488298 */ - 5943398, /* 5943398.207380 */ - 6099680, /* 6099680.215452 */ - 6253421, /* 6253420.939751 */ - 6404702, /* 6404701.706649 */ - 6553600, /* 6553600.000000 */ - }; - - - if (x == 0) - return 0; - - /* Scale x (normalize) */ - /* computing y in log(x/y) = log(x) - log(y) */ - if ((x & ((0xffffffff) << (scale + 1))) == 0) { - for (k = scale; k > 0; k--) { - if (x & (((u32) 1) << scale)) - break; - x <<= 1; - } - } else { - for (k = scale; k < 31; k++) { - if ((x & (((u32) (-1)) << (scale + 1))) == 0) - break; - x >>= 1; - } - } - /* - Now x has binary point between bit[scale] and bit[scale-1] - and 1.0 <= x < 2.0 */ - - /* correction for divison: log(x) = log(x/y)+log(y) */ - y = k * ((((u32) 1) << scale) * 200); - - /* remove integer part */ - x &= ((((u32) 1) << scale) - 1); - /* get index */ - i = (u8) (x >> (scale - indexWidth)); - /* compute delta (x - a) */ - d = x & ((((u32) 1) << (scale - indexWidth)) - 1); - /* compute log, multiplication (d* (..)) must be within range ! */ - y += log2lut[i] + - ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth)); - /* Conver to log10() */ - y /= 108853; /* (log2(10) << scale) */ - r = (y >> 1); - /* rounding */ - if (y & ((u32) 1)) - r++; - return r; -} - -/****************************************************************************/ -/* I2C **********************************************************************/ -/****************************************************************************/ - -static int drxk_i2c_lock(struct drxk_state *state) -{ - i2c_lock_adapter(state->i2c); - state->drxk_i2c_exclusive_lock = true; - - return 0; -} - -static void drxk_i2c_unlock(struct drxk_state *state) -{ - if (!state->drxk_i2c_exclusive_lock) - return; - - i2c_unlock_adapter(state->i2c); - state->drxk_i2c_exclusive_lock = false; -} - -static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, - unsigned len) -{ - if (state->drxk_i2c_exclusive_lock) - return __i2c_transfer(state->i2c, msgs, len); - else - return i2c_transfer(state->i2c, msgs, len); -} - -static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) -{ - struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = 1} - }; - - return drxk_i2c_transfer(state, msgs, 1); -} - -static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) -{ - int status; - struct i2c_msg msg = { - .addr = adr, .flags = 0, .buf = data, .len = len }; - - dprintk(3, ":"); - if (debug > 2) { - int i; - for (i = 0; i < len; i++) - printk(KERN_CONT " %02x", data[i]); - printk(KERN_CONT "\n"); - } - status = drxk_i2c_transfer(state, &msg, 1); - if (status >= 0 && status != 1) - status = -EIO; - - if (status < 0) - printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr); - - return status; -} - -static int i2c_read(struct drxk_state *state, - u8 adr, u8 *msg, int len, u8 *answ, int alen) -{ - int status; - struct i2c_msg msgs[2] = { - {.addr = adr, .flags = 0, - .buf = msg, .len = len}, - {.addr = adr, .flags = I2C_M_RD, - .buf = answ, .len = alen} - }; - - status = drxk_i2c_transfer(state, msgs, 2); - if (status != 2) { - if (debug > 2) - printk(KERN_CONT ": ERROR!\n"); - if (status >= 0) - status = -EIO; - - printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr); - return status; - } - if (debug > 2) { - int i; - dprintk(2, ": read from"); - for (i = 0; i < len; i++) - printk(KERN_CONT " %02x", msg[i]); - printk(KERN_CONT ", value = "); - for (i = 0; i < alen; i++) - printk(KERN_CONT " %02x", answ[i]); - printk(KERN_CONT "\n"); - } - return 0; -} - -static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) -{ - int status; - u8 adr = state->demod_address, mm1[4], mm2[2], len; - - if (state->single_master) - flags |= 0xC0; - - if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { - mm1[0] = (((reg << 1) & 0xFF) | 0x01); - mm1[1] = ((reg >> 16) & 0xFF); - mm1[2] = ((reg >> 24) & 0xFF) | flags; - mm1[3] = ((reg >> 7) & 0xFF); - len = 4; - } else { - mm1[0] = ((reg << 1) & 0xFF); - mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); - len = 2; - } - dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); - status = i2c_read(state, adr, mm1, len, mm2, 2); - if (status < 0) - return status; - if (data) - *data = mm2[0] | (mm2[1] << 8); - - return 0; -} - -static int read16(struct drxk_state *state, u32 reg, u16 *data) -{ - return read16_flags(state, reg, data, 0); -} - -static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) -{ - int status; - u8 adr = state->demod_address, mm1[4], mm2[4], len; - - if (state->single_master) - flags |= 0xC0; - - if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { - mm1[0] = (((reg << 1) & 0xFF) | 0x01); - mm1[1] = ((reg >> 16) & 0xFF); - mm1[2] = ((reg >> 24) & 0xFF) | flags; - mm1[3] = ((reg >> 7) & 0xFF); - len = 4; - } else { - mm1[0] = ((reg << 1) & 0xFF); - mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); - len = 2; - } - dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); - status = i2c_read(state, adr, mm1, len, mm2, 4); - if (status < 0) - return status; - if (data) - *data = mm2[0] | (mm2[1] << 8) | - (mm2[2] << 16) | (mm2[3] << 24); - - return 0; -} - -static int read32(struct drxk_state *state, u32 reg, u32 *data) -{ - return read32_flags(state, reg, data, 0); -} - -static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) -{ - u8 adr = state->demod_address, mm[6], len; - - if (state->single_master) - flags |= 0xC0; - if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { - mm[0] = (((reg << 1) & 0xFF) | 0x01); - mm[1] = ((reg >> 16) & 0xFF); - mm[2] = ((reg >> 24) & 0xFF) | flags; - mm[3] = ((reg >> 7) & 0xFF); - len = 4; - } else { - mm[0] = ((reg << 1) & 0xFF); - mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); - len = 2; - } - mm[len] = data & 0xff; - mm[len + 1] = (data >> 8) & 0xff; - - dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); - return i2c_write(state, adr, mm, len + 2); -} - -static int write16(struct drxk_state *state, u32 reg, u16 data) -{ - return write16_flags(state, reg, data, 0); -} - -static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) -{ - u8 adr = state->demod_address, mm[8], len; - - if (state->single_master) - flags |= 0xC0; - if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) { - mm[0] = (((reg << 1) & 0xFF) | 0x01); - mm[1] = ((reg >> 16) & 0xFF); - mm[2] = ((reg >> 24) & 0xFF) | flags; - mm[3] = ((reg >> 7) & 0xFF); - len = 4; - } else { - mm[0] = ((reg << 1) & 0xFF); - mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0)); - len = 2; - } - mm[len] = data & 0xff; - mm[len + 1] = (data >> 8) & 0xff; - mm[len + 2] = (data >> 16) & 0xff; - mm[len + 3] = (data >> 24) & 0xff; - dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); - - return i2c_write(state, adr, mm, len + 4); -} - -static int write32(struct drxk_state *state, u32 reg, u32 data) -{ - return write32_flags(state, reg, data, 0); -} - -static int write_block(struct drxk_state *state, u32 Address, - const int BlockSize, const u8 pBlock[]) -{ - int status = 0, BlkSize = BlockSize; - u8 Flags = 0; - - if (state->single_master) - Flags |= 0xC0; - - while (BlkSize > 0) { - int Chunk = BlkSize > state->m_ChunkSize ? - state->m_ChunkSize : BlkSize; - u8 *AdrBuf = &state->Chunk[0]; - u32 AdrLength = 0; - - if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) { - AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01); - AdrBuf[1] = ((Address >> 16) & 0xFF); - AdrBuf[2] = ((Address >> 24) & 0xFF); - AdrBuf[3] = ((Address >> 7) & 0xFF); - AdrBuf[2] |= Flags; - AdrLength = 4; - if (Chunk == state->m_ChunkSize) - Chunk -= 2; - } else { - AdrBuf[0] = ((Address << 1) & 0xFF); - AdrBuf[1] = (((Address >> 16) & 0x0F) | - ((Address >> 18) & 0xF0)); - AdrLength = 2; - } - memcpy(&state->Chunk[AdrLength], pBlock, Chunk); - dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags); - if (debug > 1) { - int i; - if (pBlock) - for (i = 0; i < Chunk; i++) - printk(KERN_CONT " %02x", pBlock[i]); - printk(KERN_CONT "\n"); - } - status = i2c_write(state, state->demod_address, - &state->Chunk[0], Chunk + AdrLength); - if (status < 0) { - printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n", - __func__, Address); - break; - } - pBlock += Chunk; - Address += (Chunk >> 1); - BlkSize -= Chunk; - } - return status; -} - -#ifndef DRXK_MAX_RETRIES_POWERUP -#define DRXK_MAX_RETRIES_POWERUP 20 -#endif - -int PowerUpDevice(struct drxk_state *state) -{ - int status; - u8 data = 0; - u16 retryCount = 0; - - dprintk(1, "\n"); - - status = i2c_read1(state, state->demod_address, &data); - if (status < 0) { - do { - data = 0; - status = i2c_write(state, state->demod_address, - &data, 1); - msleep(10); - retryCount++; - if (status < 0) - continue; - status = i2c_read1(state, state->demod_address, - &data); - } while (status < 0 && - (retryCount < DRXK_MAX_RETRIES_POWERUP)); - if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP) - goto error; - } - - /* Make sure all clk domains are active */ - status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE); - if (status < 0) - goto error; - status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); - if (status < 0) - goto error; - /* Enable pll lock tests */ - status = write16(state, SIO_CC_PLL_LOCK__A, 1); - if (status < 0) - goto error; - - state->m_currentPowerMode = DRX_POWER_UP; - -error: - if (status < 0) - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - - return status; -} - - -static int init_state(struct drxk_state *state) -{ - /* - * FIXME: most (all?) of the values bellow should be moved into - * struct drxk_config, as they are probably board-specific - */ - u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO; - u32 ulVSBIfAgcOutputLevel = 0; - u32 ulVSBIfAgcMinLevel = 0; - u32 ulVSBIfAgcMaxLevel = 0x7FFF; - u32 ulVSBIfAgcSpeed = 3; - - u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO; - u32 ulVSBRfAgcOutputLevel = 0; - u32 ulVSBRfAgcMinLevel = 0; - u32 ulVSBRfAgcMaxLevel = 0x7FFF; - u32 ulVSBRfAgcSpeed = 3; - u32 ulVSBRfAgcTop = 9500; - u32 ulVSBRfAgcCutOffCurrent = 4000; - - u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO; - u32 ulATVIfAgcOutputLevel = 0; - u32 ulATVIfAgcMinLevel = 0; - u32 ulATVIfAgcMaxLevel = 0; - u32 ulATVIfAgcSpeed = 3; - - u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF; - u32 ulATVRfAgcOutputLevel = 0; - u32 ulATVRfAgcMinLevel = 0; - u32 ulATVRfAgcMaxLevel = 0; - u32 ulATVRfAgcTop = 9500; - u32 ulATVRfAgcCutOffCurrent = 4000; - u32 ulATVRfAgcSpeed = 3; - - u32 ulQual83 = DEFAULT_MER_83; - u32 ulQual93 = DEFAULT_MER_93; - - u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; - u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; - - /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ - /* io_pad_cfg_mode output mode is drive always */ - /* io_pad_cfg_drive is set to power 2 (23 mA) */ - u32 ulGPIOCfg = 0x0113; - u32 ulInvertTSClock = 0; - u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; - u32 ulDVBTBitrate = 50000000; - u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; - - u32 ulInsertRSByte = 0; - - u32 ulRfMirror = 1; - u32 ulPowerDown = 0; - - dprintk(1, "\n"); - - state->m_hasLNA = false; - state->m_hasDVBT = false; - state->m_hasDVBC = false; - state->m_hasATV = false; - state->m_hasOOB = false; - state->m_hasAudio = false; - - if (!state->m_ChunkSize) - state->m_ChunkSize = 124; - - state->m_oscClockFreq = 0; - state->m_smartAntInverted = false; - state->m_bPDownOpenBridge = false; - - /* real system clock frequency in kHz */ - state->m_sysClockFreq = 151875; - /* Timing div, 250ns/Psys */ - /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ - state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) * - HI_I2C_DELAY) / 1000; - /* Clipping */ - if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) - state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; - state->m_HICfgWakeUpKey = (state->demod_address << 1); - /* port/bridge/power down ctrl */ - state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; - - state->m_bPowerDown = (ulPowerDown != 0); - - state->m_DRXK_A1_PATCH_CODE = false; - state->m_DRXK_A1_ROM_CODE = false; - state->m_DRXK_A2_ROM_CODE = false; - state->m_DRXK_A3_ROM_CODE = false; - state->m_DRXK_A2_PATCH_CODE = false; - state->m_DRXK_A3_PATCH_CODE = false; - - /* Init AGC and PGA parameters */ - /* VSB IF */ - state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode); - state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel); - state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel); - state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel); - state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed); - state->m_vsbPgaCfg = 140; - - /* VSB RF */ - state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode); - state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel); - state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel); - state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel); - state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed); - state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop); - state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent); - state->m_vsbPreSawCfg.reference = 0x07; - state->m_vsbPreSawCfg.usePreSaw = true; - - state->m_Quality83percent = DEFAULT_MER_83; - state->m_Quality93percent = DEFAULT_MER_93; - if (ulQual93 <= 500 && ulQual83 < ulQual93) { - state->m_Quality83percent = ulQual83; - state->m_Quality93percent = ulQual93; - } - - /* ATV IF */ - state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode); - state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel); - state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel); - state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel); - state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed); - - /* ATV RF */ - state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode); - state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel); - state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel); - state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel); - state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed); - state->m_atvRfAgcCfg.top = (ulATVRfAgcTop); - state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent); - state->m_atvPreSawCfg.reference = 0x04; - state->m_atvPreSawCfg.usePreSaw = true; - - - /* DVBT RF */ - state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; - state->m_dvbtRfAgcCfg.outputLevel = 0; - state->m_dvbtRfAgcCfg.minOutputLevel = 0; - state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF; - state->m_dvbtRfAgcCfg.top = 0x2100; - state->m_dvbtRfAgcCfg.cutOffCurrent = 4000; - state->m_dvbtRfAgcCfg.speed = 1; - - - /* DVBT IF */ - state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; - state->m_dvbtIfAgcCfg.outputLevel = 0; - state->m_dvbtIfAgcCfg.minOutputLevel = 0; - state->m_dvbtIfAgcCfg.maxOutputLevel = 9000; - state->m_dvbtIfAgcCfg.top = 13424; - state->m_dvbtIfAgcCfg.cutOffCurrent = 0; - state->m_dvbtIfAgcCfg.speed = 3; - state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30; - state->m_dvbtIfAgcCfg.IngainTgtMax = 30000; - /* state->m_dvbtPgaCfg = 140; */ - - state->m_dvbtPreSawCfg.reference = 4; - state->m_dvbtPreSawCfg.usePreSaw = false; - - /* QAM RF */ - state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; - state->m_qamRfAgcCfg.outputLevel = 0; - state->m_qamRfAgcCfg.minOutputLevel = 6023; - state->m_qamRfAgcCfg.maxOutputLevel = 27000; - state->m_qamRfAgcCfg.top = 0x2380; - state->m_qamRfAgcCfg.cutOffCurrent = 4000; - state->m_qamRfAgcCfg.speed = 3; - - /* QAM IF */ - state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; - state->m_qamIfAgcCfg.outputLevel = 0; - state->m_qamIfAgcCfg.minOutputLevel = 0; - state->m_qamIfAgcCfg.maxOutputLevel = 9000; - state->m_qamIfAgcCfg.top = 0x0511; - state->m_qamIfAgcCfg.cutOffCurrent = 0; - state->m_qamIfAgcCfg.speed = 3; - state->m_qamIfAgcCfg.IngainTgtMax = 5119; - state->m_qamIfAgcCfg.FastClipCtrlDelay = 50; - - state->m_qamPgaCfg = 140; - state->m_qamPreSawCfg.reference = 4; - state->m_qamPreSawCfg.usePreSaw = false; - - state->m_OperationMode = OM_NONE; - state->m_DrxkState = DRXK_UNINITIALIZED; - - /* MPEG output configuration */ - state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */ - state->m_insertRSByte = false; /* If TRUE; insert RS byte */ - state->m_invertDATA = false; /* If TRUE; invert DATA signals */ - state->m_invertERR = false; /* If TRUE; invert ERR signal */ - state->m_invertSTR = false; /* If TRUE; invert STR signals */ - state->m_invertVAL = false; /* If TRUE; invert VAL signals */ - state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ - - /* If TRUE; static MPEG clockrate will be used; - otherwise clockrate will adapt to the bitrate of the TS */ - - state->m_DVBTBitrate = ulDVBTBitrate; - state->m_DVBCBitrate = ulDVBCBitrate; - - state->m_TSDataStrength = (ulTSDataStrength & 0x07); - - /* Maximum bitrate in b/s in case static clockrate is selected */ - state->m_mpegTsStaticBitrate = 19392658; - state->m_disableTEIhandling = false; - - if (ulInsertRSByte) - state->m_insertRSByte = true; - - state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; - if (ulMpegLockTimeOut < 10000) - state->m_MpegLockTimeOut = ulMpegLockTimeOut; - state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; - if (ulDemodLockTimeOut < 10000) - state->m_DemodLockTimeOut = ulDemodLockTimeOut; - - /* QAM defaults */ - state->m_Constellation = DRX_CONSTELLATION_AUTO; - state->m_qamInterleaveMode = DRXK_QAM_I12_J17; - state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */ - state->m_fecRsPrescale = 1; - - state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM; - state->m_agcFastClipCtrlDelay = 0; - - state->m_GPIOCfg = (ulGPIOCfg); - - state->m_bPowerDown = false; - state->m_currentPowerMode = DRX_POWER_DOWN; - - state->m_rfmirror = (ulRfMirror == 0); - state->m_IfAgcPol = false; - return 0; -} - -static int DRXX_Open(struct drxk_state *state) -{ - int status = 0; - u32 jtag = 0; - u16 bid = 0; - u16 key = 0; - - dprintk(1, "\n"); - /* stop lock indicator process */ - status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); - if (status < 0) - goto error; - /* Check device id */ - status = read16(state, SIO_TOP_COMM_KEY__A, &key); - if (status < 0) - goto error; - status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); - if (status < 0) - goto error; - status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag); - if (status < 0) - goto error; - status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid); - if (status < 0) - goto error; - status = write16(state, SIO_TOP_COMM_KEY__A, key); -error: - if (status < 0) - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - return status; -} - -static int GetDeviceCapabilities(struct drxk_state *state) -{ - u16 sioPdrOhwCfg = 0; - u32 sioTopJtagidLo = 0; - int status; - const char *spin = ""; - - dprintk(1, "\n"); - - /* driver 0.9.0 */ - /* stop lock indicator process */ - status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); - if (status < 0) - goto error; - status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA); - if (status < 0) - goto error; - status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg); - if (status < 0) - goto error; - status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); - if (status < 0) - goto error; - - switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { - case 0: - /* ignore (bypass ?) */ - break; - case 1: - /* 27 MHz */ - state->m_oscClockFreq = 27000; - break; - case 2: - /* 20.25 MHz */ - state->m_oscClockFreq = 20250; - break; - case 3: - /* 4 MHz */ - state->m_oscClockFreq = 20250; - break; - default: - printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n"); - return -EINVAL; - } - /* - Determine device capabilities - Based on pinning v14 - */ - status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo); - if (status < 0) - goto error; - - printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo); - - /* driver 0.9.0 */ - switch ((sioTopJtagidLo >> 29) & 0xF) { - case 0: - state->m_deviceSpin = DRXK_SPIN_A1; - spin = "A1"; - break; - case 2: - state->m_deviceSpin = DRXK_SPIN_A2; - spin = "A2"; - break; - case 3: - state->m_deviceSpin = DRXK_SPIN_A3; - spin = "A3"; - break; - default: - state->m_deviceSpin = DRXK_SPIN_UNKNOWN; - status = -EINVAL; - printk(KERN_ERR "drxk: Spin %d unknown\n", - (sioTopJtagidLo >> 29) & 0xF); - goto error2; - } - switch ((sioTopJtagidLo >> 12) & 0xFF) { - case 0x13: - /* typeId = DRX3913K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = false; - state->m_hasAudio = false; - state->m_hasDVBT = true; - state->m_hasDVBC = true; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = false; - state->m_hasGPIO1 = false; - state->m_hasIRQN = false; - break; - case 0x15: - /* typeId = DRX3915K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = false; - state->m_hasDVBT = true; - state->m_hasDVBC = false; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x16: - /* typeId = DRX3916K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = false; - state->m_hasDVBT = true; - state->m_hasDVBC = false; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x18: - /* typeId = DRX3918K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = true; - state->m_hasDVBT = true; - state->m_hasDVBC = false; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x21: - /* typeId = DRX3921K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = true; - state->m_hasDVBT = true; - state->m_hasDVBC = true; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x23: - /* typeId = DRX3923K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = true; - state->m_hasDVBT = true; - state->m_hasDVBC = true; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x25: - /* typeId = DRX3925K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = true; - state->m_hasDVBT = true; - state->m_hasDVBC = true; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - case 0x26: - /* typeId = DRX3926K_TYPE_ID */ - state->m_hasLNA = false; - state->m_hasOOB = false; - state->m_hasATV = true; - state->m_hasAudio = false; - state->m_hasDVBT = true; - state->m_hasDVBC = true; - state->m_hasSAWSW = true; - state->m_hasGPIO2 = true; - state->m_hasGPIO1 = true; - state->m_hasIRQN = false; - break; - default: - printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n", - ((sioTopJtagidLo >> 12) & 0xFF)); - status = -EINVAL; - goto error2; - } - - printk(KERN_INFO - "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", - ((sioTopJtagidLo >> 12) & 0xFF), spin, - state->m_oscClockFreq / 1000, - state->m_oscClockFreq % 1000); - -error: - if (status < 0) - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - -error2: - return status; -} - -static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult) -{ - int status; - bool powerdown_cmd; - - dprintk(1, "\n"); - - /* Write command */ - status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd); - if (status < 0) - goto error; - if (cmd == SIO_HI_RA_RAM_CMD_RESET) - msleep(1); - - powerdown_cmd = - (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && - ((state->m_HICfgCtrl) & - SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == - SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); - if (powerdown_cmd == false) { - /* Wait until command rdy */ - u32 retryCount = 0; - u16 waitCmd; - - do { - msleep(1); - retryCount += 1; - status = read16(state, SIO_HI_RA_RAM_CMD__A, - &waitCmd); - } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES) - && (waitCmd != 0)); - if (status < 0) - goto error; - status = read16(state, SIO_HI_RA_RAM_RES__A, pResult); - } -error: - if (status < 0) - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - - return status; -} - -static int HI_CfgCommand(struct drxk_state *state) -{ - int status; - - dprintk(1, "\n"); - - mutex_lock(&state->mutex); - - status = write16(state, SI |