--- zzzz-none-000/linux-3.10.107/drivers/media/usb/dvb-usb/dib0700_devices.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/usb/dvb-usb/dib0700_devices.c 2021-02-04 17:41:59.000000000 +0000 @@ -32,6 +32,8 @@ struct dib0700_adapter_state { int (*set_param_save) (struct dvb_frontend *); const struct firmware *frontend_firmware; + struct dib7000p_ops dib7000p_ops; + struct dib8000_ops dib8000_ops; }; /* Hauppauge Nova-T 500 (aka Bristol) @@ -218,12 +220,21 @@ }; static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = { - 60000, 30000, - 1, 8, 3, 1, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (524 << 0), - 0, - 20452225, + .internal = 60000, + .sampling = 30000, + .pll_prediv = 1, + .pll_ratio = 8, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = 0, + .timf = 20452225, }; static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = { @@ -262,6 +273,11 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (adap->id == 0) { dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); @@ -272,16 +288,16 @@ msleep(10); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, stk7700d_dib7000p_mt2266_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = - dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80 + (adap->id << 1), &stk7700d_dib7000p_mt2266_config[adap->id]); @@ -290,6 +306,11 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (adap->id == 0) { dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); @@ -301,16 +322,16 @@ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7700d_dib7000p_mt2266_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = - dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80 + (adap->id << 1), &stk7700d_dib7000p_mt2266_config[adap->id]); @@ -320,64 +341,67 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct dib0700_adapter_state *state = adap->priv; + + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, + DIBX000_I2C_INTERFACE_TUNER, 1); return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0; } /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */ static struct dibx000_agc_config xc3028_agc_config = { - BAND_VHF | BAND_UHF, /* band_caps */ - + .band_caps = BAND_VHF | BAND_UHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | - (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ - - 712, /* inv_gain */ - 21, /* time_stabiliz */ - - 0, /* alpha_level */ - 118, /* thlock */ - - 0, /* wbd_inv */ - 2867, /* wbd_ref */ - 0, /* wbd_sel */ - 2, /* wbd_alpha */ - - 0, /* agc1_max */ - 0, /* agc1_min */ - 39718, /* agc2_max */ - 9930, /* agc2_min */ - 0, /* agc1_pt1 */ - 0, /* agc1_pt2 */ - 0, /* agc1_pt3 */ - 0, /* agc1_slope1 */ - 0, /* agc1_slope2 */ - 0, /* agc2_pt1 */ - 128, /* agc2_pt2 */ - 29, /* agc2_slope1 */ - 29, /* agc2_slope2 */ - - 17, /* alpha_mant */ - 27, /* alpha_exp */ - 23, /* beta_mant */ - 51, /* beta_exp */ - - 1, /* perform_agc_softsplit */ + .setup = (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), + .inv_gain = 712, + .time_stabiliz = 21, + .alpha_level = 0, + .thlock = 118, + .wbd_inv = 0, + .wbd_ref = 2867, + .wbd_sel = 0, + .wbd_alpha = 2, + .agc1_max = 0, + .agc1_min = 0, + .agc2_max = 39718, + .agc2_min = 9930, + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 0, + .agc1_slope1 = 0, + .agc1_slope2 = 0, + .agc2_pt1 = 0, + .agc2_pt2 = 128, + .agc2_slope1 = 29, + .agc2_slope2 = 29, + .alpha_mant = 17, + .alpha_exp = 27, + .beta_mant = 23, + .beta_exp = 51, + .perform_agc_softsplit = 1, }; /* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */ static struct dibx000_bandwidth_config xc3028_bw_config = { - 60000, 30000, /* internal, sampling */ - 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */ - 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, - modulo */ - (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ - (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ - 20452225, /* timf */ - 30000000, /* xtal_hz */ + .internal = 60000, + .sampling = 30000, + .pll_prediv = 1, + .pll_ratio = 8, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 0, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ + .ifreq = (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ + .timf = 20452225, + .xtal_hz = 30000000, }; static struct dib7000p_config stk7700ph_dib7700_xc3028_config = { @@ -397,12 +421,14 @@ int command, int arg) { struct dvb_usb_adapter *adap = ptr; + struct dib0700_adapter_state *state = adap->priv; switch (command) { case XC2028_TUNER_RESET: /* Send the tuner in then out of reset */ - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10); - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0); + msleep(10); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); break; case XC2028_RESET_CLK: break; @@ -428,12 +454,16 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) && desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX)) - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); else - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); @@ -445,14 +475,15 @@ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &stk7700ph_dib7700_xc3028_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &stk7700ph_dib7700_xc3028_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -461,8 +492,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); stk7700ph_xc3028_config.i2c_adap = tun_i2c; @@ -478,9 +510,6 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; -/* Number of keypresses to ignore before start repeating */ -#define RC_REPEAT_DELAY 6 - /* * This function is used only when firmware is < 1.20 version. Newer * firmwares use bulk mode, with functions implemented at dib0700_core, @@ -489,7 +518,8 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) { u8 key[4]; - u32 keycode; + enum rc_type protocol; + u32 scancode; u8 toggle; int i; struct dib0700_state *st = d->priv; @@ -514,30 +544,31 @@ /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ - dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ + dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ - d->last_event = 0; switch (d->props.rc.core.protocol) { case RC_BIT_NEC: /* NEC protocol sends repeat code as 0 0 0 FF */ if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && - (key[3] == 0xff)) - keycode = d->last_event; - else { - keycode = key[3-2] << 8 | key[3-3]; - d->last_event = keycode; + (key[3] == 0xff)) { + rc_repeat(d->rc_dev); + return 0; } - rc_keydown(d->rc_dev, keycode, 0); + protocol = RC_TYPE_NEC; + scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]); + toggle = 0; break; + default: /* RC-5 protocol changes toggle bit on new keypress */ - keycode = key[3-2] << 8 | key[3-3]; + protocol = RC_TYPE_RC5; + scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]); toggle = key[3-1]; - rc_keydown(d->rc_dev, keycode, toggle); - break; } + + rc_keydown(d->rc_dev, protocol, scancode, toggle); return 0; } @@ -589,59 +620,55 @@ }; static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { - BAND_UHF | BAND_VHF, - + .band_caps = BAND_UHF | BAND_VHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) - | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), - - 712, - 41, - - 0, - 118, - - 0, - 4095, - 0, - 0, - - 42598, - 16384, - 42598, - 0, - - 0, - 137, - 255, - - 0, - 255, - - 0, - 0, - - 0, - 41, - - 15, - 25, - - 28, - 48, - - 0, + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), + .inv_gain = 712, + .time_stabiliz = 41, + .alpha_level = 0, + .thlock = 118, + .wbd_inv = 0, + .wbd_ref = 4095, + .wbd_sel = 0, + .wbd_alpha = 0, + .agc1_max = 42598, + .agc1_min = 16384, + .agc2_max = 42598, + .agc2_min = 0, + .agc1_pt1 = 0, + .agc1_pt2 = 137, + .agc1_pt3 = 255, + .agc1_slope1 = 0, + .agc1_slope2 = 255, + .agc2_pt1 = 0, + .agc2_pt2 = 0, + .agc2_slope1 = 0, + .agc2_slope2 = 41, + .alpha_mant = 15, + .alpha_exp = 25, + .beta_mant = 28, + .beta_exp = 48, + .perform_agc_softsplit = 0, }; static struct dibx000_bandwidth_config stk7700p_pll_config = { - 60000, 30000, - 1, 8, 3, 1, 0, - 0, 0, 1, 1, 0, - (3 << 14) | (1 << 12) | (524 << 0), - 60258167, - 20452225, - 30000000, + .internal = 60000, + .sampling = 30000, + .pll_prediv = 1, + .pll_ratio = 8, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 0, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = 60258167, + .timf = 20452225, + .xtal_hz = 30000000, }; static struct dib7000m_config stk7700p_dib7000m_config = { @@ -673,6 +700,11 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + /* unless there is no real power management in DVB - we leave the device on GPIO6 */ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); @@ -689,11 +721,13 @@ st->mt2060_if1[0] = 1220; - if (dib7000pc_detection(&adap->dev->i2c_adap)) { - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); + if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap)) { + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); st->is_dib7000pc = 1; - } else + } else { + memset(&state->dib7000p_ops, 0, sizeof(state->dib7000p_ops)); adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); + } return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -707,14 +741,16 @@ struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; struct dib0700_state *st = adap->dev->priv; struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; s8 a; int if1=1220; + if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) { if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; } if (st->is_dib7000pc) - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); else tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); @@ -724,57 +760,54 @@ /* DIB7070 generic */ static struct dibx000_agc_config dib7070_agc_config = { - BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) - | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - - 600, - 10, - - 0, - 118, - - 0, - 3530, - 1, - 5, - - 65535, - 0, - - 65535, - 0, - - 0, - 40, - 183, - 206, - 255, - 72, - 152, - 88, - 90, - - 17, - 27, - 23, - 51, - - 0, + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + .inv_gain = 600, + .time_stabiliz = 10, + .alpha_level = 0, + .thlock = 118, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, + .agc1_max = 65535, + .agc1_min = 0, + .agc2_max = 65535, + .agc2_min = 0, + .agc1_pt1 = 0, + .agc1_pt2 = 40, + .agc1_pt3 = 183, + .agc1_slope1 = 206, + .agc1_slope2 = 255, + .agc2_pt1 = 72, + .agc2_pt2 = 152, + .agc2_slope1 = 88, + .agc2_slope2 = 90, + .alpha_mant = 17, + .alpha_exp = 27, + .beta_mant = 23, + .beta_exp = 51, + .perform_agc_softsplit = 0, }; static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("reset: %d", onoff); - return dib7000p_set_gpio(fe, 8, 0, !onoff); + return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); } static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("sleep: %d", onoff); - return dib7000p_set_gpio(fe, 9, 0, onoff); + return state->dib7000p_ops.set_gpio(fe, 9, 0, onoff); } static struct dib0070_config dib7070p_dib0070_config[2] = { @@ -818,7 +851,7 @@ default: offset = 550; break; } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); return state->set_param_save(fe); } @@ -828,43 +861,43 @@ struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; - u16 offset; - u8 band = BAND_OF_FREQUENCY(p->frequency/1000); - switch (band) { - case BAND_VHF: - dib7000p_set_gpio(fe, 0, 0, 1); - offset = 850; - break; - case BAND_UHF: - default: - dib7000p_set_gpio(fe, 0, 0, 0); - offset = 250; - break; - } - deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe); + u16 offset; + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); + switch (band) { + case BAND_VHF: + state->dib7000p_ops.set_gpio(fe, 0, 0, 1); + offset = 850; + break; + case BAND_UHF: + default: + state->dib7000p_ops.set_gpio(fe, 0, 0, 0); + offset = 250; + break; + } + deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + return state->set_param_save(fe); } static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) { - struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, - &dib7770p_dib0070_config) == NULL) - return -ENODEV; - - st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; - adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override; - return 0; + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, + &dib7770p_dib0070_config) == NULL) + return -ENODEV; + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override; + return 0; } static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL) @@ -882,38 +915,52 @@ static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { + struct dib0700_adapter_state *state = adapter->priv; struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) - return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { struct dib0700_state *st = adapter->dev->priv; + struct dib0700_adapter_state *state = adapter->priv; if (st->is_dib7000pc) - return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + struct dib0700_adapter_state *state = adapter->priv; + return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + struct dib0700_adapter_state *state = adapter->priv; + return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { - 60000, 15000, - 1, 20, 3, 1, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (524 << 0), - (0 << 25) | 0, - 20452225, - 12000000, + .internal = 60000, + .sampling = 15000, + .pll_prediv = 1, + .pll_ratio = 20, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = (0 << 25) | 0, + .timf = 20452225, + .xtal_hz = 12000000, }; static struct dib7000p_config dib7070p_dib7000p_config = { @@ -936,6 +983,11 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -954,14 +1006,15 @@ msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -988,6 +1041,11 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -1006,14 +1064,15 @@ msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7770p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &dib7770p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1112,14 +1171,22 @@ }; static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = { - 60000, 15000, /* internal, sampling*/ - 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/ - 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core, - ADClkSrc, modulo */ - (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/ - (0 << 25) | 0, /* ifreq = 0.000000 MHz*/ - 18179755, /* timf*/ - 12000000, /* xtal_hz*/ + .internal = 60000, + .sampling = 15000, + .pll_prediv = 1, + .pll_ratio = 20, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + .sad_cfg = (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/ + .ifreq = (0 << 25) | 0, /* ifreq = 0.000000 MHz*/ + .timf = 18179755, + .xtal_hz = 12000000, }; static struct dib8000_config dib807x_dib8000_config[2] = { @@ -1161,12 +1228,18 @@ static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff) { - return dib8000_set_gpio(fe, 5, 0, !onoff); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.set_gpio(fe, 5, 0, !onoff); } static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff) { - return dib8000_set_gpio(fe, 0, 0, onoff); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.set_gpio(fe, 0, 0, onoff); } static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = { @@ -1223,7 +1296,7 @@ offset += 250; break; } deb_info("WBD for DiB8000: %d\n", offset); - dib8000_set_wbd_ref(fe, offset); + state->dib8000_ops.set_wbd_ref(fe, offset); return state->set_param_save(fe); } @@ -1231,7 +1304,7 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { @@ -1252,18 +1325,27 @@ static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + struct dib0700_adapter_state *state = adapter->priv; + + return state->dib8000_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + struct dib0700_adapter_state *state = adapter->priv; + + return state->dib8000_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } /* STK807x */ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -1279,10 +1361,10 @@ msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1291,6 +1373,11 @@ /* STK807xPVR */ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(30); dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); @@ -1309,9 +1396,9 @@ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1319,10 +1406,15 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -1331,104 +1423,121 @@ /* STK8096GP */ static struct dibx000_agc_config dib8090_agc_config[2] = { { - BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - 787, - 10, - - 0, - 118, + .inv_gain = 787, + .time_stabiliz = 10, - 0, - 3530, - 1, - 5, + .alpha_level = 0, + .thlock = 118, - 65535, - 0, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, - 65535, - 0, + .agc1_max = 65535, + .agc1_min = 0, - 0, - 32, - 114, - 143, - 144, - 114, - 227, - 116, - 117, + .agc2_max = 65535, + .agc2_min = 0, - 28, - 26, - 31, - 51, + .agc1_pt1 = 0, + .agc1_pt2 = 32, + .agc1_pt3 = 114, + .agc1_slope1 = 143, + .agc1_slope2 = 144, + .agc2_pt1 = 114, + .agc2_pt2 = 227, + .agc2_slope1 = 116, + .agc2_slope2 = 117, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, - 0, + .perform_agc_softsplit = 0, }, { - BAND_CBAND, + .band_caps = BAND_CBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - 787, - 10, - - 0, - 118, + .inv_gain = 787, + .time_stabiliz = 10, - 0, - 3530, - 1, - 5, + .alpha_level = 0, + .thlock = 118, - 0, - 0, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, - 65535, - 0, + .agc1_max = 0, + .agc1_min = 0, - 0, - 32, - 114, - 143, - 144, - 114, - 227, - 116, - 117, + .agc2_max = 65535, + .agc2_min = 0, - 28, - 26, - 31, - 51, + .agc1_pt1 = 0, + .agc1_pt2 = 32, + .agc1_pt3 = 114, + .agc1_slope1 = 143, + .agc1_slope2 = 144, + .agc2_pt1 = 114, + .agc2_pt2 = 227, + .agc2_slope1 = 116, + .agc2_slope2 = 117, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, - 0, + .perform_agc_softsplit = 0, } }; static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { - 54000, 13500, - 1, 18, 3, 1, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (599 << 0), - (0 << 25) | 0, - 20199727, - 12000000, + .internal = 54000, + .sampling = 13500, + + .pll_prediv = 1, + .pll_ratio = 18, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + + .sad_cfg = (3 << 14) | (1 << 12) | (599 << 0), + + .ifreq = (0 << 25) | 0, + .timf = 20199727, + + .xtal_hz = 12000000, }; static int dib8090_get_adc_power(struct dvb_frontend *fe) { - return dib8000_get_adc_power(fe, 1); + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + return state->dib8000_ops.get_adc_power(fe, 1); } static void dib8090_agc_control(struct dvb_frontend *fe, u8 restart) @@ -1551,10 +1660,10 @@ default: deb_info("Warning : Rf frequency (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency); case BAND_VHF: - dib8000_set_gpio(fe, 3, 0, 1); + state->dib8000_ops.set_gpio(fe, 3, 0, 1); break; case BAND_UHF: - dib8000_set_gpio(fe, 3, 0, 0); + state->dib8000_ops.set_gpio(fe, 3, 0, 0); break; } @@ -1568,7 +1677,7 @@ } /** Update PLL if needed ratio **/ - dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0); + state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0); /** Get optimize PLL ratio to remove spurious **/ pll_ratio = dib8090_compute_pll_parameters(fe); @@ -1582,14 +1691,14 @@ timf = 18179756; /** Update ratio **/ - dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio); + state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio); - dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, timf); + state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, timf); if (band != BAND_CBAND) { /* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */ target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; - dib8000_set_wbd_ref(fe, target); + state->dib8000_ops.set_wbd_ref(fe, target); } if (band == BAND_CBAND) { @@ -1601,18 +1710,18 @@ msleep(ret); tune_state = dib0090_get_tune_state(fe); if (tune_state == CT_AGC_STEP_0) - dib8000_set_gpio(fe, 6, 0, 1); + state->dib8000_ops.set_gpio(fe, 6, 0, 1); else if (tune_state == CT_AGC_STEP_1) { dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); if (rf_gain_limit < 2000) /* activate the external attenuator in case of very high input power */ - dib8000_set_gpio(fe, 6, 0, 0); + state->dib8000_ops.set_gpio(fe, 6, 0, 0); } } while (tune_state < CT_AGC_STOP); deb_info("switching to PWM AGC\n"); dib0090_pwm_gain_reset(fe); - dib8000_pwm_agc_reset(fe); - dib8000_set_tune_state(fe, CT_DEMOD_START); + state->dib8000_ops.pwm_agc_reset(fe); + state->dib8000_ops.set_tune_state(fe, CT_DEMOD_START); } else { /* for everything else than CBAND we are using standard AGC */ deb_info("not tuning in CBAND - standard AGC startup\n"); @@ -1625,7 +1734,7 @@ static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; @@ -1637,6 +1746,11 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -1652,9 +1766,9 @@ msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1663,16 +1777,16 @@ { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c; - struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1); + struct dvb_frontend *fe_slave = st->dib8000_ops.get_slave_frontend(adap->fe_adap[0].fe, 1); if (fe_slave) { - tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = st->dib8000_ops.get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; fe_slave->dvb = adap->fe_adap[0].fe->dvb; fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override; } - tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; @@ -1685,6 +1799,10 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) { struct dvb_frontend *fe_slave; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(20); @@ -1703,14 +1821,18 @@ msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); if (adap->fe_adap[0].fe == NULL) return -ENODEV; - fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); - dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); + /* Needed to increment refcount */ + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; + + fe_slave = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); + state->dib8000_ops.set_slave_frontend(adap->fe_adap[0].fe, fe_slave); return fe_slave == NULL ? -ENODEV : 0; } @@ -1809,13 +1931,22 @@ }; static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = { - 108000, 13500, - 1, 9, 1, 0, 0, - 0, 0, 0, 0, 2, - (3 << 14) | (1 << 12) | (524 << 0), - (0 << 25) | 0, - 20199729, - 12000000, + .internal = 108000, + .sampling = 13500, + .pll_prediv = 1, + .pll_ratio = 9, + .pll_range = 1, + .pll_reset = 0, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 0, + .ADClkSrc = 0, + .modulo = 2, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = (0 << 25) | 0, + .timf = 20199729, + .xtal_hz = 12000000, }; static struct dib8000_config tfe8096p_dib8000_config = { @@ -1845,7 +1976,7 @@ { 0xFFFF, 0, 0, 0, 0, 0}, }; -static const struct dib0090_config tfe8096p_dib0090_config = { +static struct dib0090_config tfe8096p_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -1853,8 +1984,6 @@ .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib8096p_tuner_sleep, - .sleep = dib8096p_tuner_sleep, .freq_offset_khz_uhf = -143, .freq_offset_khz_vhf = -143, @@ -1871,8 +2000,6 @@ .fref_clock_ratio = 1, - .wbd = dib8096p_wbd_table, - .ls_cfg_pad_drv = 0, .data_tx_drv = 0, .low_if = NULL, @@ -1983,15 +2110,15 @@ /* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */ target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; - dib8000_set_wbd_ref(fe, target); + state->dib8000_ops.set_wbd_ref(fe, target); if (dib8096p_get_best_sampling(fe, &adc) == 0) { pll.pll_ratio = adc.pll_loopdiv; pll.pll_prediv = adc.pll_prediv; dib0700_set_i2c_speed(adap->dev, 200); - dib8000_update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0); - dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); + state->dib8000_ops.update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0); + state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); dib0700_set_i2c_speed(adap->dev, 1000); } return 0; @@ -2001,6 +2128,10 @@ { struct dib0700_state *st = adap->dev->priv; u32 fw_version; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib8000_attach, &state->dib8000_ops)) + return -ENODEV; dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); if (fw_version >= 0x10200) @@ -2021,10 +2152,10 @@ msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); + state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); - adap->fe_adap[0].fe = dvb_attach(dib8000_attach, - &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config); + adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, + 0x80, &tfe8096p_dib8000_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -2032,13 +2163,17 @@ static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe8096p_dib0090_config.reset = st->dib8000_ops.tuner_sleep; + tfe8096p_dib0090_config.sleep = st->dib8000_ops.tuner_sleep; + tfe8096p_dib0090_config.wbd = dib8096p_wbd_table; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe8096p_dib0090_config) == NULL) return -ENODEV; - dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib8000_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup; @@ -2479,14 +2614,14 @@ memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); dib0090_pwm_gain_reset(fe); target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; - dib7000p_set_wbd_ref(fe, target); + state->dib7000p_ops.set_wbd_ref(fe, target); if (dib7090p_get_best_sampling(fe, &adc) == 0) { pll.pll_ratio = adc.pll_loopdiv; pll.pll_prediv = adc.pll_prediv; - dib7000p_update_pll(fe, &pll); - dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); + state->dib7000p_ops.update_pll(fe, &pll); + state->dib7000p_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); } return 0; } @@ -2501,14 +2636,17 @@ static int tfe7790p_update_lna(struct dvb_frontend *fe, u16 agc_global) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("update LNA: agc global=%i", agc_global); if (agc_global < 25000) { - dib7000p_set_gpio(fe, 8, 0, 0); - dib7000p_set_agc1_min(fe, 0); + state->dib7000p_ops.set_gpio(fe, 8, 0, 0); + state->dib7000p_ops.set_agc1_min(fe, 0); } else { - dib7000p_set_gpio(fe, 8, 0, 1); - dib7000p_set_agc1_min(fe, 32768); + state->dib7000p_ops.set_gpio(fe, 8, 0, 1); + state->dib7000p_ops.set_agc1_min(fe, 32768); } return 0; @@ -2605,13 +2743,22 @@ }; static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = { - 60000, 15000, - 1, 5, 0, 0, 0, - 0, 0, 1, 1, 2, - (3 << 14) | (1 << 12) | (524 << 0), - (0 << 25) | 0, - 20452225, - 15000000, + .internal = 60000, + .sampling = 15000, + .pll_prediv = 1, + .pll_ratio = 5, + .pll_range = 0, + .pll_reset = 0, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = (0 << 25) | 0, + .timf = 20452225, + .xtal_hz = 15000000, }; static struct dib7000p_config nim7090_dib7000p_config = { @@ -2644,13 +2791,16 @@ static int tfe7090p_pvr_update_lna(struct dvb_frontend *fe, u16 agc_global) { + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + deb_info("TFE7090P-PVR update LNA: agc global=%i", agc_global); if (agc_global < 25000) { - dib7000p_set_gpio(fe, 5, 0, 0); - dib7000p_set_agc1_min(fe, 0); + state->dib7000p_ops.set_gpio(fe, 5, 0, 0); + state->dib7000p_ops.set_agc1_min(fe, 0); } else { - dib7000p_set_gpio(fe, 5, 0, 1); - dib7000p_set_agc1_min(fe, 32768); + state->dib7000p_ops.set_gpio(fe, 5, 0, 1); + state->dib7000p_ops.set_agc1_min(fe, 32768); } return 0; @@ -2714,7 +2864,7 @@ } }; -static const struct dib0090_config nim7090_dib0090_config = { +static struct dib0090_config nim7090_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -2722,14 +2872,10 @@ .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 0, .freq_offset_khz_vhf = 0, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2776,7 +2922,7 @@ .enMpegOutput = 1, }; -static const struct dib0090_config tfe7790p_dib0090_config = { +static struct dib0090_config tfe7790p_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, .io.pll_range = 0, @@ -2784,14 +2930,10 @@ .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 0, .freq_offset_khz_vhf = 0, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2813,7 +2955,7 @@ .force_crystal_mode = 1, }; -static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { +static struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, .io.pll_bypass = 0, @@ -2822,14 +2964,10 @@ .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = 50, .freq_offset_khz_vhf = 70, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2854,14 +2992,10 @@ .io.pll_loopdiv = 6, .io.adc_clock_ratio = 0, .io.pll_int_loop_filt = 0, - .reset = dib7090_tuner_sleep, - .sleep = dib7090_tuner_sleep, .freq_offset_khz_uhf = -50, .freq_offset_khz_vhf = -70, - .get_adc_power = dib7090_get_adc_power, - .clkouttobamse = 1, .analog_output = 0, @@ -2883,6 +3017,11 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(20); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -2895,11 +3034,12 @@ msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -2907,12 +3047,16 @@ static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + nim7090_dib0090_config.reset = st->dib7000p_ops.tuner_sleep, + nim7090_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep, + nim7090_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -2922,6 +3066,10 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* The TFE7090 requires the dib0700 to not be in master mode */ st->disable_streaming_master_mode = 1; @@ -2939,17 +3087,18 @@ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } dib0700_set_i2c_speed(adap->dev, 340); - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); if (adap->fe_adap[0].fe == NULL) return -ENODEV; - dib7090_slave_reset(adap->fe_adap[0].fe); + state->dib7000p_ops.slave_reset(adap->fe_adap[0].fe); return 0; } @@ -2957,19 +3106,24 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *i2c; + struct dib0700_adapter_state *state = adap->priv; if (adap->dev->adapter[0].fe_adap[0].fe == NULL) { err("the master dib7090 has to be initialized first"); return -ENODEV; /* the master device has not been initialized */ } - i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); - if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + + i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); + if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); dib0700_set_i2c_speed(adap->dev, 200); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -2978,12 +3132,16 @@ static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe7090pvr_dib0090_config[0].reset = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[0].sleep = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[0].get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -2993,12 +3151,16 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + tfe7090pvr_dib0090_config[1].reset = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[1].sleep = st->dib7000p_ops.tuner_sleep; + tfe7090pvr_dib0090_config[1].get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -3008,6 +3170,10 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* The TFE7790P requires the dib0700 to not be in master mode */ st->disable_streaming_master_mode = 1; @@ -3024,13 +3190,14 @@ msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &tfe7790p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &tfe7790p_dib7000p_config); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; @@ -3040,13 +3207,18 @@ { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c = - dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe); + + + tfe7790p_dib0090_config.reset = st->dib7000p_ops.tuner_sleep; + tfe7790p_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep; + tfe7790p_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power; if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7790p_dib0090_config) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; @@ -3103,30 +3275,41 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) { + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + stk7070pd_init(adap->dev); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) { - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; + + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int novatd_read_status_override(struct dvb_frontend *fe, - fe_status_t *stat) + enum fe_status *stat) { struct dvb_usb_adapter *adap = fe->dvb->priv; struct dvb_usb_device *dev = adap->dev; @@ -3164,6 +3347,10 @@ { struct dvb_usb_device *dev = adap->dev; struct dib0700_state *st = dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; if (adap->id == 0) { stk7070pd_init(dev); @@ -3173,15 +3360,16 @@ dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0); dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18, + if (state->dib7000p_ops.i2c_enumeration(&dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); + dvb_detach(&state->dib7000p_ops); return -ENODEV; } } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&dev->i2c_adap, adap->id == 0 ? 0x80 : 0x82, &stk7070pd_dib7000p_config[adap->id]); @@ -3291,12 +3479,13 @@ int command, int arg) { struct dvb_usb_adapter *adap = priv; + struct dib0700_adapter_state *state = adap->priv; if (command == XC4000_TUNER_RESET) { /* Reset the tuner */ - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10); - dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1); } else { err("xc4000: unknown tuner callback command: %d\n", command); return -EINVAL; @@ -3337,14 +3526,22 @@ }; static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = { - 60000, 30000, /* internal, sampling */ - 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */ - 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, */ - /* ADClkSrc, modulo */ - (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */ - 39370534, /* ifreq */ - 20452225, /* timf */ - 30000000 /* xtal */ + .internal = 60000, + .sampling = 30000, + .pll_prediv = 1, + .pll_ratio = 8, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 0, + .sad_cfg = (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */ + .ifreq = 39370534, + .timf = 20452225, + .xtal_hz = 30000000 }; /* FIXME: none of these inputs are validated yet */ @@ -3374,6 +3571,10 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; + struct dib0700_adapter_state *state = adap->priv; + + if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) + return -ENODEV; /* Power Supply on */ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); @@ -3397,12 +3598,13 @@ msleep(500); - if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) { + if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) { /* Demodulator not found for some reason? */ + dvb_detach(&state->dib7000p_ops); return -ENODEV; } - adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12, + adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x12, &pctv_340e_config); st->is_dib7000pc = 1; @@ -3420,9 +3622,10 @@ static int xc4000_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; + struct dib0700_adapter_state *state = adap->priv; /* The xc4000 is not on the main i2c bus */ - tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (tun_i2c == NULL) { printk(KERN_ERR "Could not reach tuner i2c bus\n"); @@ -3589,6 +3792,8 @@ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790P) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, /* 80 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) }, + { USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E) }, + { USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E_SE) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -3616,6 +3821,10 @@ } \ } +#define DIB0700_NUM_FRONTENDS(n) \ + .num_frontends = n, \ + .size_of_priv = sizeof(struct dib0700_adapter_state) + struct dvb_usb_device_properties dib0700_devices[] = { { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -3623,7 +3832,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3687,7 +3896,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, @@ -3695,7 +3904,7 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, @@ -3727,7 +3936,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3739,7 +3948,7 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3792,7 +4001,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3837,7 +4046,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3848,7 +4057,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -3919,7 +4127,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3930,7 +4138,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -3965,7 +4172,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3976,9 +4183,8 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3989,16 +4195,23 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, - .num_device_descs = 1, + .num_device_descs = 3, .devices = { { "Hauppauge Nova-TD Stick (52009)", { &dib0700_usb_id_table[35], NULL }, { NULL }, }, + { "PCTV 2002e", + { &dib0700_usb_id_table[81], NULL }, + { NULL }, + }, + { "PCTV 2002e SE", + { &dib0700_usb_id_table[82], NULL }, + { NULL }, + }, }, .rc.core = { @@ -4016,7 +4229,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4027,9 +4240,8 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4040,7 +4252,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -4084,7 +4295,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4095,9 +4306,8 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4108,7 +4318,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -4135,7 +4344,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4146,8 +4355,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4205,15 +4412,13 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = s5h1411_frontend_attach, .tuner_attach = xc5000_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4243,15 +4448,13 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = lgdt3305_frontend_attach, .tuner_attach = mxl5007t_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4271,7 +4474,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4282,8 +4485,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4323,7 +4524,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4334,8 +4535,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4369,7 +4568,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4380,11 +4579,9 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4395,8 +4592,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4422,7 +4617,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4434,8 +4629,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4461,7 +4654,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4473,8 +4666,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4500,7 +4691,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4512,8 +4703,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4539,7 +4728,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4551,8 +4740,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4578,7 +4765,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4590,8 +4777,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4617,7 +4802,7 @@ .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4629,11 +4814,9 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4645,8 +4828,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4672,15 +4853,13 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = pctv340e_frontend_attach, .tuner_attach = xc4000_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4709,7 +4888,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4721,9 +4900,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x03), } }, - - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4749,7 +4925,7 @@ .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4762,9 +4938,6 @@ DIB0700_DEFAULT_STREAMING_CONFIG(0x02), } }, - - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, },