diff options
Diffstat (limited to 'linux/drivers/media/dvb/frontends/dib3000mb.c')
-rw-r--r-- | linux/drivers/media/dvb/frontends/dib3000mb.c | 264 |
1 files changed, 165 insertions, 99 deletions
diff --git a/linux/drivers/media/dvb/frontends/dib3000mb.c b/linux/drivers/media/dvb/frontends/dib3000mb.c index 1d2489d85..f7ee10fdf 100644 --- a/linux/drivers/media/dvb/frontends/dib3000mb.c +++ b/linux/drivers/media/dvb/frontends/dib3000mb.c @@ -30,9 +30,9 @@ #include <linux/delay.h> #include "dvb_frontend.h" +#include "dib3000-common.h" #include "dib3000mb_priv.h" -#include "dib3000mb.h" - +#include "dib3000.h" struct dib3000mb_state { @@ -41,7 +41,11 @@ struct dib3000mb_state { struct dvb_frontend_ops ops; /* configuration settings */ - const struct dib3000mb_config* config; + const struct dib3000_config* config; + + spinlock_t pid_list_lock; + struct dib3000_pid pid_list[DIB3000MB_NUM_PIDS]; + int feedcount; struct dvb_frontend frontend; }; @@ -68,9 +72,11 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=setfe,1 /* Version information */ #define DRIVER_VERSION "0.1" -#define DRIVER_DESC "DiBcom 3000-MB DVB-T Demodulator driver" +#define DRIVER_DESC "DiBcom 3000-MB DVB-T demodulator driver" #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" + +/* handy shortcuts */ #define rd(reg) dib3000mb_read_reg(state,reg) #define wr(reg,val) if (dib3000mb_write_reg(state,reg,val)) \ { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; } @@ -80,7 +86,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=setfe,1 wr(a[i],v[i]); \ } -static u16 dib3000mb_read_reg(struct dib3000mb_state *state, u16 reg) +static int dib3000mb_read_reg(struct dib3000mb_state *state, u16 reg) { u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; u8 rb[2]; @@ -153,10 +159,10 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, if (tuner) { wr(DIB3000MB_REG_TUNER, - DIB3000MB_ACTIVATE_TUNER_XFER(state->config->pll_addr)); + DIB3000_TUNER_WRITE_ENABLE(state->config->pll_addr)); state->config->pll_set(fe, fep); wr(DIB3000MB_REG_TUNER, - DIB3000MB_DEACTIVATE_TUNER_XFER(state->config->pll_addr)); + DIB3000_TUNER_WRITE_DISABLE(state->config->pll_addr)); deb_setf("bandwidth: "); switch (ofdm->bandwidth) { @@ -188,15 +194,14 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, switch (ofdm->transmission_mode) { case TRANSMISSION_MODE_2K: deb_setf("2k\n"); - wr(DIB3000MB_REG_FFT, DIB3000MB_FFT_2K); + wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); break; case TRANSMISSION_MODE_8K: deb_setf("8k\n"); - wr(DIB3000MB_REG_FFT, DIB3000MB_FFT_8K); + wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); break; case TRANSMISSION_MODE_AUTO: deb_setf("auto\n"); - wr(DIB3000MB_REG_FFT, DIB3000MB_FFT_AUTO); break; default: return -EINVAL; @@ -206,23 +211,22 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, switch (ofdm->guard_interval) { case GUARD_INTERVAL_1_32: deb_setf("1_32\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000MB_GUARD_TIME_1_32); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); break; case GUARD_INTERVAL_1_16: deb_setf("1_16\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000MB_GUARD_TIME_1_16); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); break; case GUARD_INTERVAL_1_8: deb_setf("1_8\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000MB_GUARD_TIME_1_8); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); break; case GUARD_INTERVAL_1_4: deb_setf("1_4\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000MB_GUARD_TIME_1_4); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); break; case GUARD_INTERVAL_AUTO: deb_setf("auto\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000MB_GUARD_TIME_AUTO); break; default: return -EINVAL; @@ -232,14 +236,14 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, switch (fep->inversion) { case INVERSION_OFF: deb_setf("off\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000MB_DDS_INV_OFF); + wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); break; case INVERSION_AUTO: deb_setf("auto "); break; case INVERSION_ON: deb_setf("on\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000MB_DDS_INV_ON); + wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); break; default: return -EINVAL; @@ -249,15 +253,15 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, switch (ofdm->constellation) { case QPSK: deb_setf("qpsk\n"); - wr(DIB3000MB_REG_QAM, DIB3000MB_QAM_QPSK); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); break; case QAM_16: deb_setf("qam16\n"); - wr(DIB3000MB_REG_QAM, DIB3000MB_QAM_QAM16); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); break; case QAM_64: deb_setf("qam64\n"); - wr(DIB3000MB_REG_QAM, DIB3000MB_QAM_QAM64); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); break; case QAM_AUTO: break; @@ -271,19 +275,18 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, /* fall through */ case HIERARCHY_1: deb_setf("alpha=1\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000MB_VIT_ALPHA_1); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); break; case HIERARCHY_2: deb_setf("alpha=2\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000MB_VIT_ALPHA_2); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); break; case HIERARCHY_4: deb_setf("alpha=4\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000MB_VIT_ALPHA_4); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); break; case HIERARCHY_AUTO: deb_setf("alpha=auto\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000MB_VIT_ALPHA_AUTO); break; default: return -EINVAL; @@ -292,40 +295,40 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, deb_setf("hierarchy: "); if (ofdm->hierarchy_information == HIERARCHY_NONE) { deb_setf("none\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000MB_VIT_HRCH_OFF); - wr(DIB3000MB_REG_VIT_HP, DIB3000MB_VIT_HP); + wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); + wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); fe_cr = ofdm->code_rate_HP; } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { deb_setf("on\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000MB_VIT_HRCH_ON); - wr(DIB3000MB_REG_VIT_HP, DIB3000MB_VIT_LP); + wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); + wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); fe_cr = ofdm->code_rate_LP; } deb_setf("fec: "); switch (fe_cr) { case FEC_1_2: deb_setf("1_2\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_1_2); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); break; case FEC_2_3: deb_setf("2_3\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_2_3); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); break; case FEC_3_4: deb_setf("3_4\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_3_4); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); break; case FEC_5_6: deb_setf("5_6\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_5_6); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); break; case FEC_7_8: deb_setf("7_8\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_7_8); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); break; case FEC_NONE: deb_setf("none "); - /* fall through */ + break; case FEC_AUTO: deb_setf("auto\n"); break; @@ -333,7 +336,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, return -EINVAL; } - seq = dib3000mb_seq + seq = dib3000_seq [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] [ofdm->guard_interval == GUARD_INTERVAL_AUTO] [fep->inversion == INVERSION_AUTO]; @@ -377,6 +380,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, ofdm->hierarchy_information == HIERARCHY_AUTO || fe_cr == FEC_AUTO || fep->inversion == INVERSION_AUTO) { + int as_count=0; deb_setf("autosearch enabled.\n"); @@ -385,8 +389,10 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - while ((search_state = dib3000mb_fe_read_search_status(fe)) < 0); - deb_info("search_state after autosearch %d\n",search_state); + while ((search_state = dib3000mb_fe_read_search_status(fe)) < 0 && as_count++ < 100) + msleep(1); + + deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count); } else { wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); @@ -395,7 +401,6 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, return 0; } - static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) { struct dib3000mb_state* state = (struct dib3000mb_state*) fe->demodulator_priv; @@ -411,9 +416,6 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON); - wr(DIB3000MB_REG_QAM, DIB3000MB_QAM_RESERVED); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000MB_VIT_ALPHA_AUTO); - wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB); wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB); @@ -435,7 +437,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT); wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT); - wr(DIB3000MB_REG_SEQ, dib3000mb_seq[1][1][1]); + wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); @@ -453,8 +455,6 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108); wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122); wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000MB_FEC_1_2); - wr(DIB3000MB_REG_VIT_HP, DIB3000MB_VIT_HP); wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT); wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs); @@ -467,7 +467,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142); wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188); - wr(DIB3000MB_REG_FIFO_144, DIB3000MB_FIFO_144); + wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE); wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146); wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147); @@ -476,34 +476,15 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) if (state->config->pll_init) { wr(DIB3000MB_REG_TUNER, - DIB3000MB_ACTIVATE_TUNER_XFER(state->config->pll_addr << 1)); + DIB3000_TUNER_WRITE_ENABLE(state->config->pll_addr)); state->config->pll_init(fe); wr(DIB3000MB_REG_TUNER, - DIB3000MB_DEACTIVATE_TUNER_XFER(state->config->pll_addr << 1)); + DIB3000_TUNER_WRITE_DISABLE(state->config->pll_addr)); } return 0; } - - - - - - - - - - - - - - - - - - - static int dib3000mb_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { @@ -540,15 +521,15 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { - case DIB3000MB_QAM_QPSK: + case DIB3000_CONSTELLATION_QPSK: deb_getf("QPSK "); ofdm->constellation = QPSK; break; - case DIB3000MB_QAM_QAM16: + case DIB3000_CONSTELLATION_16QAM: deb_getf("QAM16 "); ofdm->constellation = QAM_16; break; - case DIB3000MB_QAM_QAM64: + case DIB3000_CONSTELLATION_64QAM: deb_getf("QAM64 "); ofdm->constellation = QAM_64; break; @@ -565,19 +546,19 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, ofdm->code_rate_HP = FEC_NONE; switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { - case DIB3000MB_VIT_ALPHA_OFF: + case DIB3000_ALPHA_0: deb_getf("HIERARCHY_NONE "); ofdm->hierarchy_information = HIERARCHY_NONE; break; - case DIB3000MB_VIT_ALPHA_1: + case DIB3000_ALPHA_1: deb_getf("HIERARCHY_1 "); ofdm->hierarchy_information = HIERARCHY_1; break; - case DIB3000MB_VIT_ALPHA_2: + case DIB3000_ALPHA_2: deb_getf("HIERARCHY_2 "); ofdm->hierarchy_information = HIERARCHY_2; break; - case DIB3000MB_VIT_ALPHA_4: + case DIB3000_ALPHA_4: deb_getf("HIERARCHY_4 "); ofdm->hierarchy_information = HIERARCHY_4; break; @@ -595,23 +576,23 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, } switch (tps_val) { - case DIB3000MB_FEC_1_2: + case DIB3000_FEC_1_2: deb_getf("FEC_1_2 "); *cr = FEC_1_2; break; - case DIB3000MB_FEC_2_3: + case DIB3000_FEC_2_3: deb_getf("FEC_2_3 "); *cr = FEC_2_3; break; - case DIB3000MB_FEC_3_4: + case DIB3000_FEC_3_4: deb_getf("FEC_3_4 "); *cr = FEC_3_4; break; - case DIB3000MB_FEC_5_6: + case DIB3000_FEC_5_6: deb_getf("FEC_5_6 "); *cr = FEC_4_5; break; - case DIB3000MB_FEC_7_8: + case DIB3000_FEC_7_8: deb_getf("FEC_7_8 "); *cr = FEC_7_8; break; @@ -622,19 +603,19 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, deb_getf("TPS: %d\n",tps_val); switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { - case DIB3000MB_GUARD_TIME_1_32: + case DIB3000_GUARD_TIME_1_32: deb_getf("GUARD_INTERVAL_1_32 "); ofdm->guard_interval = GUARD_INTERVAL_1_32; break; - case DIB3000MB_GUARD_TIME_1_16: + case DIB3000_GUARD_TIME_1_16: deb_getf("GUARD_INTERVAL_1_16 "); ofdm->guard_interval = GUARD_INTERVAL_1_16; break; - case DIB3000MB_GUARD_TIME_1_8: + case DIB3000_GUARD_TIME_1_8: deb_getf("GUARD_INTERVAL_1_8 "); ofdm->guard_interval = GUARD_INTERVAL_1_8; break; - case DIB3000MB_GUARD_TIME_1_4: + case DIB3000_GUARD_TIME_1_4: deb_getf("GUARD_INTERVAL_1_4 "); ofdm->guard_interval = GUARD_INTERVAL_1_4; break; @@ -645,11 +626,11 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, deb_getf("TPS: %d\n", tps_val); switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { - case DIB3000MB_FFT_2K: + case DIB3000_TRANSMISSION_MODE_2K: deb_getf("TRANSMISSION_MODE_2K "); ofdm->transmission_mode = TRANSMISSION_MODE_2K; break; - case DIB3000MB_FFT_8K: + case DIB3000_TRANSMISSION_MODE_8K: deb_getf("TRANSMISSION_MODE_8K "); ofdm->transmission_mode = TRANSMISSION_MODE_8K; break; @@ -801,7 +782,7 @@ static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fr static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe) { - return dib3000mb_fe_init(fe, 0); + return dib3000mb_fe_init(fe, 0); } static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) @@ -811,44 +792,129 @@ static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_ static void dib3000mb_release(struct dvb_frontend* fe) { - struct dib3000mb_state* state = (struct dib3000mb_state*) fe->demodulator_priv; + struct dib3000mb_state *state = (struct dib3000mb_state*) fe->demodulator_priv; kfree(state); } +/* pid filter and transfer stuff */ + +/* fetch a pid from pid_list */ +static int dib3000_get_pid_index(struct dib3000_pid pid_list[], + int num_pids, int pid, spinlock_t *pid_list_lock,int onoff) +{ + int i,ret = -1; + unsigned long flags; + + spin_lock_irqsave(pid_list_lock,flags); + for (i=0; i < num_pids; i++) + if (onoff) { + if (!pid_list[i].active) { + pid_list[i].pid = pid; + pid_list[i].active = 1; + ret = i; + break; + } + } else { + if (pid_list[i].active && pid_list[i].pid == pid) { + pid_list[i].pid = 0; + pid_list[i].active = 0; + ret = i; + break; + } + } + + spin_unlock_irqrestore(pid_list_lock,flags); + return ret; +} + +static int dib3000mb_pid_control(struct dvb_frontend *fe,int pid,int onoff) +{ + struct dib3000mb_state *state = fe->demodulator_priv; + int index = dib3000_get_pid_index(state->pid_list, DIB3000MB_NUM_PIDS, pid, &state->pid_list_lock,onoff); + pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); + + deb_info("setting pid 0x%x on index %d\n",pid,index); + + if (index >= 0) { + wr(index+DIB3000MB_REG_FIRST_PID,pid); + } else { + err("no more pids for filtering."); + return -ENOMEM; + } + return 0; +} + +static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) +{ + struct dib3000mb_state *state = (struct dib3000mb_state*) fe->demodulator_priv; + + if (onoff) { + wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE); + } else { + wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); + } + return 0; +} + +static int dib3000mb_pid_filter(struct dvb_frontend *fe, int onoff) +{ + //struct dib3000mb_state *state = fe->demodulator_priv; + /* switch it off and on */ + return 0; +} + static struct dvb_frontend_ops dib3000mb_ops; -struct dvb_frontend* dib3000mb_attach(const struct dib3000mb_config* config, - struct i2c_adapter* i2c) +struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, + struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops) { struct dib3000mb_state* state = NULL; - u16 manfid, devid; + int i; /* allocate memory for the internal state */ state = (struct dib3000mb_state*) kmalloc(sizeof(struct dib3000mb_state), GFP_KERNEL); - if (state == NULL) goto error; + if (state == NULL) + goto error; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); - /* check if the demod is there */ - manfid = dib3000mb_read_reg(state, DIB3000MB_REG_MANUFACTOR_ID); - if (manfid != 0x01b3) goto error; - - devid = dib3000mb_read_reg(state, DIB3000MB_REG_DEVICE_ID); - if (devid != 0x3000) goto error; - + /* check for the correct demod */ + if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) + goto error; + + if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID) + goto error; + + /* initialize the id_list */ + deb_info("initializing %d pids for the pid_list.\n",DIB3000MB_NUM_PIDS); + state->pid_list_lock = SPIN_LOCK_UNLOCKED; + memset(state->pid_list,0,DIB3000MB_NUM_PIDS*(sizeof(struct dib3000_pid))); + for (i=0; i < DIB3000MB_NUM_PIDS; i++) { + state->pid_list[i].pid = 0; + state->pid_list[i].active = 0; + } + state->feedcount = 0; + /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; + + /* set the xfer operations */ + xfer_ops->pid_filter = dib3000mb_pid_filter; + xfer_ops->fifo_ctrl = dib3000mb_fifo_control; + xfer_ops->pid_ctrl = dib3000mb_pid_control; + return &state->frontend; error: - if (state) kfree(state); + if (state) + kfree(state); return NULL; } - + static struct dvb_frontend_ops dib3000mb_ops = { .info = { |