From 078cab821ad997ef9274e4445cb7f06ba2bdb69d Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 3 Jul 2007 16:53:42 +0400 Subject: Add STB0899 support From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2034 +++++++++++++++++++++++ 1 file changed, 2034 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/stb0899_drv.c (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c new file mode 100644 index 000000000..9c54e704e --- /dev/null +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -0,0 +1,2034 @@ +/* + STB0899 Multistandard Frontend driver + Copyright (C) Manu Abraham (abraham.manu@gmail.com) + + Copyright (C) ST Microelectronics + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include + +#include +#include "dvb_frontend.h" + +#include "stb0899_drv.h" +#include "stb0899_priv.h" +#include "stb0899_reg.h" + +static unsigned int verbose = 5; +module_param(verbose, int, 0644); + +/* C/N in dB/10, NIRM/NIRL */ +static const struct stb0899_tab stb0899_cn_tab[] = { + { 200, 2600 }, + { 190, 2700 }, + { 180, 2860 }, + { 170, 3020 }, + { 160, 3210 }, + { 150, 3440 }, + { 140, 3710 }, + { 130, 4010 }, + { 120, 4360 }, + { 110, 4740 }, + { 100, 5190 }, + { 90, 5670 }, + { 80, 6200 }, + { 70, 6770 }, + { 60, 7360 }, + { 50, 7970 }, + { 40, 8250 }, + { 30, 9000 }, + { 20, 9450 }, + { 15, 9600 }, +}; + +/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10. + * As measured, connected to a modulator. + * -8.0 to -50.0 dBm directly connected, + * -52.0 to -74.8 with extra attenuation. + * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm. + * Crude linear extrapolation below -84.8dBm and above -8.0dBm. + */ +static const struct stb0899_tab stb0899_dvbsrf_tab[] = { + { -950, -128 }, + { -748, -94 }, + { -745, -92 }, + { -735, -90 }, + { -720, -87 }, + { -670, -77 }, + { -640, -70 }, + { -610, -62 }, + { -600, -60 }, + { -590, -56 }, + { -560, -41 }, + { -540, -25 }, + { -530, -17 }, + { -520, -11 }, + { -500, 1 }, + { -490, 6 }, + { -480, 10 }, + { -440, 22 }, + { -420, 27 }, + { -400, 31 }, + { -380, 34 }, + { -340, 40 }, + { -320, 43 }, + { -280, 48 }, + { -250, 52 }, + { -230, 55 }, + { -180, 61 }, + { -140, 66 }, + { -90, 73 }, + { -80, 74 }, + { 500, 127 } +}; + +/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10. + * As measured, connected to a modulator. + * -8.0 to -50.1 dBm directly connected, + * -53.0 to -76.6 with extra attenuation. + * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm. + * Crude linear extrapolation below -76.6dBm and above -8.0dBm. + */ +static const struct stb0899_tab stb0899_dvbs2rf_tab[] = { + { 700, 0 }, + { -80, 3217 }, + { -150, 3893 }, + { -190, 4217 }, + { -240, 4621 }, + { -280, 4945 }, + { -320, 5273 }, + { -350, 5545 }, + { -370, 5741 }, + { -410, 6147 }, + { -450, 6671 }, + { -490, 7413 }, + { -501, 7665 }, + { -530, 8767 }, + { -560, 10219 }, + { -580, 10939 }, + { -590, 11518 }, + { -600, 11723 }, + { -650, 12659 }, + { -690, 13219 }, + { -730, 13645 }, + { -750, 13909 }, + { -766, 14153 }, + { -999, 16383 } +}; + +/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/ +struct stb0899_tab stb0899_quant_tab[] = { + { 0, 0 }, + { 0, 100 }, + { 600, 200 }, + { 950, 299 }, + { 1200, 398 }, + { 1400, 501 }, + { 1560, 603 }, + { 1690, 700 }, + { 1810, 804 }, + { 1910, 902 }, + { 2000, 1000 }, + { 2080, 1096 }, + { 2160, 1202 }, + { 2230, 1303 }, + { 2350, 1496 }, + { 2410, 1603 }, + { 2460, 1698 }, + { 2510, 1799 }, + { 2600, 1995 }, + { 2650, 2113 }, + { 2690, 2213 }, + { 2720, 2291 }, + { 2760, 2399 }, + { 2800, 2512 }, + { 2860, 2692 }, + { 2930, 2917 }, + { 2960, 3020 }, + { 3010, 3199 }, + { 3040, 3311 }, + { 3060, 3388 }, + { 3120, 3631 }, + { 3190, 3936 }, + { 3400, 5012 }, + { 3610, 6383 }, + { 3800, 7943 }, + { 4210, 12735 }, + { 4500, 17783 }, + { 4690, 22131 }, + { 4810, 25410 } +}; + +/* DVB-S2 Es/N0 estimate in dB/100 vs read value */ +struct stb0899_tab stb0899_est_tab[] = { + { 0, 0 }, + { 0, 1 }, + { 301, 2 }, + { 1204, 16 }, + { 1806, 64 }, + { 2408, 256 }, + { 2709, 512 }, + { 3010, 1023 }, + { 3311, 2046 }, + { 3612, 4093 }, + { 3823, 6653 }, + { 3913, 8185 }, + { 4010, 10233 }, + { 4107, 12794 }, + { 4214, 16368 }, + { 4266, 18450 }, + { 4311, 20464 }, + { 4353, 22542 }, + { 4391, 24604 }, + { 4425, 26607 }, + { 4457, 28642 }, + { 4487, 30690 }, + { 4515, 32734 }, + { 4612, 40926 }, + { 4692, 49204 }, + { 4816, 65464 }, + { 4913, 81846 }, + { 4993, 98401 }, + { 5060, 114815 }, + { 5118, 131220 }, + { 5200, 158489 }, + { 5300, 199526 }, + { 5400, 251189 }, + { 5500, 316228 }, + { 5600, 398107 }, + { 5720, 524807 }, + { 5721, 526017 }, +}; + +int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg) +{ + int ret; + + u8 b0[] = { reg >> 8, reg & 0xff }; + u8 buf; + + struct i2c_msg msg[] = { + { + .addr = state->config->demod_address, + .flags = 0, + .buf = b0, + .len = 2 + },{ + .addr = state->config->demod_address, + .flags = I2C_M_RD, + .buf = &buf, + .len = 1 + } + }; + + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) { + if (ret != -ERESTARTSYS) + dprintk(verbose, FE_ERROR, 1, + "Read error, Reg=[0x%02x], Status=%d", + reg, ret); + + return ret < 0 ? ret : -EREMOTEIO; + } + if (unlikely(verbose >= FE_DEBUGREG)) + dprintk(verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", + reg, buf); + + + return (unsigned int)buf; +} + +int stb0899_read_reg(struct stb0899_state *state, unsigned int reg) +{ + int result; + + result = _stb0899_read_reg(state, reg); + /* + * Bug ID 9: + * access to 0xf2xx/0xf6xx + * must be followed by read from 0xf2ff/0xf6ff. + */ + if ((reg != 0xf2ff) && (reg != 0xf6ff) && + (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) + _stb0899_read_reg(state, (reg | 0x00ff)); + + return result; +} + +u32 _stb0899_read_s2reg(struct stb0899_state *state, + u32 stb0899_i2cdev, + u32 stb0899_base_addr, + u16 stb0899_reg_offset) +{ + int status; + u32 data; + u8 buf[7] = { 0 }; + u16 tmpaddr; + + u8 buf_0[] = { + GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ + GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ + GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ + }; + u8 buf_1[] = { + 0x00, /* 0xf3 Reg Offset */ + 0x00, /* 0x44 Reg Offset */ + }; + + struct i2c_msg msg_0 = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf_0, + .len = 6 + }; + + struct i2c_msg msg_1 = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf_1, + .len = 2 + }; + + struct i2c_msg msg_r = { + .addr = state->config->demod_address, + .flags = I2C_M_RD, + .buf = buf, + .len = 4 + }; + + tmpaddr = stb0899_reg_offset & 0xff00; + if (!(stb0899_reg_offset & 0x8)) + tmpaddr = stb0899_reg_offset | 0x20; + + buf_1[0] = GETBYTE(tmpaddr, BYTE1); + buf_1[1] = GETBYTE(tmpaddr, BYTE0); + + status = i2c_transfer(state->i2c, &msg_0, 1); + if (status < 1) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); + + goto err; + } + + /* Dummy */ + status = i2c_transfer(state->i2c, &msg_1, 1); + if (status < 1) + goto err; + + status = i2c_transfer(state->i2c, &msg_r, 1); + if (status < 1) + goto err; + + buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); + buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); + + /* Actual */ + status = i2c_transfer(state->i2c, &msg_1, 1); + if (status < 1) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); + goto err; + } + + status = i2c_transfer(state->i2c, &msg_r, 1); + if (status < 1) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); + return status < 0 ? status : -EREMOTEIO; + } + + data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]); + if (unlikely(state->verbose >= FE_DEBUGREG)) + printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data); + + return data; + +err: + return status < 0 ? status : -EREMOTEIO; +} + +int stb0899_write_s2reg(struct stb0899_state *state, + u32 stb0899_i2cdev, + u32 stb0899_base_addr, + u16 stb0899_reg_offset, + u32 stb0899_data) +{ + int status; + + /* Base Address Setup */ + u8 buf_0[] = { + GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ + GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ + GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ + GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ + }; + u8 buf_1[] = { + 0x00, /* 0xf3 Reg Offset */ + 0x00, /* 0x44 Reg Offset */ + 0x00, /* data */ + 0x00, /* data */ + 0x00, /* data */ + 0x00, /* data */ + }; + + struct i2c_msg msg_0 = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf_0, + .len = 6 + }; + + struct i2c_msg msg_1 = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf_1, + .len = 6 + }; + + buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); + buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); + buf_1[2] = GETBYTE(stb0899_data, BYTE0); + buf_1[3] = GETBYTE(stb0899_data, BYTE1); + buf_1[4] = GETBYTE(stb0899_data, BYTE2); + buf_1[5] = GETBYTE(stb0899_data, BYTE3); + + if (unlikely(state->verbose >= FE_DEBUGREG)) + printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data); + + status = i2c_transfer(state->i2c, &msg_0, 1); + if (unlikely(status < 1)) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); + goto err; + } + status = i2c_transfer(state->i2c, &msg_1, 1); + if (unlikely(status < 1)) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", + __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); + + return status < 0 ? status : -EREMOTEIO; + } + + return 0; + +err: + return status < 0 ? status : -EREMOTEIO; +} + +int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, size_t count) +{ + int status; + + u8 b0[] = { reg >> 8, reg & 0xff }; + + struct i2c_msg msg[] = { + { + .addr = state->config->demod_address, + .flags = 0, + .buf = b0, + .len = 2 + },{ + .addr = state->config->demod_address, + .flags = I2C_M_RD, + .buf = buf, + .len = count + } + }; + + status = i2c_transfer(state->i2c, msg, 2); + if (status != 2) { + if (status != -ERESTARTSYS) + printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n", + __func__, reg, count, status); + goto err; + } + /* + * Bug ID 9: + * access to 0xf2xx/0xf6xx + * must be followed by read from 0xf2ff/0xf6ff. + */ + if ((reg != 0xf2ff) && (reg != 0xf6ff) && + (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) + _stb0899_read_reg(state, (reg | 0x00ff)); + + if (unlikely(state->verbose >= FE_DEBUGREG)) { + int i; + + printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); + for (i = 0; i < count; i++) { + printk(" %02x", buf[i]); + } + printk("\n"); + } + + return 0; +err: + return status < 0 ? status : -EREMOTEIO; +} + +int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, size_t count) +{ + int ret; + u8 buf[2 + count]; + struct i2c_msg i2c_msg = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf, + .len = 2 + count + }; + + buf[0] = reg >> 8; + buf[1] = reg & 0xff; + memcpy(&buf[2], data, count); + + if (unlikely(state->verbose >= FE_DEBUGREG)) { + int i; + + printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); + for (i = 0; i < count; i++) + printk(" %02x", data[i]); + printk("\n"); + } + ret = i2c_transfer(state->i2c, &i2c_msg, 1); + + /* + * Bug ID 9: + * access to 0xf2xx/0xf6xx + * must be followed by read from 0xf2ff/0xf6ff. + */ + if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) + stb0899_read_reg(state, (reg | 0x00ff)); + + if (ret != 1) { + if (ret != -ERESTARTSYS) + dprintk(verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", + reg, data[0], count, ret); + return ret < 0 ? ret : -EREMOTEIO; + } + + return 0; +} + +int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) +{ + return stb0899_write_regs(state, reg, &data, 1); +} + +/* + * stb0899_get_mclk + * Get STB0899 master clock frequency + * ExtClk: external clock frequency (Hz) + */ +static u32 stb0899_get_mclk(struct stb0899_state *state) +{ + u32 mclk = 90000000, div = 0; + + div = stb0899_read_reg(state, STB0899_NCOARSE); + mclk = (div + 1) * state->config->xtal_freq / 6; + dprintk(verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk); + + return mclk; +} + +/* + * stb0899_set_mclk + * Set STB0899 master Clock frequency + * Mclk: demodulator master clock + * ExtClk: external clock frequency (Hz) + */ +static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) +{ + struct stb0899_internal *internal = &state->internal; + u8 mdiv = 0; + + dprintk(verbose, FE_DEBUG, 1, "state->config=%p", state->config); + mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1; + dprintk(verbose, FE_DEBUG, 1, "mdiv=%d", mdiv); + + stb0899_write_reg(state, STB0899_NCOARSE, mdiv); + internal->master_clk = stb0899_get_mclk(state); + + dprintk(verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); +} + +static void stb0899_release(struct dvb_frontend *fe) +{ + struct stb0899_state *state = fe->demodulator_priv; + + dprintk(verbose, FE_DEBUG, 1, "Release Frontend"); + kfree(state); +} + +/* + * stb0899_get_alpha + * return: rolloff + */ +static int stb0899_get_alpha(struct stb0899_state *state) +{ + u8 mode_coeff; + + mode_coeff = stb0899_read_reg(state, STB0899_DEMOD); + + if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1) + return 20; + else + return 35; +} + +/* + * stb0899_init_calc + */ +static void stb0899_init_calc(struct stb0899_state *state) +{ + struct stb0899_internal *internal = &state->internal; + int master_clk; + u8 agc[1]; + u8 agc1cn; + u32 reg; + + /* Read registers (in burst mode) */ + agc1cn = stb0899_read_reg(state, STB0899_AGC1CN); + stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ + + /* Initial calculations */ + master_clk = stb0899_get_mclk(state); + internal->t_agc1 = 0; + internal->t_agc2 = 0; + internal->master_clk = master_clk; + internal->mclk = master_clk / 65536L; + internal->rolloff = stb0899_get_alpha(state); + + /* DVBS2 Initial calculations */ + /* Set AGC value to the middle */ + internal->agc_gain = 8154; + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); + STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain); + stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); + + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA); + internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg); + + internal->center_freq = 0; + internal->av_frame_coarse = 10; + internal->av_frame_fine = 20; + internal->step_size = 2; +/* + if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO)) + pParams->IQLocked = 0; + else + pParams->IQLocked = 1; +*/ +} + +static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout) +{ + u8 reg = 0; + unsigned long start = jiffies; + + while (1) { + reg = stb0899_read_reg(state, STB0899_DISSTATUS); + if (!STB0899_GETFIELD(FIFOFULL, reg)) + break; + if ((jiffies - start) > timeout) { + dprintk(verbose, FE_ERROR, 1, "timed out !!"); + return -ETIMEDOUT; + } + } + + return 0; +} + +static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) +{ + struct stb0899_state *state = fe->demodulator_priv; + u8 reg, i; + + if (cmd->msg_len > 8) + return -EINVAL; + + /* enable FIFO precharge */ + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + for (i = 0; i < cmd->msg_len; i++) { + /* wait for FIFO empty */ + if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0) + return -ETIMEDOUT; + + stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]); + } + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + + return 0; +} + +static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout) +{ + u8 reg = 0; + unsigned long start = jiffies; + + while (!STB0899_GETFIELD(RXEND, reg)) { + reg = stb0899_read_reg(state, STB0899_DISRX_ST0); + if (jiffies - start > timeout) { + dprintk(verbose, FE_ERROR, 1, "timed out!!"); + return -ETIMEDOUT; + } + msleep(10); + } + + return 0; +} + +static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) +{ + struct stb0899_state *state = fe->demodulator_priv; + u8 reg, length = 0, i; + int result; + + if (stb0899_wait_diseqc_rxidle(state, 100) < 0) + return -ETIMEDOUT; + + reg = stb0899_read_reg(state, STB0899_DISRX_ST0); + if (STB0899_GETFIELD(RXEND, reg)) { + + reg = stb0899_read_reg(state, STB0899_DISRX_ST1); + length = STB0899_GETFIELD(FIFOBYTENBR, reg); + + if (length > sizeof (reply->msg)) { + result = -EOVERFLOW; + goto exit; + } + reply->msg_len = length; + + /* extract data */ + for (i = 0; i < length; i++) + reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO); + } + + return 0; +exit: + + return result; +} + +static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout) +{ + u8 reg = 0; + unsigned long start = jiffies; + + while (!STB0899_GETFIELD(TXIDLE, reg)) { + reg = stb0899_read_reg(state, STB0899_DISSTATUS); + if (jiffies - start > timeout) { + dprintk(verbose, FE_ERROR, 1, "timed out!!"); + return -ETIMEDOUT; + } + msleep(10); + } + return 0; +} + +static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +{ + struct stb0899_state *state = fe->demodulator_priv; + u8 reg, old_state; + + /* wait for diseqc idle */ + if (stb0899_wait_diseqc_txidle(state, 100) < 0) + return -ETIMEDOUT; + + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + old_state = reg; + /* set to burst mode */ + STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02); + STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + switch (burst) { + case SEC_MINI_A: + /* unmodulated */ + stb0899_write_reg(state, STB0899_DISFIFO, 0x00); + break; + case SEC_MINI_B: + /* modulated */ + stb0899_write_reg(state, STB0899_DISFIFO, 0xff); + break; + } + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + /* wait for diseqc idle */ + if (stb0899_wait_diseqc_txidle(state, 100) < 0) + return -ETIMEDOUT; + + /* restore state */ + stb0899_write_reg(state, STB0899_DISCNTRL1, old_state); + + return 0; +} + +#if 0 +static int stb0899_diseqc_init(struct stb0899_state *state) +{ + struct dvb_diseqc_master_cmd tx_data; + struct dvb_diseqc_slave_reply rx_data; + + u8 f22_tx, f22_rx, reg; + + u32 mclk, tx_freq = 22000, count = 0, i; + + u32 trial = 0; /* try max = 2 (try 20khz and 17.5 khz) */ + u32 ret_1 = 0; /* 20 Khz status */ + u32 ret_2 = 0; /* 17.5 Khz status */ + + tx_data.msg[0] = 0xe2; + tx_data.msg_len = 3; + /* disable Tx spy */ + reg = stb0899_read_reg(state, STB0899_DISCNTRL2); + STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); + stb0899_write_reg(state, STB0899_DISCNTRL2, reg); + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 1); + stb0899_write_reg(state, STB0899_DISCNTRL2, reg); + + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); + stb0899_write_reg(state, STB0899_DISCNTRL2, reg); + + mclk = stb0899_get_mclk(state); + f22_tx = mclk / (tx_freq * 32); + stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ + state->rx_freq = 20000; + f22_rx = mclk / (state->rx_freq * 32); + + while ((count < 5) && (trial < 2)) { + stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* 2 possible values 17.5k/20k */ + + for (i = 0; i < 5; i++) { + msleep(50); + stb0899_send_diseqc_msg(&state->frontend, &tx_data); + msleep(100); + stb0899_recv_slave_reply(&state->frontend, &rx_data); + if (rx_data.msg_len >= 1) { + if ((rx_data.msg[0] == 0xe4) || (rx_data.msg[0] == 0xe5)) + count++; + } + } + if (trial == 0) + ret_1 = count; + else + ret_2 = count; + + trial++; + state->rx_freq = 17500; + f22_rx = mclk / (state->rx_freq * 32); + } + if (ret_1 > ret_2) { + state->rx_freq = 20000; + f22_rx = mclk / (state->rx_freq * 32); + } else { + state->rx_freq = 17500; + f22_rx = mclk / (state->rx_freq * 32); + } + + stb0899_write_reg(state, STB0899_DISF22, f22_tx); + if ((ret_1 == 0) && (ret_2 == 0)) + state->rx_freq = 0; /* no DiSEqC 2.0 slave */ + + return 0; +} +#endif + +static int stb0899_sleep(struct dvb_frontend *fe) +{ + struct stb0899_state *state = fe->demodulator_priv; + u8 reg; + + dprintk(verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); + + reg = stb0899_read_reg(state, STB0899_SYNTCTRL); + STB0899_SETFIELD_VAL(STANDBY, reg, 1); + stb0899_write_reg(state, STB0899_SYNTCTRL, reg); + + return 0; +} + +static int stb0899_wakeup(struct dvb_frontend *fe) +{ + int rc; + struct stb0899_state *state = fe->demodulator_priv; + + if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI))) + return rc; + /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */ + if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00))) + return rc; + if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) + return rc; + + return 0; +} + +static int stb0899_init(struct dvb_frontend *fe) +{ + int i; + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_config *config = state->config; + + dprintk(verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); +// mutex_init(&state->search_lock); + + /* init device */ + dprintk(verbose, FE_DEBUG, 1, "init device"); + for (i = 0; config->init_dev[i].address != 0xffff; i++) + stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data); + + dprintk(verbose, FE_DEBUG, 1, "init S2 demod"); + /* init S2 demod */ + for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++) + stb0899_write_s2reg(state, STB0899_S2DEMOD, + config->init_s2_demod[i].base_address, + config->init_s2_demod[i].offset, + config->init_s2_demod[i].data); + + dprintk(verbose, FE_DEBUG, 1, "init S1 demod"); + /* init S1 demod */ + for (i = 0; config->init_s1_demod[i].address != 0xffff; i++) + stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data); + + dprintk(verbose, FE_DEBUG, 1, "init S2 FEC"); + /* init S2 fec */ + for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++) + stb0899_write_s2reg(state, STB0899_S2FEC, + config->init_s2_fec[i].base_address, + config->init_s2_fec[i].offset, + config->init_s2_fec[i].data); + + dprintk(verbose, FE_DEBUG, 1, "init TST"); + /* init test */ + for (i = 0; config->init_tst[i].address != 0xffff; i++) + stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data); + + stb0899_init_calc(state); +// stb0899_diseqc_init(state); + + return 0; +} + +static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val) +{ + int res = 0; + int min = 0, med; + + if (val < tab[min].read) + res = tab[min].real; + else if (val >= tab[max].read) + res = tab[max].real; + else { + while ((max - min) > 1) { + med = (max + min) / 2; + if (val >= tab[min].read && val < tab[med].read) + max = med; + else + min = med; + } + res = ((val - tab[min].read) * + (tab[max].real - tab[min].real) / + (tab[max].read - tab[min].read)) + + tab[min].real; + } + + return res; +} + +static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + int val; + u32 reg; + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + case DVBFE_DELSYS_DSS: + if (internal->lock) { + reg = stb0899_read_reg(state, STB0899_VSTATUS); + if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { + + reg = stb0899_read_reg(state, STB0899_AGCIQIN); + val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg); + + *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val); + *strength += 750; + dprintk(verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", + val & 0xff, *strength); + } + } + break; + case DVBFE_DELSYS_DVBS2: + if (internal->lock) { + reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); + val = STB0899_GETFIELD(IF_AGC_GAIN, reg); + + *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); + *strength += 750; + dprintk(verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", + val & 0x3fff, *strength); + } + break; + default: + dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + break; + } + + return 0; +} + +static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + unsigned int val, quant, quantn = -1, est, estn = -1; + u8 buf[2]; + u32 reg; + + reg = stb0899_read_reg(state, STB0899_VSTATUS); + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + case DVBFE_DELSYS_DSS: + if (internal->lock) { + if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { + + stb0899_read_regs(state, STB0899_NIRM, buf, 2); + val = MAKEWORD16(buf[0], buf[1]); + + *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val); + dprintk(verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", + buf[0], buf[1], val, *snr); + } + } + break; + case DVBFE_DELSYS_DVBS2: + if (internal->lock) { + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); + quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg); + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); + est = STB0899_GETFIELD(ESN0_EST, reg); + if (est == 1) + val = 301; /* C/N = 30.1 dB */ + else if (est == 2) + val = 270; /* C/N = 27.0 dB */ + else { + /* quantn = 100 * log(quant^2) */ + quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100); + /* estn = 100 * log(est) */ + estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est); + /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */ + val = (quantn - estn) / 10; + } + *snr = val; + dprintk(verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", + quant, quantn, est, estn, val); + } + break; + default: + dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + break; + } + + return 0; +} + +static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + u8 reg; + *status = 0; + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + case DVBFE_DELSYS_DSS: + dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS"); + if (internal->lock) { + reg = stb0899_read_reg(state, STB0899_VSTATUS); + if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { + dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK"); + *status |= FE_HAS_CARRIER | FE_HAS_LOCK; + + reg = stb0899_read_reg(state, STB0899_PLPARM); + if (STB0899_GETFIELD(VITCURPUN, reg)) { + dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC"); + *status |= FE_HAS_VITERBI | FE_HAS_SYNC; + } + } + } + break; + case DVBFE_DELSYS_DVBS2: + dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2"); + if (internal->lock) { + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); + if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) { + *status |= FE_HAS_CARRIER; + dprintk(state->verbose, FE_DEBUG, 1, + "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER"); + + reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1); + if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) { + *status |= FE_HAS_LOCK; + dprintk(state->verbose, FE_DEBUG, 1, + "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK"); + + } + if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) { + *status |= FE_HAS_VITERBI; + dprintk(state->verbose, FE_DEBUG, 1, + "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI"); + } + if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) { + *status |= FE_HAS_SYNC; + dprintk(state->verbose, FE_DEBUG, 1, + "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC"); + } + } + } + break; + default: + dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + break; + } + return 0; +} + +/* + * stb0899_get_error + * viterbi error for DVB-S/DSS + * packet error for DVB-S2 + * Bit Error Rate or Packet Error Rate * 10 ^ 7 + */ +static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + u8 lsb, msb; + u32 i; + + *ber = 0; + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + case DVBFE_DELSYS_DSS: + if (internal->lock) { + /* average 5 BER values */ + for (i = 0; i < 5; i++) { + msleep(100); + lsb = stb0899_read_reg(state, STB0899_ECNT1L); + msb = stb0899_read_reg(state, STB0899_ECNT1M); + *ber += MAKEWORD16(msb, lsb); + } + *ber /= 5; + /* Viterbi Check */ + if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) { + /* Error Rate */ + *ber *= 9766; + /* ber = ber * 10 ^ 7 */ + *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); + *ber /= 8; + } + } + break; + case DVBFE_DELSYS_DVBS2: + if (internal->lock) { + /* Average 5 PER values */ + for (i = 0; i < 5; i++) { + msleep(100); + lsb = stb0899_read_reg(state, STB0899_ECNT1L); + msb = stb0899_read_reg(state, STB0899_ECNT1M); + *ber += MAKEWORD16(msb, lsb); + } + /* ber = ber * 10 ^ 7 */ + *ber *= 10000000; + *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); + } + break; + default: + dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + } + + return 0; +} + +static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + struct stb0899_state *state = fe->demodulator_priv; + + switch (voltage) { + case SEC_VOLTAGE_13: + stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); + stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); + stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00); + break; + case SEC_VOLTAGE_18: + stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02); + stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); + stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); + break; + case SEC_VOLTAGE_OFF: + stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); + stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82); + stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + u8 div; + + /* wait for diseqc idle */ + if (stb0899_wait_diseqc_txidle(state, 100) < 0) + return -ETIMEDOUT; + + switch (tone) { + case SEC_TONE_ON: + div = (internal->master_clk / 100) / 5632; + div = (div + 5) / 10; + stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66); + stb0899_write_reg(state, STB0899_ACRPRESC, 0x31); + stb0899_write_reg(state, STB0899_ACRDIV1, div); + break; + case SEC_TONE_OFF: + stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20); + break; + default: + break; + } + return 0; +} + +static int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + int i2c_stat; + struct stb0899_state *state = fe->demodulator_priv; + + i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT); + if (i2c_stat < 0) + goto err; + + if (enable) { + dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ..."); + i2c_stat |= STB0899_I2CTON; + if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) + goto err; + } + return 0; +err: + dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater enable failed"); + return -EREMOTEIO; +} + + +static inline void CONVERT32(u32 x, char *str) +{ + *str++ = (x >> 24) & 0xff; + *str++ = (x >> 16) & 0xff; + *str++ = (x >> 8) & 0xff; + *str++ = (x >> 0) & 0xff; + *str = '\0'; +} + +int stb0899_get_dev_id(struct stb0899_state *state) +{ + u8 chip_id, release; + u16 id; + u32 demod_ver = 0, fec_ver = 0; + char demod_str[4] = { 0 }; + char fec_str[4] = { 0 }; + + id = stb0899_read_reg(state, STB0899_DEV_ID); + dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id); + chip_id = STB0899_GETFIELD(CHIP_ID, id); + release = STB0899_GETFIELD(CHIP_REL, id); + + dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]", + chip_id, release); + + CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str); + + demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID); + dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver); + CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str); + fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG); + if (! (chip_id > 0)) { + dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899"); + + return -ENODEV; + } + dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver); + + return 0; +} + +static const struct dvbfe_info dvbs_info = { + .name = "STB0899 DVB-S", + .delivery = DVBFE_DELSYS_DVBS, + .delsys = { + .dvbs.modulation = DVBFE_MOD_QPSK, + .dvbs.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | + DVBFE_FEC_3_4 | DVBFE_FEC_5_6 | + DVBFE_FEC_6_7 + }, + + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 0 +}; + +static const struct dvbfe_info dss_info = { + .name = "STB0899 DSS", + .delivery = DVBFE_DELSYS_DSS, + .delsys = { + .dss.modulation = DVBFE_MOD_BPSK | DVBFE_MOD_QPSK, + .dss.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | + DVBFE_FEC_3_4 | DVBFE_FEC_5_6 | + DVBFE_FEC_6_7 + }, + + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 0 +}; + +static const struct dvbfe_info dvbs2_info = { + .name = "STB0899 DVB-S2", + .delivery = DVBFE_DELSYS_DVBS2, + .delsys = { + .dvbs2.modulation = DVBFE_MOD_QPSK | DVBFE_MOD_8PSK | + DVBFE_MOD_16APSK | DVBFE_MOD_32APSK, + + .dvbs2.fec = DVBFE_FEC_1_4 | DVBFE_FEC_1_3 | + DVBFE_FEC_2_5 | DVBFE_FEC_1_2 | + DVBFE_FEC_3_5 | DVBFE_FEC_2_3 | + DVBFE_FEC_3_4 | DVBFE_FEC_4_5 | + DVBFE_FEC_5_6 | DVBFE_FEC_8_9 | + DVBFE_FEC_9_10, + }, + + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 0 +}; + +static int stb0899_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) +{ + struct stb0899_state *state = fe->demodulator_priv; + + dprintk(verbose, FE_DEBUG, 1, "Get Info"); + + state->delsys = fe_info->delivery; + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + dprintk(verbose, FE_ERROR, 1, "Querying DVB-S info"); + memcpy(fe_info, &dvbs_info, sizeof (struct dvbfe_info)); + break; + case DVBFE_DELSYS_DSS: + dprintk(verbose, FE_ERROR, 1, "Querying DSS info"); + memcpy(fe_info, &dss_info, sizeof (struct dvbfe_info)); + break; + case DVBFE_DELSYS_DVBS2: + dprintk(verbose, FE_ERROR, 1, "Querying DVB-S2 info"); + memcpy(fe_info, &dvbs2_info, sizeof (struct dvbfe_info)); + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + return -EINVAL; + } + dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); + + return 0; +} + +static int stb0899_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DSS | DVBFE_DELSYS_DVBS2; + + return 0; +} + +void stb0899_set_delsys(struct stb0899_state *state) +{ + u8 reg; + u8 stop_clk[2]; + + stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1); + stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2); + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + dprintk(verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); + /* FECM/Viterbi ON */ + reg = stb0899_read_reg(state, STB0899_FECM); + STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); + STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); + stb0899_write_reg(state, STB0899_FECM, reg); + + stb0899_write_reg(state, STB0899_RSULC, 0xb1); + stb0899_write_reg(state, STB0899_TSULC, 0x40); + stb0899_write_reg(state, STB0899_RSLLC, 0x42); + stb0899_write_reg(state, STB0899_TSLPL, 0x12); + + reg = stb0899_read_reg(state, STB0899_TSTRES); + STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); + stb0899_write_reg(state, STB0899_TSTRES, reg); + + STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); + + STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); + STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); + + STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 1); + + STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); + break; + case DVBFE_DELSYS_DVBS2: + /* FECM/Viterbi OFF */ + reg = stb0899_read_reg(state, STB0899_FECM); + STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); + STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0); + stb0899_write_reg(state, STB0899_FECM, reg); + + stb0899_write_reg(state, STB0899_RSULC, 0xb1); + stb0899_write_reg(state, STB0899_TSULC, 0x42); + stb0899_write_reg(state, STB0899_RSLLC, 0x40); + stb0899_write_reg(state, STB0899_TSLPL, 0x02); + + reg = stb0899_read_reg(state, STB0899_TSTRES); + STB0899_SETFIELD_VAL(FRESLDPC, reg, 0); + stb0899_write_reg(state, STB0899_TSTRES, reg); + + STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0); + STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0); + + STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0); + STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0); + + STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0); + STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); + + STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0); + break; + case DVBFE_DELSYS_DSS: + /* FECM/Viterbi ON */ + reg = stb0899_read_reg(state, STB0899_FECM); + STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1); + STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); + stb0899_write_reg(state, STB0899_FECM, reg); + + stb0899_write_reg(state, STB0899_RSULC, 0xa1); + stb0899_write_reg(state, STB0899_TSULC, 0x61); + stb0899_write_reg(state, STB0899_RSLLC, 0x42); + + reg = stb0899_read_reg(state, STB0899_TSTRES); + STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); + stb0899_write_reg(state, STB0899_TSTRES, reg); + + STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); + + STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); + STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); + + STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); + + STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + break; + } + STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0); + stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2); +} + +/* + * stb0899_set_iterations + * set the LDPC iteration scale function + */ +static void stb0899_set_iterations(struct stb0899_state *state) +{ + struct stb0899_internal *internal = &state->internal; + struct stb0899_config *config = state->config; + + s32 iter_scale; + u32 reg; + + iter_scale = 17 * (internal->master_clk / 1000); + iter_scale += 410000; + iter_scale /= (internal->srate / 1000000); + iter_scale /= 1000; + + if (iter_scale > config->ldpc_max_iter) + iter_scale = config->ldpc_max_iter; + + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER); + STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale); + stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); +} + +static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_params *params) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_params *i_params = &state->params; + struct stb0899_internal *internal = &state->internal; + + u32 SearchRange, gain; + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + dprintk(verbose, FE_ERROR, 1, "set DVB-S params"); + i_params->freq = params->frequency; + i_params->srate = params->delsys.dvbs.symbol_rate; + break; + case DVBFE_DELSYS_DSS: + dprintk(verbose, FE_ERROR, 1, "set DSS params"); + i_params->freq = params->frequency; + i_params->srate = params->delsys.dss.symbol_rate; + break; + case DVBFE_DELSYS_DVBS2: + dprintk(verbose, FE_ERROR, 1, "set DVB-S2 params"); + i_params->freq = params->frequency; + i_params->srate = params->delsys.dvbs2.symbol_rate; + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + return -EINVAL; + } + dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); + +// SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ + SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ + dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); + /* checking Search Range is meaningless for a fixed 3 Mhz */ + if (INRANGE(i_params->srate, 1000000, 45000000)) { + dprintk(verbose, FE_DEBUG, 1, "Parameters IN RANGE"); + stb0899_set_delsys(state); + + if (state->config->tuner_set_rfsiggain) { + if (internal->srate > 15000000) + gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */ + else if (internal->srate > 5000000) + gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */ + else + gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */ + state->config->tuner_set_rfsiggain(fe, gain); + } + + if (i_params->srate <= 5000000) + stb0899_set_mclk(state, 76500000); + else + stb0899_set_mclk(state, 99000000); + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + case DVBFE_DELSYS_DSS: + dprintk(verbose, FE_DEBUG, 1, "DVB-S delivery system"); + internal->freq = i_params->freq; + internal->srate = i_params->srate; + /* + * search = user search range + + * 500Khz + + * 2 * Tuner_step_size + + * 10% of the symbol rate + */ + internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5); + internal->derot_percent = 30; + + /* What to do for tuners having no bandwidth setup ? */ + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + 10000000)) / 10); + if (state->config->tuner_get_bandwidth) + state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); + /* Set DVB-S1 AGC */ + stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11); + + /* Run the search algorithm */ + dprintk(verbose, FE_DEBUG, 1, "running DVB-S search algo .."); + if (stb0899_dvbs_algo(state) == RANGEOK) { + internal->lock = 1; + dprintk(verbose, FE_DEBUG, 1, + "-------------------------------------> DVB-S LOCK !"); + +// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */ +// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); +// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); +// dprintk(verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); +// dprintk(verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); + + return DVBFE_ALGO_SEARCH_SUCCESS; + } else { + internal->lock = 0; + + return DVBFE_ALGO_SEARCH_FAILED; + } + break; + case DVBFE_DELSYS_DVBS2: + internal->freq = i_params->freq; + internal->srate = i_params->srate; + internal->srch_range = SearchRange; + + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + 10000000)); + if (state->config->tuner_get_bandwidth) + state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); + +// pParams->SpectralInv = pSearch->IQ_Inversion; + + /* Set DVB-S2 AGC */ + stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c); + + /* Set IterScale =f(MCLK,SYMB) */ + stb0899_set_iterations(state); + + /* Run the search algorithm */ + dprintk(verbose, FE_DEBUG, 1, "running DVB-S2 search algo .."); + if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) { + internal->lock = 1; + dprintk(verbose, FE_DEBUG, 1, + "-------------------------------------> DVB-S2 LOCK !"); + +// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */ +// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); +// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); + + return DVBFE_ALGO_SEARCH_SUCCESS; + } else { + internal->lock = 0; + + return DVBFE_ALGO_SEARCH_FAILED; + } + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + return DVBFE_ALGO_SEARCH_INVALID; + } + } + + return DVBFE_ALGO_SEARCH_ERROR; +} + +static enum stb0899_status stb0899_track_carrier(struct stb0899_state *state) +{ + u8 reg; + + reg = stb0899_read_reg(state, STB0899_DSTATUS); + dprintk(verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg); + if (STB0899_GETFIELD(CARRIER_FOUND, reg)) { + dprintk(verbose, FE_DEBUG, 1, "-------------> CARRIEROK !"); + return CARRIEROK; + } else { + dprintk(verbose, FE_DEBUG, 1, "-------------> NOCARRIER !"); + return NOCARRIER; + } + + return NOCARRIER; +} + +static enum stb0899_status stb0899_get_ifagc(struct stb0899_state *state) +{ + u8 reg; + + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS); + dprintk(verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg); + if (STB0899_GETFIELD(IF_AGC_LOCK, reg)) { + dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !"); + return AGC1OK; + } else { + dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCK LOST !"); + return NOAGC1; + } + + return NOAGC1; +} + +static int stb0899_get_s1fec(struct stb0899_internal *internal, enum dvbfe_fec *fec) +{ + switch (internal->fecrate) { + case STB0899_FEC_1_2: + *fec = DVBFE_FEC_1_2; + break; + case STB0899_FEC_2_3: + *fec = DVBFE_FEC_2_3; + break; + case STB0899_FEC_3_4: + *fec = DVBFE_FEC_3_4; + break; + case STB0899_FEC_5_6: + *fec = DVBFE_FEC_5_6; + break; + case STB0899_FEC_6_7: + *fec = DVBFE_FEC_6_7; + break; + case STB0899_FEC_7_8: + *fec = DVBFE_FEC_7_8; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int stb0899_get_modcod(struct stb0899_internal *internal, struct dvbs2_params *params) +{ + switch (internal->modcod) { + case STB0899_DUMMY_PLF: + params->modulation = DVBFE_MOD_NONE; + params->fec = DVBFE_FEC_NONE; + break; + case STB0899_QPSK_14: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_1_4; + break; + case STB0899_QPSK_13: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_1_3; + break; + case STB0899_QPSK_25: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_2_5; + break; + case STB0899_QPSK_12: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_1_2; + break; + case STB0899_QPSK_35: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_3_5; + break; + case STB0899_QPSK_23: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_2_3; + break; + case STB0899_QPSK_34: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_3_4; + break; + case STB0899_QPSK_45: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_4_5; + break; + case STB0899_QPSK_56: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_5_6; + break; + case STB0899_QPSK_89: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_8_9; + break; + case STB0899_QPSK_910: + params->modulation = DVBFE_MOD_QPSK; + params->fec = DVBFE_FEC_9_10; + break; + case STB0899_8PSK_35: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_3_5; + break; + case STB0899_8PSK_23: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_2_3; + break; + case STB0899_8PSK_34: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_3_4; + break; + case STB0899_8PSK_56: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_5_6; + break; + case STB0899_8PSK_89: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_8_9; + break; + case STB0899_8PSK_910: + params->modulation = DVBFE_MOD_8PSK; + params->fec = DVBFE_FEC_9_10; + break; + case STB0899_16APSK_23: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_2_3; + break; + case STB0899_16APSK_34: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_3_4; + break; + case STB0899_16APSK_45: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_4_5; + break; + case STB0899_16APSK_56: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_5_6; + break; + case STB0899_16APSK_89: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_8_9; + break; + case STB0899_16APSK_910: + params->modulation = DVBFE_MOD_16APSK; + params->fec = DVBFE_FEC_9_10; + break; + case STB0899_32APSK_34: + params->modulation = DVBFE_MOD_32APSK; + params->fec = DVBFE_FEC_3_4; + break; + case STB0899_32APSK_45: + params->modulation = DVBFE_MOD_32APSK; + params->fec = DVBFE_FEC_4_5; + break; + case STB0899_32APSK_56: + params->modulation = DVBFE_MOD_32APSK; + params->fec = DVBFE_FEC_5_6; + break; + case STB0899_32APSK_89: + params->modulation = DVBFE_MOD_32APSK; + params->fec = DVBFE_FEC_8_9; + break; + case STB0899_32APSK_910: + params->modulation = DVBFE_MOD_32APSK; + params->fec = DVBFE_FEC_9_10; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * stb0899_track + * periodically check the signal level against a specified + * threshold level and perform derotator centering. + * called once we have a lock from a succesful search + * event. + * + * Will be called periodically called to maintain the + * lock. + * + * Will be used to get parameters as well as info from + * the decoded baseband header + * + * Once a new lock has established, the internal state + * frequency (internal->freq) is updated + */ +static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S state"); + if (stb0899_track_carrier(state) == CARRIEROK) { + params->frequency = internal->freq; + params->inversion = internal->inversion; + params->delivery = state->delsys; + params->delsys.dvbs.symbol_rate = internal->srate; + params->delsys.dvbs.modulation = DVBFE_MOD_QPSK; + stb0899_get_s1fec(internal, ¶ms->delsys.dvbs.fec); + } + break; + case DVBFE_DELSYS_DSS: + dprintk(verbose, FE_DEBUG, 1, "Tracking DSS state"); + if (stb0899_track_carrier(state) == CARRIEROK) { + params->frequency = internal->freq; + params->inversion = internal->inversion; + params->delivery = state->delsys; + params->delsys.dss.symbol_rate = internal->srate; + params->delsys.dss.modulation = DVBFE_MOD_QPSK; + stb0899_get_s1fec(internal, ¶ms->delsys.dss.fec); + } + break; + case DVBFE_DELSYS_DVBS2: + dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S2 state"); + if (stb0899_get_ifagc(state) == AGC1OK) { + params->frequency = internal->freq; + params->inversion = internal->inversion; + params->delivery = state->delsys; + params->delsys.dvbs2.symbol_rate = internal->srate; + stb0899_get_modcod(internal, ¶ms->delsys.dvbs2); + params->delsys.dvbs2.rolloff = internal->rolloff; + params->delsys.dvbs2.matype_1 = stb0899_read_reg(state, STB0899_MATSTRL); + params->delsys.dvbs2.matype_2 = stb0899_read_reg(state, STB0899_MATSTRM); + params->delsys.dvbs2.upl_1 = stb0899_read_reg(state, STB0899_UPLSTRL); + params->delsys.dvbs2.upl_2 = stb0899_read_reg(state, STB0899_UPLSTRM); + params->delsys.dvbs2.dfl_1 = stb0899_read_reg(state, STB0899_DFLSTRL); + params->delsys.dvbs2.dfl_2 = stb0899_read_reg(state, STB0899_DFLSTRM); + params->delsys.dvbs2.sync = stb0899_read_reg(state, STB0899_SYNCSTR); + params->delsys.dvbs2.syncd_1 = stb0899_read_reg(state, STB0899_SYNCDSTRL); + params->delsys.dvbs2.syncd_2 = stb0899_read_reg(state, STB0899_SYNCDSTRM); + } + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + return -EINVAL; + } + + return 0; +} + +static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *params) +{ + struct stb0899_state *state = fe->demodulator_priv; + struct stb0899_internal *internal = &state->internal; + + params->frequency = internal->freq; + params->inversion = internal->inversion; + params->delivery = state->delsys; + switch (state->delsys) { + case DVBFE_DELSYS_DVBS: + dprintk(verbose, FE_DEBUG, 1, "Get DVB-S params"); + params->delsys.dvbs.symbol_rate = internal->srate; + params->delsys.dvbs.modulation = DVBFE_MOD_QPSK; + break; + case DVBFE_DELSYS_DSS: + dprintk(verbose, FE_DEBUG, 1, "Get DSS params"); + params->delsys.dss.symbol_rate = internal->srate; + params->delsys.dss.modulation = DVBFE_MOD_QPSK; + + break; + case DVBFE_DELSYS_DVBS2: + dprintk(verbose, FE_DEBUG, 1, "Get DVB-S2 params"); + params->delsys.dvbs2.symbol_rate = internal->srate; + break; + default: + dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + return -EINVAL; + } + + return 0; +} + +static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_CUSTOM; +} + +static struct dvb_frontend_ops stb0899_ops = { + + .info = { + .name = "STB0899 Multistandard", + }, + + .release = stb0899_release, + .init = stb0899_init, + .sleep = stb0899_sleep, +// .wakeup = stb0899_wakeup, + + .i2c_gate_ctrl = stb0899_i2c_gate_ctrl, + .get_info = stb0899_get_info, + .get_delsys = stb0899_get_delsys, + + .get_frontend_algo = stb0899_frontend_algo, + .search = stb0899_search, + .track = stb0899_track, + .get_params = stb0899_get_params, + + .read_status = stb0899_read_status, + .read_snr = stb0899_read_snr, + .read_signal_strength = stb0899_read_signal_strength, + .read_status = stb0899_read_status, + .read_ber = stb0899_read_ber, + + .set_voltage = stb0899_set_voltage, + .set_tone = stb0899_set_tone, + + .diseqc_send_master_cmd = stb0899_send_diseqc_msg, + .diseqc_recv_slave_reply = stb0899_recv_slave_reply, + .diseqc_send_burst = stb0899_send_diseqc_burst, +}; + +struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) +{ + struct stb0899_state *state = NULL; + + state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL); + if (state == NULL) + goto error; + + state->verbose = verbose; + state->config = config; + state->i2c = i2c; + state->frontend.ops = stb0899_ops; + state->frontend.demodulator_priv = state; + + stb0899_wakeup(&state->frontend); + if (stb0899_get_dev_id(state) == -ENODEV) { + printk("%s: Exiting .. !\n", __func__); + goto error; + } + + printk("%s: Attaching STB0899 \n", __func__); + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(stb0899_attach); +MODULE_PARM_DESC(verbose, "Set Verbosity level"); +MODULE_AUTHOR("Manu Abraham"); +MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 43e837557b617862679d6ba6547ab531078c7620 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 2 Jul 2007 15:44:32 +0400 Subject: On the KNC1 cards the CLOCK is clamped to a maximum limit of 90MHz, eventhough not limited in hardware, this causes instabilities at a higher clock due to issues such as thermal, also the divider wraps around, which causes the demodulator core to actually run at a lower frequency. This needs to be empirically tested whether it affects other cards. If found necessary, this parameter needs to be moved out to the config struct such that it can be made hardware dependant. Reducing the CLOCK from 99MHz to 90MHz improved the acquisition time taken on the KNC1 cards and hence such a change. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 9c54e704e..b2bb1c94a 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1579,7 +1579,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa if (i_params->srate <= 5000000) stb0899_set_mclk(state, 76500000); else - stb0899_set_mclk(state, 99000000); + stb0899_set_mclk(state, 90000000); switch (state->delsys) { case DVBFE_DELSYS_DVBS: -- cgit v1.2.3 From e0bb0f04b51e3c228e90443b11880cdbdbfc08d4 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 2 Jul 2007 16:01:48 +0400 Subject: Use a delay for tracking acquisition status From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index b2bb1c94a..d49263772 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1873,11 +1873,14 @@ static int stb0899_get_modcod(struct stb0899_internal *internal, struct dvbs2_pa * Once a new lock has established, the internal state * frequency (internal->freq) is updated */ -static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params) +static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, int *delay) { + u32 lock_lost; + struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; +#if 0 switch (state->delsys) { case DVBFE_DELSYS_DVBS: dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S state"); @@ -1925,6 +1928,13 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params) dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } +#endif + lock_lost = STB0899_READ_S2REG(STB0899_S2DEMOD, LOCK_LOST); + dprintk(verbose, FE_DEBUG, 1, "Lock Lost=[0x%02x]\n", lock_lost); + if (STB0899_GETFIELD(LOCK_LOST, lock_lost)) + dprintk(verbose, FE_ERROR, 1, "Demodulator LOST LOCK !\n"); + + *delay = HZ/10; return 0; } -- cgit v1.2.3 From 3166bbf2b298996f42905cb7821ce91ef99ed1ff Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 2 Jul 2007 16:08:23 +0400 Subject: Let's neither sleep nor wakeup for now From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index d49263772..85fca73ae 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -875,11 +875,11 @@ static int stb0899_sleep(struct dvb_frontend *fe) u8 reg; dprintk(verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); - +#if 0 reg = stb0899_read_reg(state, STB0899_SYNTCTRL); STB0899_SETFIELD_VAL(STANDBY, reg, 1); stb0899_write_reg(state, STB0899_SYNTCTRL, reg); - +#endif return 0; } @@ -888,6 +888,7 @@ static int stb0899_wakeup(struct dvb_frontend *fe) int rc; struct stb0899_state *state = fe->demodulator_priv; +#if 0 if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI))) return rc; /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */ @@ -895,6 +896,7 @@ static int stb0899_wakeup(struct dvb_frontend *fe) return rc; if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) return rc; +#endif return 0; } -- cgit v1.2.3 From b6a7503cf67885eaaeab7a54e7b13b0be52d1de6 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 2 Jul 2007 16:40:47 +0400 Subject: FIX: reading from wrong registers From: Marko Schluessler Signed-off-by: Marko Schluessler Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 85fca73ae..ed8da8faa 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -817,11 +817,11 @@ static int stb0899_diseqc_init(struct stb0899_state *state) reg = stb0899_read_reg(state, STB0899_DISCNTRL2); STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + reg = stb0899_read_reg(state, STB0899_DISCNTRL2); STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 1); stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + reg = stb0899_read_reg(state, STB0899_DISCNTRL2); STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); stb0899_write_reg(state, STB0899_DISCNTRL2, reg); -- cgit v1.2.3 From e44d91b99cd1928b20b0eeff0ddfa0b1c1de51d7 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 2 Jul 2007 16:48:50 +0400 Subject: FIX: Add in missing inversion (should be ideally in the config struct) Thanks to Marco Schluessler for pointing it out From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index ed8da8faa..f43b2cf8e 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -2025,6 +2025,7 @@ struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_ad state->i2c = i2c; state->frontend.ops = stb0899_ops; state->frontend.demodulator_priv = state; + state->internal.inversion = IQ_SWAP_AUTO; stb0899_wakeup(&state->frontend); if (stb0899_get_dev_id(state) == -ENODEV) { -- cgit v1.2.3 From 6f0be0f7c1866de4fd9108e5a75f936fbb37add1 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sun, 23 Sep 2007 04:39:17 +0400 Subject: Really silly! Disabled all clocks and expected it to run. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index f43b2cf8e..d83dac9b4 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -251,14 +251,13 @@ int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg) dprintk(verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", reg, buf); - return (unsigned int)buf; } int stb0899_read_reg(struct stb0899_state *state, unsigned int reg) { int result; - + result = _stb0899_read_reg(state, reg); /* * Bug ID 9: @@ -888,7 +887,6 @@ static int stb0899_wakeup(struct dvb_frontend *fe) int rc; struct stb0899_state *state = fe->demodulator_priv; -#if 0 if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI))) return rc; /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */ @@ -896,7 +894,6 @@ static int stb0899_wakeup(struct dvb_frontend *fe) return rc; if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) return rc; -#endif return 0; } @@ -1618,7 +1615,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa // internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); // dprintk(verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); // dprintk(verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); - + return DVBFE_ALGO_SEARCH_SUCCESS; } else { internal->lock = 0; @@ -1959,7 +1956,6 @@ static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *para dprintk(verbose, FE_DEBUG, 1, "Get DSS params"); params->delsys.dss.symbol_rate = internal->srate; params->delsys.dss.modulation = DVBFE_MOD_QPSK; - break; case DVBFE_DELSYS_DVBS2: dprintk(verbose, FE_DEBUG, 1, "Get DVB-S2 params"); @@ -1971,7 +1967,7 @@ static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *para } return 0; -} +} static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) { -- cgit v1.2.3 From b6ce06755fc429ee83fd77affa9d57797ee209af Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 25 Sep 2007 02:51:32 +0400 Subject: TT S2 3200 shouldn't need Inversion ON and Inversion AUTO at the same time This is a racy situation. Inversion is default OFF on the TT S2 3200 hardware, unlike the KNC1 where it is default Inverted From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index d83dac9b4..3078c04d9 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -2011,17 +2011,19 @@ static struct dvb_frontend_ops stb0899_ops = { struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) { struct stb0899_state *state = NULL; + enum stb0899_inversion inversion; state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL); if (state == NULL) goto error; + inversion = config->inversion; state->verbose = verbose; state->config = config; state->i2c = i2c; state->frontend.ops = stb0899_ops; state->frontend.demodulator_priv = state; - state->internal.inversion = IQ_SWAP_AUTO; + state->internal.inversion = inversion; stb0899_wakeup(&state->frontend); if (stb0899_get_dev_id(state) == -ENODEV) { -- cgit v1.2.3 From f1ccdcf99d9319cfca38cf3a55e6be98b99d62e9 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 27 Sep 2007 01:32:13 +0400 Subject: Optimizations Reduce capture range from 10MHz to 3Mhz * Reduces szapping time a lot * increased stability at Low Symbol rates * overall increases reliability in tuning From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 3078c04d9..078678792 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1557,8 +1557,8 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa } dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); -// SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ - SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ + SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ +// SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); /* checking Search Range is meaningless for a fixed 3 Mhz */ if (INRANGE(i_params->srate, 1000000, 45000000)) { @@ -1597,7 +1597,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa /* What to do for tuners having no bandwidth setup ? */ if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + 10000000)) / 10); + state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); /* Set DVB-S1 AGC */ @@ -1629,7 +1629,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa internal->srch_range = SearchRange; if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + 10000000)); + state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); -- cgit v1.2.3 From 70c6ae4abd34047d767949a985afd7f922796736 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 5 Oct 2007 00:39:19 +0400 Subject: Bug! Timing recovery was calculated for 99MHz not 90 MHz From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 078678792..c39131741 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1578,7 +1578,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa if (i_params->srate <= 5000000) stb0899_set_mclk(state, 76500000); else - stb0899_set_mclk(state, 90000000); + stb0899_set_mclk(state, 99000000); switch (state->delsys) { case DVBFE_DELSYS_DVBS: -- cgit v1.2.3 From 2eb656e25d91845553a215568bd53a36d4ad6064 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 5 Oct 2007 16:04:32 +0400 Subject: Bug: Set Auxilliary Clock Register correctly From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index c39131741..7f575b5fc 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1221,7 +1221,7 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; - u8 div; + u8 div, reg; /* wait for diseqc idle */ if (stb0899_wait_diseqc_txidle(state, 100) < 0) @@ -1232,7 +1232,9 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) div = (internal->master_clk / 100) / 5632; div = (div + 5) / 10; stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66); - stb0899_write_reg(state, STB0899_ACRPRESC, 0x31); + reg = stb0899_read_reg(state, STB0899_ACRPRESC); + STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03); + stb0899_write_reg(state, STB0899_ACRPRESC, reg); stb0899_write_reg(state, STB0899_ACRDIV1, div); break; case SEC_TONE_OFF: -- cgit v1.2.3 From 1b6803c5c59820db0f49b9461d991f91ce789e85 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 5 Oct 2007 18:41:19 +0400 Subject: Initialize DiSEqC From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 7f575b5fc..4fe20afeb 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -796,7 +796,6 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t return 0; } -#if 0 static int stb0899_diseqc_init(struct stb0899_state *state) { struct dvb_diseqc_master_cmd tx_data; @@ -812,17 +811,18 @@ static int stb0899_diseqc_init(struct stb0899_state *state) tx_data.msg[0] = 0xe2; tx_data.msg_len = 3; - /* disable Tx spy */ reg = stb0899_read_reg(state, STB0899_DISCNTRL2); STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - reg = stb0899_read_reg(state, STB0899_DISCNTRL2); - STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 1); - stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - reg = stb0899_read_reg(state, STB0899_DISCNTRL2); - STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL2, reg); + /* disable Tx spy */ + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); mclk = stb0899_get_mclk(state); f22_tx = mclk / (tx_freq * 32); @@ -830,6 +830,7 @@ static int stb0899_diseqc_init(struct stb0899_state *state) state->rx_freq = 20000; f22_rx = mclk / (state->rx_freq * 32); +#if 0 while ((count < 5) && (trial < 2)) { stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* 2 possible values 17.5k/20k */ @@ -864,9 +865,9 @@ static int stb0899_diseqc_init(struct stb0899_state *state) if ((ret_1 == 0) && (ret_2 == 0)) state->rx_freq = 0; /* no DiSEqC 2.0 slave */ +#endif return 0; } -#endif static int stb0899_sleep(struct dvb_frontend *fe) { @@ -939,7 +940,7 @@ static int stb0899_init(struct dvb_frontend *fe) stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data); stb0899_init_calc(state); -// stb0899_diseqc_init(state); + stb0899_diseqc_init(state); return 0; } -- cgit v1.2.3 From 5a9b049e20e0b7f4a640c3af1be3918b365da2a1 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 5 Oct 2007 19:09:43 +0400 Subject: Bug: DiSEqC receiver was trying to initialize the transmitter From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 4fe20afeb..aaab58688 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -832,7 +832,7 @@ static int stb0899_diseqc_init(struct stb0899_state *state) #if 0 while ((count < 5) && (trial < 2)) { - stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* 2 possible values 17.5k/20k */ + stb0899_write_reg(state, STB0899_DISF22RX, f22_rx); /* 2 possible values 17.5k/20k */ for (i = 0; i < 5; i++) { msleep(50); @@ -861,7 +861,7 @@ static int stb0899_diseqc_init(struct stb0899_state *state) f22_rx = mclk / (state->rx_freq * 32); } - stb0899_write_reg(state, STB0899_DISF22, f22_tx); + stb0899_write_reg(state, STB0899_DISF22RX, f22_rx); if ((ret_1 == 0) && (ret_2 == 0)) state->rx_freq = 0; /* no DiSEqC 2.0 slave */ -- cgit v1.2.3 From ddc7e3b68aad0f78bab0d331b45b0bb86ca40c5d Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 6 Oct 2007 16:41:16 +0400 Subject: Hmmph, a proper calculation broke the working behaviour. Need some thoughts, temporary for now .. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index aaab58688..a53320685 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1581,7 +1581,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa if (i_params->srate <= 5000000) stb0899_set_mclk(state, 76500000); else - stb0899_set_mclk(state, 99000000); + stb0899_set_mclk(state, 90000000); switch (state->delsys) { case DVBFE_DELSYS_DVBS: -- cgit v1.2.3 From 71d6d17ac156761a41221d80254021e9508aaca5 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 10 Oct 2007 13:12:13 +0400 Subject: return invalid for invalid parameters From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index a53320685..144477a2a 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1008,7 +1008,7 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) break; default: dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); - break; + return -EINVAL; } return 0; @@ -1064,7 +1064,7 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) break; default: dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); - break; + return -EINVAL; } return 0; @@ -1126,7 +1126,7 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) break; default: dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); - break; + return -EINVAL; } return 0; } @@ -1185,6 +1185,7 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) break; default: dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + return -EINVAL; } return 0; @@ -1242,7 +1243,7 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20); break; default: - break; + return -EINVAL; } return 0; } -- cgit v1.2.3 From df1967b47cfc020db8de09734d4d890d8b2b87d2 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 15 Oct 2007 21:39:58 +0400 Subject: Though insignificant, removes an unnecessary read of the LOCK_LOSS register, which should have happenend in the DVB-S2 mode only, but reading it as it is for the other delivery systems causes nothing to say but LOCK_LOST, which just causes confusion amongst users. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 144477a2a..9346fb443 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1926,16 +1926,16 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i params->delsys.dvbs2.syncd_1 = stb0899_read_reg(state, STB0899_SYNCDSTRL); params->delsys.dvbs2.syncd_2 = stb0899_read_reg(state, STB0899_SYNCDSTRM); } + lock_lost = STB0899_READ_S2REG(STB0899_S2DEMOD, LOCK_LOST); + dprintk(verbose, FE_DEBUG, 1, "Lock Lost=[0x%02x]\n", lock_lost); + if (STB0899_GETFIELD(LOCK_LOST, lock_lost)) + dprintk(verbose, FE_ERROR, 1, "Demodulator LOST LOCK !\n"); break; default: dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } #endif - lock_lost = STB0899_READ_S2REG(STB0899_S2DEMOD, LOCK_LOST); - dprintk(verbose, FE_DEBUG, 1, "Lock Lost=[0x%02x]\n", lock_lost); - if (STB0899_GETFIELD(LOCK_LOST, lock_lost)) - dprintk(verbose, FE_ERROR, 1, "Demodulator LOST LOCK !\n"); *delay = HZ/10; -- cgit v1.2.3 From 3308d27f9c620a22a959ece885d136f7d84421c9 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 24 Oct 2007 02:56:18 +0400 Subject: Fix: assignment of wrong values From: Marko Schluessler Signed-off-by: Marko Schluessler Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 9346fb443..5d19b9ca0 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -611,7 +611,7 @@ static void stb0899_init_calc(struct stb0899_state *state) { struct stb0899_internal *internal = &state->internal; int master_clk; - u8 agc[1]; + u8 agc[2]; u8 agc1cn; u32 reg; -- cgit v1.2.3 From 9faac02992fa789a4b815fbb53df9b6fafb41284 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 31 Oct 2007 02:46:49 +0400 Subject: Add post process interfaces From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 5d19b9ca0..2d3fd7870 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -580,11 +580,35 @@ static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) dprintk(verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); } +static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) +{ + struct stb0899_config *config = state->config; + struct stb0899_postproc *postproc = config->postproc; + + /* post process event */ + if (postproc) { + if (enable) { + if (postproc[STB0899_POSTPROC_GPIO_POWER].level == STB0899_GPIOPULLUP) + stb0899_write_reg(state, postproc[ctl].gpio, 0x02); + else + stb0899_write_reg(state, postproc[ctl].gpio, 0x82); + } else { + if (postproc[STB0899_POSTPROC_GPIO_POWER].level == STB0899_GPIOPULLUP) + stb0899_write_reg(state, postproc[ctl].gpio, 0x82); + else + stb0899_write_reg(state, postproc[ctl].gpio, 0x02); + } + } + return 0; +} + static void stb0899_release(struct dvb_frontend *fe) { struct stb0899_state *state = fe->demodulator_priv; dprintk(verbose, FE_DEBUG, 1, "Release Frontend"); + /* post process event */ + stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); kfree(state); } @@ -880,6 +904,9 @@ static int stb0899_sleep(struct dvb_frontend *fe) STB0899_SETFIELD_VAL(STANDBY, reg, 1); stb0899_write_reg(state, STB0899_SYNTCTRL, reg); #endif + /* post process event */ + stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); + return 0; } @@ -896,6 +923,9 @@ static int stb0899_wakeup(struct dvb_frontend *fe) if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) return rc; + /* post process event */ + stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1); + return 0; } @@ -1091,6 +1121,8 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) if (STB0899_GETFIELD(VITCURPUN, reg)) { dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC"); *status |= FE_HAS_VITERBI | FE_HAS_SYNC; + /* post process event */ + stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); } } } @@ -1120,6 +1152,8 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) *status |= FE_HAS_SYNC; dprintk(state->verbose, FE_DEBUG, 1, "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC"); + /* post process event */ + stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); } } } -- cgit v1.2.3 From 3855025dc4f81e754a1b7f1dd740cb591e033e68 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 31 Oct 2007 03:05:59 +0400 Subject: Fix a typo in the previous commit From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 2d3fd7870..241ce282b 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -588,12 +588,12 @@ static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) /* post process event */ if (postproc) { if (enable) { - if (postproc[STB0899_POSTPROC_GPIO_POWER].level == STB0899_GPIOPULLUP) + if (postproc[ctl].level == STB0899_GPIOPULLUP) stb0899_write_reg(state, postproc[ctl].gpio, 0x02); else stb0899_write_reg(state, postproc[ctl].gpio, 0x82); } else { - if (postproc[STB0899_POSTPROC_GPIO_POWER].level == STB0899_GPIOPULLUP) + if (postproc[ctl].level == STB0899_GPIOPULLUP) stb0899_write_reg(state, postproc[ctl].gpio, 0x82); else stb0899_write_reg(state, postproc[ctl].gpio, 0x02); -- cgit v1.2.3 From 1c1a526514057c036f3048f77d26f649326a331b Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 10 Nov 2007 23:59:16 +0400 Subject: Code simplification: clock is already initialized, no need to initialize again. Thanks to Marko Schluessler for pointing it out From: Manu Abraham Signed-off-by: Marko Schluessler Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 241ce282b..0b09f4859 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -550,7 +550,7 @@ int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) */ static u32 stb0899_get_mclk(struct stb0899_state *state) { - u32 mclk = 90000000, div = 0; + u32 mclk = 0, div = 0; div = stb0899_read_reg(state, STB0899_NCOARSE); mclk = (div + 1) * state->config->xtal_freq / 6; -- cgit v1.2.3 From 9c44a82e63fa63c7930da98e87ece51dc8f2c01d Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 19 Nov 2007 23:44:47 +0400 Subject: Revert back previous change to 90MHz Note: * At High Symbol Rates we do not have enouph machine cycles to handle the incoming symbols and hence might run into problems at the very end of the specified definition * Most of the equations have been calculated for a master clock of 99 MHz, running at 90MHz, raises lot of issues such as the need to recalculate all of them , which is eventually very painful. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 0b09f4859..450ab094e 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1616,7 +1616,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa if (i_params->srate <= 5000000) stb0899_set_mclk(state, 76500000); else - stb0899_set_mclk(state, 90000000); + stb0899_set_mclk(state, 99000000); switch (state->delsys) { case DVBFE_DELSYS_DVBS: -- cgit v1.2.3 From e26b6fdba08d411586b8a313be072175217f697f Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 18 Jan 2008 18:28:48 +0400 Subject: Bug: Bandwidth calculation Bug #1: The 5 tap equaliser is set to correct simple perturbations like reflections on the IF cable for DVB-S. In the case of DVB-S2 a more powerful equalizer is used to correct the filter group delay allowing the bandwidth to be reduced by a factor of 1/3 Bug #2: The ZIF tuner takes badwidth to be set in Hz From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 450ab094e..2790989b6 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1595,8 +1595,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa } dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); - SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ -// SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10 Mhz) */ + SearchRange = 10000000; dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); /* checking Search Range is meaningless for a fixed 3 Mhz */ if (INRANGE(i_params->srate, 1000000, 45000000)) { @@ -1667,7 +1666,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa internal->srch_range = SearchRange; if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100); + state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange)); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); -- cgit v1.2.3 From e60074d344e06a54b1808d50ead56c3af27c26ac Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 18 Jan 2008 21:15:17 +0400 Subject: Initialize post process events to NULL From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 2790989b6..9067240ce 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -583,7 +583,7 @@ static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) { struct stb0899_config *config = state->config; - struct stb0899_postproc *postproc = config->postproc; + const struct stb0899_postproc *postproc = config->postproc; /* post process event */ if (postproc) { -- cgit v1.2.3 From d22b293bacbccd52aac5b48b97a4483b039f7573 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 19 Jan 2008 03:09:52 +0400 Subject: Bug Fix an overflow in bandwidth calculation From: Reinhard Nissl Signed-off-by: Reinhard Nissl Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 9067240ce..b2aad669a 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1634,7 +1634,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa /* What to do for tuners having no bandwidth setup ? */ if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100); + state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); /* Set DVB-S1 AGC */ -- cgit v1.2.3 From a32a37328e5b8ce008dc2d3bdcae2690246b910a Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 21 Jan 2008 23:17:48 +0400 Subject: Bug: a string which contains 4 digits needs an array of size 5. The fifth character will hold the terminating '\0' From: Reinhard Nissl Signed-off-by: Reinhard Nissl Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index b2aad669a..8b74c8e80 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1318,8 +1318,8 @@ int stb0899_get_dev_id(struct stb0899_state *state) u8 chip_id, release; u16 id; u32 demod_ver = 0, fec_ver = 0; - char demod_str[4] = { 0 }; - char fec_str[4] = { 0 }; + char demod_str[5] = { 0 }; + char fec_str[5] = { 0 }; id = stb0899_read_reg(state, STB0899_DEV_ID); dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id); -- cgit v1.2.3 From eab83567f6ad5747a7852e2880959e02775e54d4 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 26 Jan 2008 01:25:13 +0400 Subject: Bug! F/3 Clock domain was incorrectly used From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 8b74c8e80..48eab791c 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1474,7 +1474,7 @@ void stb0899_set_delsys(struct stb0899_state *state) STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 1); + STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); break; -- cgit v1.2.3 From aa766963fb7d65df8a40f4d2b1ff979909eb6ac4 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 26 Jan 2008 03:28:46 +0400 Subject: Cleanup/Optimization: * Fix compile warnings * The compile warnings helped to identify 2 unnecessary I/O operations From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 48eab791c..c9a4a338c 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -495,7 +495,7 @@ err: return status < 0 ? status : -EREMOTEIO; } -int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, size_t count) +int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count) { int ret; u8 buf[2 + count]; -- cgit v1.2.3 From 93ae58d1ce49d3b6e6dc2e8282492d20dbc219a2 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 26 Jan 2008 03:39:16 +0400 Subject: Fix a compile warning From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index c9a4a338c..4beda52fb 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -444,7 +444,7 @@ err: return status < 0 ? status : -EREMOTEIO; } -int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, size_t count) +int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count) { int status; -- cgit v1.2.3 From a52af51ed4b377cab3886bb48864a036a2b0081c Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 4 Feb 2008 02:37:02 +0400 Subject: Optimization, Fix a Bug * cut down some I/O operations by disabling "disable gate" * budget_av was left with the gate open, thereby more susceptible to RF interference due to I/O operations From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 4beda52fb..a3f019b3c 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1282,7 +1282,7 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) return 0; } -static int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { int i2c_stat; struct stb0899_state *state = fe->demodulator_priv; @@ -1296,10 +1296,15 @@ static int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) i2c_stat |= STB0899_I2CTON; if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) goto err; + } else { + dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ..."); + i2c_stat &= ~STB0899_I2CTON; + if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) + goto err; } return 0; err: - dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater enable failed"); + dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed"); return -EREMOTEIO; } @@ -1633,10 +1638,17 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa internal->derot_percent = 30; /* What to do for tuners having no bandwidth setup ? */ + /* enable tuner I/O */ + stb0899_i2c_gate_ctrl(&state->frontend, 1); + if (state->config->tuner_set_bandwidth) state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); + + /* disable tuner I/O */ + stb0899_i2c_gate_ctrl(&state->frontend, 0); + /* Set DVB-S1 AGC */ stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11); @@ -1665,11 +1677,17 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa internal->srate = i_params->srate; internal->srch_range = SearchRange; + /* enable tuner I/O */ + stb0899_i2c_gate_ctrl(&state->frontend, 1); + if (state->config->tuner_set_bandwidth) state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange)); if (state->config->tuner_get_bandwidth) state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); + /* disable tuner I/O */ + stb0899_i2c_gate_ctrl(&state->frontend, 0); + // pParams->SpectralInv = pSearch->IQ_Inversion; /* Set DVB-S2 AGC */ -- cgit v1.2.3 From 4d93e2e1b7218d6e255a267ede1c13a4c5bf2587 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sun, 24 Feb 2008 02:10:56 +0400 Subject: We can now reduce the debug levels, just need to look at errors only. (Hope so) From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index a3f019b3c..5d78b228c 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -31,7 +31,7 @@ #include "stb0899_priv.h" #include "stb0899_reg.h" -static unsigned int verbose = 5; +static unsigned int verbose = 1; module_param(verbose, int, 0644); /* C/N in dB/10, NIRM/NIRL */ -- cgit v1.2.3 From 239c3c85d294f545c110681a2e8989d92a304e78 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 1 Mar 2008 20:54:28 +0400 Subject: Code Simplification From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 5d78b228c..8dc9f4b76 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1578,20 +1578,18 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa u32 SearchRange, gain; + i_params->freq = params->frequency; switch (state->delsys) { case DVBFE_DELSYS_DVBS: dprintk(verbose, FE_ERROR, 1, "set DVB-S params"); - i_params->freq = params->frequency; i_params->srate = params->delsys.dvbs.symbol_rate; break; case DVBFE_DELSYS_DSS: dprintk(verbose, FE_ERROR, 1, "set DSS params"); - i_params->freq = params->frequency; i_params->srate = params->delsys.dss.symbol_rate; break; case DVBFE_DELSYS_DVBS2: dprintk(verbose, FE_ERROR, 1, "set DVB-S2 params"); - i_params->freq = params->frequency; i_params->srate = params->delsys.dvbs2.symbol_rate; break; default: -- cgit v1.2.3 From 01fac3d72ef1952f2a05ea1064b9fb0f95123a81 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 5 Mar 2008 02:19:58 +0400 Subject: Optimizations galore: Blistering barnacles! The KNC1 and friends like 90 Mhz clock much better rather than running at a higher throttle, for almost similar hardware. he exact cause unknown, possibly due to a lower voltage applied for the demod power supply. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 8dc9f4b76..121f224a8 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1575,6 +1575,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa struct stb0899_state *state = fe->demodulator_priv; struct stb0899_params *i_params = &state->params; struct stb0899_internal *internal = &state->internal; + struct stb0899_config *config = state->config; u32 SearchRange, gain; @@ -1616,9 +1617,9 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa } if (i_params->srate <= 5000000) - stb0899_set_mclk(state, 76500000); + stb0899_set_mclk(state, config->lo_clk); else - stb0899_set_mclk(state, 99000000); + stb0899_set_mclk(state, config->hi_clk); switch (state->delsys) { case DVBFE_DELSYS_DVBS: -- cgit v1.2.3 From b3b114fdfb64434656d39cd6ad440349d84cffe2 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sun, 9 Mar 2008 03:28:09 +0400 Subject: Make delivery system standalone. Eventhough the delivery system is made standalone, DVBFE_SET_DELSYS needs to be set as the very first operation, for a multistandard frontend Splitting delivery system out as a new ioctl, makes things a bit more easier to understand. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 121f224a8..5915780c8 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1415,7 +1415,6 @@ static int stb0899_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) dprintk(verbose, FE_DEBUG, 1, "Get Info"); - state->delsys = fe_info->delivery; switch (state->delsys) { case DVBFE_DELSYS_DVBS: dprintk(verbose, FE_ERROR, 1, "Querying DVB-S info"); @@ -1445,7 +1444,7 @@ static int stb0899_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_del return 0; } -void stb0899_set_delsys(struct stb0899_state *state) +static void stb0899_set_delivery(struct stb0899_state *state) { u8 reg; u8 stop_clk[2]; @@ -1604,7 +1603,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa /* checking Search Range is meaningless for a fixed 3 Mhz */ if (INRANGE(i_params->srate, 1000000, 45000000)) { dprintk(verbose, FE_DEBUG, 1, "Parameters IN RANGE"); - stb0899_set_delsys(state); + stb0899_set_delivery(state); if (state->config->tuner_set_rfsiggain) { if (internal->srate > 15000000) @@ -2028,6 +2027,14 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_CUSTOM; } +static int stb0899_set_delsys(struct dvb_frontend *fe, enum dvbfe_delsys delsys) +{ + struct stb0899_state *state = fe->demodulator_priv; + + state->delsys = delsys; + return 0; +} + static struct dvb_frontend_ops stb0899_ops = { .info = { @@ -2042,6 +2049,7 @@ static struct dvb_frontend_ops stb0899_ops = { .i2c_gate_ctrl = stb0899_i2c_gate_ctrl, .get_info = stb0899_get_info, .get_delsys = stb0899_get_delsys, + .set_delsys = stb0899_set_delsys, .get_frontend_algo = stb0899_frontend_algo, .search = stb0899_search, -- cgit v1.2.3 From f10f14000721f086f4eb3e448b2330166110ac67 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 24 Oct 2008 01:47:55 +0400 Subject: Remove unreferenced delivery From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 5915780c8..3156f3c24 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -1352,7 +1352,6 @@ int stb0899_get_dev_id(struct stb0899_state *state) static const struct dvbfe_info dvbs_info = { .name = "STB0899 DVB-S", - .delivery = DVBFE_DELSYS_DVBS, .delsys = { .dvbs.modulation = DVBFE_MOD_QPSK, .dvbs.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | @@ -1370,7 +1369,6 @@ static const struct dvbfe_info dvbs_info = { static const struct dvbfe_info dss_info = { .name = "STB0899 DSS", - .delivery = DVBFE_DELSYS_DSS, .delsys = { .dss.modulation = DVBFE_MOD_BPSK | DVBFE_MOD_QPSK, .dss.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | @@ -1388,7 +1386,6 @@ static const struct dvbfe_info dss_info = { static const struct dvbfe_info dvbs2_info = { .name = "STB0899 DVB-S2", - .delivery = DVBFE_DELSYS_DVBS2, .delsys = { .dvbs2.modulation = DVBFE_MOD_QPSK | DVBFE_MOD_8PSK | DVBFE_MOD_16APSK | DVBFE_MOD_32APSK, -- cgit v1.2.3 From 0ea79925035f398467b41e1a7541649767fc2fc5 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 9 Jul 2008 22:33:38 +0400 Subject: Fix runtime verbosity From: Reinhard Nissl Signed-off-by: Reinhard Nissl Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 144 ++++++++++++------------ 1 file changed, 72 insertions(+), 72 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 3156f3c24..4d00cc848 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -31,7 +31,7 @@ #include "stb0899_priv.h" #include "stb0899_reg.h" -static unsigned int verbose = 1; +static unsigned int verbose = 0;//1; module_param(verbose, int, 0644); /* C/N in dB/10, NIRM/NIRL */ @@ -241,14 +241,14 @@ int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg) ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { if (ret != -ERESTARTSYS) - dprintk(verbose, FE_ERROR, 1, + dprintk(state->verbose, FE_ERROR, 1, "Read error, Reg=[0x%02x], Status=%d", reg, ret); return ret < 0 ? ret : -EREMOTEIO; } - if (unlikely(verbose >= FE_DEBUGREG)) - dprintk(verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", + if (unlikely(*state->verbose >= FE_DEBUGREG)) + dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", reg, buf); return (unsigned int)buf; @@ -361,7 +361,7 @@ u32 _stb0899_read_s2reg(struct stb0899_state *state, } data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]); - if (unlikely(state->verbose >= FE_DEBUGREG)) + if (unlikely(*state->verbose >= FE_DEBUGREG)) printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data); @@ -418,7 +418,7 @@ int stb0899_write_s2reg(struct stb0899_state *state, buf_1[4] = GETBYTE(stb0899_data, BYTE2); buf_1[5] = GETBYTE(stb0899_data, BYTE3); - if (unlikely(state->verbose >= FE_DEBUGREG)) + if (unlikely(*state->verbose >= FE_DEBUGREG)) printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data); @@ -480,7 +480,7 @@ int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u3 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) _stb0899_read_reg(state, (reg | 0x00ff)); - if (unlikely(state->verbose >= FE_DEBUGREG)) { + if (unlikely(*state->verbose >= FE_DEBUGREG)) { int i; printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); @@ -510,7 +510,7 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, buf[1] = reg & 0xff; memcpy(&buf[2], data, count); - if (unlikely(state->verbose >= FE_DEBUGREG)) { + if (unlikely(*state->verbose >= FE_DEBUGREG)) { int i; printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); @@ -530,7 +530,7 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, if (ret != 1) { if (ret != -ERESTARTSYS) - dprintk(verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", + dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", reg, data[0], count, ret); return ret < 0 ? ret : -EREMOTEIO; } @@ -554,7 +554,7 @@ static u32 stb0899_get_mclk(struct stb0899_state *state) div = stb0899_read_reg(state, STB0899_NCOARSE); mclk = (div + 1) * state->config->xtal_freq / 6; - dprintk(verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk); + dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk); return mclk; } @@ -570,14 +570,14 @@ static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) struct stb0899_internal *internal = &state->internal; u8 mdiv = 0; - dprintk(verbose, FE_DEBUG, 1, "state->config=%p", state->config); + dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config); mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1; - dprintk(verbose, FE_DEBUG, 1, "mdiv=%d", mdiv); + dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv); stb0899_write_reg(state, STB0899_NCOARSE, mdiv); internal->master_clk = stb0899_get_mclk(state); - dprintk(verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); + dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); } static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) @@ -606,7 +606,7 @@ static void stb0899_release(struct dvb_frontend *fe) { struct stb0899_state *state = fe->demodulator_priv; - dprintk(verbose, FE_DEBUG, 1, "Release Frontend"); + dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend"); /* post process event */ stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); kfree(state); @@ -683,7 +683,7 @@ static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeo if (!STB0899_GETFIELD(FIFOFULL, reg)) break; if ((jiffies - start) > timeout) { - dprintk(verbose, FE_ERROR, 1, "timed out !!"); + dprintk(state->verbose, FE_ERROR, 1, "timed out !!"); return -ETIMEDOUT; } } @@ -725,7 +725,7 @@ static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout) while (!STB0899_GETFIELD(RXEND, reg)) { reg = stb0899_read_reg(state, STB0899_DISRX_ST0); if (jiffies - start > timeout) { - dprintk(verbose, FE_ERROR, 1, "timed out!!"); + dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); return -ETIMEDOUT; } msleep(10); @@ -774,7 +774,7 @@ static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout) while (!STB0899_GETFIELD(TXIDLE, reg)) { reg = stb0899_read_reg(state, STB0899_DISSTATUS); if (jiffies - start > timeout) { - dprintk(verbose, FE_ERROR, 1, "timed out!!"); + dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); return -ETIMEDOUT; } msleep(10); @@ -898,7 +898,7 @@ static int stb0899_sleep(struct dvb_frontend *fe) struct stb0899_state *state = fe->demodulator_priv; u8 reg; - dprintk(verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); + dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); #if 0 reg = stb0899_read_reg(state, STB0899_SYNTCTRL); STB0899_SETFIELD_VAL(STANDBY, reg, 1); @@ -935,15 +935,15 @@ static int stb0899_init(struct dvb_frontend *fe) struct stb0899_state *state = fe->demodulator_priv; struct stb0899_config *config = state->config; - dprintk(verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); + dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); // mutex_init(&state->search_lock); /* init device */ - dprintk(verbose, FE_DEBUG, 1, "init device"); + dprintk(state->verbose, FE_DEBUG, 1, "init device"); for (i = 0; config->init_dev[i].address != 0xffff; i++) stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data); - dprintk(verbose, FE_DEBUG, 1, "init S2 demod"); + dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod"); /* init S2 demod */ for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++) stb0899_write_s2reg(state, STB0899_S2DEMOD, @@ -951,12 +951,12 @@ static int stb0899_init(struct dvb_frontend *fe) config->init_s2_demod[i].offset, config->init_s2_demod[i].data); - dprintk(verbose, FE_DEBUG, 1, "init S1 demod"); + dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod"); /* init S1 demod */ for (i = 0; config->init_s1_demod[i].address != 0xffff; i++) stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data); - dprintk(verbose, FE_DEBUG, 1, "init S2 FEC"); + dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC"); /* init S2 fec */ for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++) stb0899_write_s2reg(state, STB0899_S2FEC, @@ -964,7 +964,7 @@ static int stb0899_init(struct dvb_frontend *fe) config->init_s2_fec[i].offset, config->init_s2_fec[i].data); - dprintk(verbose, FE_DEBUG, 1, "init TST"); + dprintk(state->verbose, FE_DEBUG, 1, "init TST"); /* init test */ for (i = 0; config->init_tst[i].address != 0xffff; i++) stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data); @@ -1020,7 +1020,7 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val); *strength += 750; - dprintk(verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", + dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", val & 0xff, *strength); } } @@ -1032,12 +1032,12 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); *strength += 750; - dprintk(verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", + dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", val & 0x3fff, *strength); } break; default: - dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); return -EINVAL; } @@ -1064,7 +1064,7 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) val = MAKEWORD16(buf[0], buf[1]); *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val); - dprintk(verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", + dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", buf[0], buf[1], val, *snr); } } @@ -1088,12 +1088,12 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) val = (quantn - estn) / 10; } *snr = val; - dprintk(verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", + dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", quant, quantn, est, estn, val); } break; default: - dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); return -EINVAL; } @@ -1159,7 +1159,7 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) } break; default: - dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); return -EINVAL; } return 0; @@ -1218,7 +1218,7 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) } break; default: - dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); return -EINVAL; } @@ -1410,26 +1410,26 @@ static int stb0899_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) { struct stb0899_state *state = fe->demodulator_priv; - dprintk(verbose, FE_DEBUG, 1, "Get Info"); + dprintk(state->verbose, FE_DEBUG, 1, "Get Info"); switch (state->delsys) { case DVBFE_DELSYS_DVBS: - dprintk(verbose, FE_ERROR, 1, "Querying DVB-S info"); + dprintk(state->verbose, FE_ERROR, 1, "Querying DVB-S info"); memcpy(fe_info, &dvbs_info, sizeof (struct dvbfe_info)); break; case DVBFE_DELSYS_DSS: - dprintk(verbose, FE_ERROR, 1, "Querying DSS info"); + dprintk(state->verbose, FE_ERROR, 1, "Querying DSS info"); memcpy(fe_info, &dss_info, sizeof (struct dvbfe_info)); break; case DVBFE_DELSYS_DVBS2: - dprintk(verbose, FE_ERROR, 1, "Querying DVB-S2 info"); + dprintk(state->verbose, FE_ERROR, 1, "Querying DVB-S2 info"); memcpy(fe_info, &dvbs2_info, sizeof (struct dvbfe_info)); break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } - dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); + dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); return 0; } @@ -1451,7 +1451,7 @@ static void stb0899_set_delivery(struct stb0899_state *state) switch (state->delsys) { case DVBFE_DELSYS_DVBS: - dprintk(verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); + dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); /* FECM/Viterbi ON */ reg = stb0899_read_reg(state, STB0899_FECM); STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); @@ -1534,7 +1534,7 @@ static void stb0899_set_delivery(struct stb0899_state *state) STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); break; } STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0); @@ -1578,28 +1578,28 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa i_params->freq = params->frequency; switch (state->delsys) { case DVBFE_DELSYS_DVBS: - dprintk(verbose, FE_ERROR, 1, "set DVB-S params"); + dprintk(state->verbose, FE_ERROR, 1, "set DVB-S params"); i_params->srate = params->delsys.dvbs.symbol_rate; break; case DVBFE_DELSYS_DSS: - dprintk(verbose, FE_ERROR, 1, "set DSS params"); + dprintk(state->verbose, FE_ERROR, 1, "set DSS params"); i_params->srate = params->delsys.dss.symbol_rate; break; case DVBFE_DELSYS_DVBS2: - dprintk(verbose, FE_ERROR, 1, "set DVB-S2 params"); + dprintk(state->verbose, FE_ERROR, 1, "set DVB-S2 params"); i_params->srate = params->delsys.dvbs2.symbol_rate; break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } - dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); + dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); SearchRange = 10000000; - dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); + dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); /* checking Search Range is meaningless for a fixed 3 Mhz */ if (INRANGE(i_params->srate, 1000000, 45000000)) { - dprintk(verbose, FE_DEBUG, 1, "Parameters IN RANGE"); + dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE"); stb0899_set_delivery(state); if (state->config->tuner_set_rfsiggain) { @@ -1620,7 +1620,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa switch (state->delsys) { case DVBFE_DELSYS_DVBS: case DVBFE_DELSYS_DSS: - dprintk(verbose, FE_DEBUG, 1, "DVB-S delivery system"); + dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system"); internal->freq = i_params->freq; internal->srate = i_params->srate; /* @@ -1648,17 +1648,17 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11); /* Run the search algorithm */ - dprintk(verbose, FE_DEBUG, 1, "running DVB-S search algo .."); + dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo .."); if (stb0899_dvbs_algo(state) == RANGEOK) { internal->lock = 1; - dprintk(verbose, FE_DEBUG, 1, + dprintk(state->verbose, FE_DEBUG, 1, "-------------------------------------> DVB-S LOCK !"); // stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */ // internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); // internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); -// dprintk(verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); -// dprintk(verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); +// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); +// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); return DVBFE_ALGO_SEARCH_SUCCESS; } else { @@ -1692,10 +1692,10 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa stb0899_set_iterations(state); /* Run the search algorithm */ - dprintk(verbose, FE_DEBUG, 1, "running DVB-S2 search algo .."); + dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo .."); if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) { internal->lock = 1; - dprintk(verbose, FE_DEBUG, 1, + dprintk(state->verbose, FE_DEBUG, 1, "-------------------------------------> DVB-S2 LOCK !"); // stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */ @@ -1710,7 +1710,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa } break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return DVBFE_ALGO_SEARCH_INVALID; } } @@ -1723,12 +1723,12 @@ static enum stb0899_status stb0899_track_carrier(struct stb0899_state *state) u8 reg; reg = stb0899_read_reg(state, STB0899_DSTATUS); - dprintk(verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg); + dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg); if (STB0899_GETFIELD(CARRIER_FOUND, reg)) { - dprintk(verbose, FE_DEBUG, 1, "-------------> CARRIEROK !"); + dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !"); return CARRIEROK; } else { - dprintk(verbose, FE_DEBUG, 1, "-------------> NOCARRIER !"); + dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !"); return NOCARRIER; } @@ -1740,12 +1740,12 @@ static enum stb0899_status stb0899_get_ifagc(struct stb0899_state *state) u8 reg; reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS); - dprintk(verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg); + dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg); if (STB0899_GETFIELD(IF_AGC_LOCK, reg)) { - dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !"); + dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !"); return AGC1OK; } else { - dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCK LOST !"); + dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCK LOST !"); return NOAGC1; } @@ -1932,7 +1932,7 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i #if 0 switch (state->delsys) { case DVBFE_DELSYS_DVBS: - dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S state"); + dprintk(state->verbose, FE_DEBUG, 1, "Tracking DVB-S state"); if (stb0899_track_carrier(state) == CARRIEROK) { params->frequency = internal->freq; params->inversion = internal->inversion; @@ -1943,7 +1943,7 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i } break; case DVBFE_DELSYS_DSS: - dprintk(verbose, FE_DEBUG, 1, "Tracking DSS state"); + dprintk(state->verbose, FE_DEBUG, 1, "Tracking DSS state"); if (stb0899_track_carrier(state) == CARRIEROK) { params->frequency = internal->freq; params->inversion = internal->inversion; @@ -1954,7 +1954,7 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i } break; case DVBFE_DELSYS_DVBS2: - dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S2 state"); + dprintk(state->verbose, FE_DEBUG, 1, "Tracking DVB-S2 state"); if (stb0899_get_ifagc(state) == AGC1OK) { params->frequency = internal->freq; params->inversion = internal->inversion; @@ -1973,12 +1973,12 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i params->delsys.dvbs2.syncd_2 = stb0899_read_reg(state, STB0899_SYNCDSTRM); } lock_lost = STB0899_READ_S2REG(STB0899_S2DEMOD, LOCK_LOST); - dprintk(verbose, FE_DEBUG, 1, "Lock Lost=[0x%02x]\n", lock_lost); + dprintk(state->verbose, FE_DEBUG, 1, "Lock Lost=[0x%02x]\n", lock_lost); if (STB0899_GETFIELD(LOCK_LOST, lock_lost)) - dprintk(verbose, FE_ERROR, 1, "Demodulator LOST LOCK !\n"); + dprintk(state->verbose, FE_ERROR, 1, "Demodulator LOST LOCK !\n"); break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } #endif @@ -1998,21 +1998,21 @@ static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *para params->delivery = state->delsys; switch (state->delsys) { case DVBFE_DELSYS_DVBS: - dprintk(verbose, FE_DEBUG, 1, "Get DVB-S params"); + dprintk(state->verbose, FE_DEBUG, 1, "Get DVB-S params"); params->delsys.dvbs.symbol_rate = internal->srate; params->delsys.dvbs.modulation = DVBFE_MOD_QPSK; break; case DVBFE_DELSYS_DSS: - dprintk(verbose, FE_DEBUG, 1, "Get DSS params"); + dprintk(state->verbose, FE_DEBUG, 1, "Get DSS params"); params->delsys.dss.symbol_rate = internal->srate; params->delsys.dss.modulation = DVBFE_MOD_QPSK; break; case DVBFE_DELSYS_DVBS2: - dprintk(verbose, FE_DEBUG, 1, "Get DVB-S2 params"); + dprintk(state->verbose, FE_DEBUG, 1, "Get DVB-S2 params"); params->delsys.dvbs2.symbol_rate = internal->srate; break; default: - dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system"); + dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } @@ -2077,7 +2077,7 @@ struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_ad goto error; inversion = config->inversion; - state->verbose = verbose; + state->verbose = &verbose; state->config = config; state->i2c = i2c; state->frontend.ops = stb0899_ops; -- cgit v1.2.3 From c553edd5135a293a84f9fd98ed49c51e33bf3787 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 27 Oct 2008 01:28:52 +0400 Subject: Port STB0899 and STB6100 From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 250 ++++++------------------ 1 file changed, 63 insertions(+), 187 deletions(-) (limited to 'linux/drivers/media/dvb/frontends/stb0899_drv.c') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 4d00cc848..02edf1760 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -823,16 +823,17 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t static int stb0899_diseqc_init(struct stb0899_state *state) { struct dvb_diseqc_master_cmd tx_data; +/* struct dvb_diseqc_slave_reply rx_data; - +*/ u8 f22_tx, f22_rx, reg; - u32 mclk, tx_freq = 22000, count = 0, i; - + u32 mclk, tx_freq = 22000;/* count = 0, i; */ +#if 0 u32 trial = 0; /* try max = 2 (try 20khz and 17.5 khz) */ u32 ret_1 = 0; /* 20 Khz status */ u32 ret_2 = 0; /* 17.5 Khz status */ - +#endif tx_data.msg[0] = 0xe2; tx_data.msg_len = 3; reg = stb0899_read_reg(state, STB0899_DISCNTRL2); @@ -896,8 +897,9 @@ static int stb0899_diseqc_init(struct stb0899_state *state) static int stb0899_sleep(struct dvb_frontend *fe) { struct stb0899_state *state = fe->demodulator_priv; +/* u8 reg; - +*/ dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); #if 0 reg = stb0899_read_reg(state, STB0899_SYNTCTRL); @@ -936,7 +938,6 @@ static int stb0899_init(struct dvb_frontend *fe) struct stb0899_config *config = state->config; dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); -// mutex_init(&state->search_lock); /* init device */ dprintk(state->verbose, FE_DEBUG, 1, "init device"); @@ -1009,8 +1010,8 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) int val; u32 reg; switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - case DVBFE_DELSYS_DSS: + case SYS_DVBS: + case SYS_DSS: if (internal->lock) { reg = stb0899_read_reg(state, STB0899_VSTATUS); if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { @@ -1025,7 +1026,7 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) } } break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: if (internal->lock) { reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); val = STB0899_GETFIELD(IF_AGC_GAIN, reg); @@ -1055,8 +1056,8 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) reg = stb0899_read_reg(state, STB0899_VSTATUS); switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - case DVBFE_DELSYS_DSS: + case SYS_DVBS: + case SYS_DSS: if (internal->lock) { if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { @@ -1069,7 +1070,7 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) } } break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: if (internal->lock) { reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg); @@ -1108,8 +1109,8 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) *status = 0; switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - case DVBFE_DELSYS_DSS: + case SYS_DVBS: + case SYS_DSS: dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS"); if (internal->lock) { reg = stb0899_read_reg(state, STB0899_VSTATUS); @@ -1127,7 +1128,7 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) } } break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2"); if (internal->lock) { reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); @@ -1182,8 +1183,8 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) *ber = 0; switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - case DVBFE_DELSYS_DSS: + case SYS_DVBS: + case SYS_DSS: if (internal->lock) { /* average 5 BER values */ for (i = 0; i < 5; i++) { @@ -1203,7 +1204,7 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) } } break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: if (internal->lock) { /* Average 5 PER values */ for (i = 0; i < 5; i++) { @@ -1350,97 +1351,6 @@ int stb0899_get_dev_id(struct stb0899_state *state) return 0; } -static const struct dvbfe_info dvbs_info = { - .name = "STB0899 DVB-S", - .delsys = { - .dvbs.modulation = DVBFE_MOD_QPSK, - .dvbs.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | - DVBFE_FEC_3_4 | DVBFE_FEC_5_6 | - DVBFE_FEC_6_7 - }, - - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 0 -}; - -static const struct dvbfe_info dss_info = { - .name = "STB0899 DSS", - .delsys = { - .dss.modulation = DVBFE_MOD_BPSK | DVBFE_MOD_QPSK, - .dss.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | - DVBFE_FEC_3_4 | DVBFE_FEC_5_6 | - DVBFE_FEC_6_7 - }, - - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 0 -}; - -static const struct dvbfe_info dvbs2_info = { - .name = "STB0899 DVB-S2", - .delsys = { - .dvbs2.modulation = DVBFE_MOD_QPSK | DVBFE_MOD_8PSK | - DVBFE_MOD_16APSK | DVBFE_MOD_32APSK, - - .dvbs2.fec = DVBFE_FEC_1_4 | DVBFE_FEC_1_3 | - DVBFE_FEC_2_5 | DVBFE_FEC_1_2 | - DVBFE_FEC_3_5 | DVBFE_FEC_2_3 | - DVBFE_FEC_3_4 | DVBFE_FEC_4_5 | - DVBFE_FEC_5_6 | DVBFE_FEC_8_9 | - DVBFE_FEC_9_10, - }, - - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 0 -}; - -static int stb0899_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) -{ - struct stb0899_state *state = fe->demodulator_priv; - - dprintk(state->verbose, FE_DEBUG, 1, "Get Info"); - - switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - dprintk(state->verbose, FE_ERROR, 1, "Querying DVB-S info"); - memcpy(fe_info, &dvbs_info, sizeof (struct dvbfe_info)); - break; - case DVBFE_DELSYS_DSS: - dprintk(state->verbose, FE_ERROR, 1, "Querying DSS info"); - memcpy(fe_info, &dss_info, sizeof (struct dvbfe_info)); - break; - case DVBFE_DELSYS_DVBS2: - dprintk(state->verbose, FE_ERROR, 1, "Querying DVB-S2 info"); - memcpy(fe_info, &dvbs2_info, sizeof (struct dvbfe_info)); - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - return -EINVAL; - } - dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); - - return 0; -} - -static int stb0899_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys) -{ - *fe_delsys = DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DSS | DVBFE_DELSYS_DVBS2; - - return 0; -} - static void stb0899_set_delivery(struct stb0899_state *state) { u8 reg; @@ -1450,7 +1360,7 @@ static void stb0899_set_delivery(struct stb0899_state *state) stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2); switch (state->delsys) { - case DVBFE_DELSYS_DVBS: + case SYS_DVBS: dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); /* FECM/Viterbi ON */ reg = stb0899_read_reg(state, STB0899_FECM); @@ -1479,7 +1389,7 @@ static void stb0899_set_delivery(struct stb0899_state *state) STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: /* FECM/Viterbi OFF */ reg = stb0899_read_reg(state, STB0899_FECM); STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); @@ -1507,7 +1417,7 @@ static void stb0899_set_delivery(struct stb0899_state *state) STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0); break; - case DVBFE_DELSYS_DSS: + case SYS_DSS: /* FECM/Viterbi ON */ reg = stb0899_read_reg(state, STB0899_FECM); STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1); @@ -1566,33 +1476,19 @@ static void stb0899_set_iterations(struct stb0899_state *state) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); } -static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_params *params) +static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct stb0899_state *state = fe->demodulator_priv; struct stb0899_params *i_params = &state->params; struct stb0899_internal *internal = &state->internal; struct stb0899_config *config = state->config; + struct dtv_frontend_properties *props = &fe->dtv_property_cache; u32 SearchRange, gain; - i_params->freq = params->frequency; - switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - dprintk(state->verbose, FE_ERROR, 1, "set DVB-S params"); - i_params->srate = params->delsys.dvbs.symbol_rate; - break; - case DVBFE_DELSYS_DSS: - dprintk(state->verbose, FE_ERROR, 1, "set DSS params"); - i_params->srate = params->delsys.dss.symbol_rate; - break; - case DVBFE_DELSYS_DVBS2: - dprintk(state->verbose, FE_ERROR, 1, "set DVB-S2 params"); - i_params->srate = params->delsys.dvbs2.symbol_rate; - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - return -EINVAL; - } + i_params->freq = p->frequency; + i_params->srate = p->u.qpsk.symbol_rate; + state->delsys = props->delivery_system; dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); SearchRange = 10000000; @@ -1604,11 +1500,11 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa if (state->config->tuner_set_rfsiggain) { if (internal->srate > 15000000) - gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */ + gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */ else if (internal->srate > 5000000) - gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */ + gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */ else - gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */ + gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */ state->config->tuner_set_rfsiggain(fe, gain); } @@ -1618,8 +1514,8 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa stb0899_set_mclk(state, config->hi_clk); switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - case DVBFE_DELSYS_DSS: + case SYS_DVBS: + case SYS_DSS: dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system"); internal->freq = i_params->freq; internal->srate = i_params->srate; @@ -1667,7 +1563,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa return DVBFE_ALGO_SEARCH_FAILED; } break; - case DVBFE_DELSYS_DVBS2: + case SYS_DVBS2: internal->freq = i_params->freq; internal->srate = i_params->srate; internal->srch_range = SearchRange; @@ -1717,7 +1613,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa return DVBFE_ALGO_SEARCH_ERROR; } - +#if 0 static enum stb0899_status stb0899_track_carrier(struct stb0899_state *state) { u8 reg; @@ -1752,26 +1648,26 @@ static enum stb0899_status stb0899_get_ifagc(struct stb0899_state *state) return NOAGC1; } -static int stb0899_get_s1fec(struct stb0899_internal *internal, enum dvbfe_fec *fec) +static int stb0899_get_s1fec(struct stb0899_internal *internal, enum fe_code_rate *fec) { switch (internal->fecrate) { case STB0899_FEC_1_2: - *fec = DVBFE_FEC_1_2; + *fec = FEC_1_2; break; case STB0899_FEC_2_3: - *fec = DVBFE_FEC_2_3; + *fec = FEC_2_3; break; case STB0899_FEC_3_4: - *fec = DVBFE_FEC_3_4; + *fec = FEC_3_4; break; case STB0899_FEC_5_6: - *fec = DVBFE_FEC_5_6; + *fec = FEC_5_6; break; case STB0899_FEC_6_7: - *fec = DVBFE_FEC_6_7; + *fec = FEC_6_7; break; case STB0899_FEC_7_8: - *fec = DVBFE_FEC_7_8; + *fec = FEC_7_8; break; default: return -EINVAL; @@ -1905,7 +1801,7 @@ static int stb0899_get_modcod(struct stb0899_internal *internal, struct dvbs2_pa return 0; } - +#endif /* * stb0899_track * periodically check the signal level against a specified @@ -1922,14 +1818,14 @@ static int stb0899_get_modcod(struct stb0899_internal *internal, struct dvbs2_pa * Once a new lock has established, the internal state * frequency (internal->freq) is updated */ -static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, int *delay) +static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { +#if 0 u32 lock_lost; struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; -#if 0 switch (state->delsys) { case DVBFE_DELSYS_DVBS: dprintk(state->verbose, FE_DEBUG, 1, "Tracking DVB-S state"); @@ -1981,40 +1877,19 @@ static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params, i dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); return -EINVAL; } -#endif - - *delay = HZ/10; +// *delay = HZ/10; +#endif return 0; } -static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *params) +static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; - params->frequency = internal->freq; - params->inversion = internal->inversion; - params->delivery = state->delsys; - switch (state->delsys) { - case DVBFE_DELSYS_DVBS: - dprintk(state->verbose, FE_DEBUG, 1, "Get DVB-S params"); - params->delsys.dvbs.symbol_rate = internal->srate; - params->delsys.dvbs.modulation = DVBFE_MOD_QPSK; - break; - case DVBFE_DELSYS_DSS: - dprintk(state->verbose, FE_DEBUG, 1, "Get DSS params"); - params->delsys.dss.symbol_rate = internal->srate; - params->delsys.dss.modulation = DVBFE_MOD_QPSK; - break; - case DVBFE_DELSYS_DVBS2: - dprintk(state->verbose, FE_DEBUG, 1, "Get DVB-S2 params"); - params->delsys.dvbs2.symbol_rate = internal->srate; - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - return -EINVAL; - } + dprintk(state->verbose, FE_DEBUG, 1, "Get params"); + p->u.qpsk.symbol_rate = internal->srate; return 0; } @@ -2024,18 +1899,21 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_CUSTOM; } -static int stb0899_set_delsys(struct dvb_frontend *fe, enum dvbfe_delsys delsys) -{ - struct stb0899_state *state = fe->demodulator_priv; - - state->delsys = delsys; - return 0; -} - static struct dvb_frontend_ops stb0899_ops = { .info = { - .name = "STB0899 Multistandard", + .name = "STB0899 Multistandard", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, + .symbol_rate_min = 5000000, + .symbol_rate_max = 45000000, + + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK }, .release = stb0899_release, @@ -2044,14 +1922,12 @@ static struct dvb_frontend_ops stb0899_ops = { // .wakeup = stb0899_wakeup, .i2c_gate_ctrl = stb0899_i2c_gate_ctrl, - .get_info = stb0899_get_info, - .get_delsys = stb0899_get_delsys, - .set_delsys = stb0899_set_delsys, .get_frontend_algo = stb0899_frontend_algo, .search = stb0899_search, .track = stb0899_track, - .get_params = stb0899_get_params, + .get_frontend = stb0899_get_frontend, + .read_status = stb0899_read_status, .read_snr = stb0899_read_snr, -- cgit v1.2.3