|
@@ -12,6 +12,7 @@
|
|
|
#include "dib7000m.h"
|
|
|
#include "dib7000p.h"
|
|
|
#include "dib8000.h"
|
|
|
+#include "dib9000.h"
|
|
|
#include "mt2060.h"
|
|
|
#include "mt2266.h"
|
|
|
#include "tuner-xc2028.h"
|
|
@@ -29,6 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif
|
|
|
|
|
|
struct dib0700_adapter_state {
|
|
|
int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
|
|
|
+ const struct firmware *frontend_firmware;
|
|
|
};
|
|
|
|
|
|
/* Hauppauge Nova-T 500 (aka Bristol)
|
|
@@ -1243,13 +1245,13 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
|
|
|
static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
|
|
|
u16 pid, int onoff)
|
|
|
{
|
|
|
- return dib8000_pid_filter(adapter->fe, index, pid, onoff);
|
|
|
+ return dib8000_pid_filter(adapter->fe, index, pid, onoff);
|
|
|
}
|
|
|
|
|
|
static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
|
|
|
- int onoff)
|
|
|
+ int onoff)
|
|
|
{
|
|
|
- return dib8000_pid_filter_ctrl(adapter->fe, onoff);
|
|
|
+ return dib8000_pid_filter_ctrl(adapter->fe, onoff);
|
|
|
}
|
|
|
|
|
|
/* STK807x */
|
|
@@ -1321,11 +1323,11 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
|
|
|
|
|
|
/* STK8096GP */
|
|
|
struct dibx000_agc_config dib8090_agc_config[2] = {
|
|
|
- {
|
|
|
+ {
|
|
|
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 */
|
|
|
+ * 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),
|
|
|
|
|
@@ -1362,12 +1364,12 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
|
|
|
51,
|
|
|
|
|
|
0,
|
|
|
- },
|
|
|
- {
|
|
|
+ },
|
|
|
+ {
|
|
|
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 */
|
|
|
+ * 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),
|
|
|
|
|
@@ -1404,159 +1406,1098 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
|
|
|
51,
|
|
|
|
|
|
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,
|
|
|
+ 54000, 13500,
|
|
|
+ 1, 18, 3, 1, 0,
|
|
|
+ 0, 0, 1, 1, 2,
|
|
|
+ (3 << 14) | (1 << 12) | (599 << 0),
|
|
|
+ (0 << 25) | 0,
|
|
|
+ 20199727,
|
|
|
+ 12000000,
|
|
|
};
|
|
|
|
|
|
static int dib8090_get_adc_power(struct dvb_frontend *fe)
|
|
|
{
|
|
|
- return dib8000_get_adc_power(fe, 1);
|
|
|
+ return dib8000_get_adc_power(fe, 1);
|
|
|
+}
|
|
|
+
|
|
|
+static struct dib8000_config dib809x_dib8000_config[2] = {
|
|
|
+ {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+
|
|
|
+ .agc_config_count = 2,
|
|
|
+ .agc = dib8090_agc_config,
|
|
|
+ .agc_control = dib0090_dcc_freq,
|
|
|
+ .pll = &dib8090_pll_config_12mhz,
|
|
|
+ .tuner_is_baseband = 1,
|
|
|
+
|
|
|
+ .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
|
|
|
+ .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
|
|
|
+ .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
|
|
|
+
|
|
|
+ .hostbus_diversity = 1,
|
|
|
+ .div_cfg = 0x31,
|
|
|
+ .output_mode = OUTMODE_MPEG2_FIFO,
|
|
|
+ .drives = 0x2d98,
|
|
|
+ .diversity_delay = 48,
|
|
|
+ .refclksel = 3,
|
|
|
+ },{
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+
|
|
|
+ .agc_config_count = 2,
|
|
|
+ .agc = dib8090_agc_config,
|
|
|
+ .agc_control = dib0090_dcc_freq,
|
|
|
+ .pll = &dib8090_pll_config_12mhz,
|
|
|
+ .tuner_is_baseband = 1,
|
|
|
+
|
|
|
+ .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
|
|
|
+ .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
|
|
|
+ .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
|
|
|
+
|
|
|
+ .hostbus_diversity = 1,
|
|
|
+ .div_cfg = 0x31,
|
|
|
+ .output_mode = OUTMODE_DIVERSITY,
|
|
|
+ .drives = 0x2d08,
|
|
|
+ .diversity_delay = 1,
|
|
|
+ .refclksel = 3,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib0090_wbd_slope dib8090_wbd_table[] = {
|
|
|
+ /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
|
|
|
+ { 120, 0, 500, 0, 500, 4 }, /* CBAND */
|
|
|
+ { 170, 0, 450, 0, 450, 4 }, /* CBAND */
|
|
|
+ { 380, 48, 373, 28, 259, 6 }, /* VHF */
|
|
|
+ { 860, 34, 700, 36, 616, 6 }, /* high UHF */
|
|
|
+ { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib0090_config dib809x_dib0090_config = {
|
|
|
+ .io.pll_bypass = 1,
|
|
|
+ .io.pll_range = 1,
|
|
|
+ .io.pll_prediv = 1,
|
|
|
+ .io.pll_loopdiv = 20,
|
|
|
+ .io.adc_clock_ratio = 8,
|
|
|
+ .io.pll_int_loop_filt = 0,
|
|
|
+ .io.clock_khz = 12000,
|
|
|
+ .reset = dib80xx_tuner_reset,
|
|
|
+ .sleep = dib80xx_tuner_sleep,
|
|
|
+ .clkouttobamse = 1,
|
|
|
+ .analog_output = 1,
|
|
|
+ .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
|
|
|
+ .use_pwm_agc = 1,
|
|
|
+ .clkoutdrive = 1,
|
|
|
+ .get_adc_power = dib8090_get_adc_power,
|
|
|
+ .freq_offset_khz_uhf = -63,
|
|
|
+ .freq_offset_khz_vhf = -143,
|
|
|
+ .wbd = dib8090_wbd_table,
|
|
|
+ .fref_clock_ratio = 6,
|
|
|
+};
|
|
|
+
|
|
|
+static int dib8096_set_param_override(struct dvb_frontend *fe,
|
|
|
+ struct dvb_frontend_parameters *fep)
|
|
|
+{
|
|
|
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
|
|
|
+ u16 target;
|
|
|
+ int ret = 0;
|
|
|
+ enum frontend_tune_state tune_state = CT_SHUTDOWN;
|
|
|
+ u16 ltgain, rf_gain_limit;
|
|
|
+
|
|
|
+ ret = state->set_param_save(fe, fep);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
|
|
|
+ dib8000_set_wbd_ref(fe, target);
|
|
|
+
|
|
|
+
|
|
|
+ if (band == BAND_CBAND) {
|
|
|
+ deb_info("tuning in CBAND - soft-AGC startup\n");
|
|
|
+ /* TODO specific wbd target for dib0090 - needed for startup ? */
|
|
|
+ dib0090_set_tune_state(fe, CT_AGC_START);
|
|
|
+ do {
|
|
|
+ ret = dib0090_gain_control(fe);
|
|
|
+ msleep(ret);
|
|
|
+ tune_state = dib0090_get_tune_state(fe);
|
|
|
+ if (tune_state == CT_AGC_STEP_0)
|
|
|
+ dib8000_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 == 0)
|
|
|
+ dib8000_set_gpio(fe, 6, 0, 0);
|
|
|
+ }
|
|
|
+ } while (tune_state < CT_AGC_STOP);
|
|
|
+ dib0090_pwm_gain_reset(fe);
|
|
|
+ dib8000_pwm_agc_reset(fe);
|
|
|
+ dib8000_set_tune_state(fe, CT_DEMOD_START);
|
|
|
+ } else {
|
|
|
+ deb_info("not tuning in CBAND - standard AGC startup\n");
|
|
|
+ dib0090_pwm_gain_reset(fe);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+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, DIBX000_I2C_INTERFACE_TUNER, 1);
|
|
|
+
|
|
|
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
+ adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
+
|
|
|
+ dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
+
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
|
|
|
+
|
|
|
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
|
|
|
+
|
|
|
+ return adap->fe == NULL ? -ENODEV : 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dib0700_adapter_state *st = adap->priv;
|
|
|
+ struct i2c_adapter *tun_i2c;
|
|
|
+ struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1);
|
|
|
+
|
|
|
+ if (fe_slave) {
|
|
|
+ tun_i2c = dib8000_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->dvb;
|
|
|
+ fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
|
|
|
+ }
|
|
|
+ tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
|
|
|
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
+ adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dvb_frontend *fe_slave;
|
|
|
+
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
+ msleep(1000);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
+
|
|
|
+ dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
+
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80);
|
|
|
+
|
|
|
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
|
|
|
+ if (adap->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, fe_slave);
|
|
|
+
|
|
|
+ return fe_slave == NULL ? -ENODEV : 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* STK9090M */
|
|
|
+static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
|
|
|
+{
|
|
|
+ return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff);
|
|
|
+}
|
|
|
+
|
|
|
+static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
|
|
|
+{
|
|
|
+ return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff);
|
|
|
+}
|
|
|
+
|
|
|
+static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
|
|
|
+{
|
|
|
+ return dib9000_set_gpio(fe, 5, 0, !onoff);
|
|
|
+}
|
|
|
+
|
|
|
+static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
|
|
|
+{
|
|
|
+ return dib9000_set_gpio(fe, 0, 0, onoff);
|
|
|
+}
|
|
|
+
|
|
|
+static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
|
|
|
+{
|
|
|
+ u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
|
|
|
+ u8 rb[2];
|
|
|
+ struct i2c_msg msg[2] = {
|
|
|
+ {.addr = 0x1e >> 1,.flags = 0,.buf = wb,.len = 2},
|
|
|
+ {.addr = 0x1e >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
|
|
|
+ };
|
|
|
+ u8 index_data;
|
|
|
+
|
|
|
+ dibx000_i2c_set_speed(i2c, 250);
|
|
|
+
|
|
|
+ if (i2c_transfer(i2c, msg, 2) != 2)
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ switch (rb[0] << 8 | rb[1]) {
|
|
|
+ case 0:
|
|
|
+ deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
|
|
|
+ return -EIO;
|
|
|
+ case 1:
|
|
|
+ deb_info("Found DiB0170 rev2");
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ deb_info("Found DiB0190 rev2");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ deb_info("DiB01x0 not found");
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (index_data = 0; index_data < len; index_data += 2) {
|
|
|
+ wb[2] = (data[index_data + 1] >> 8) & 0xff;
|
|
|
+ wb[3] = (data[index_data + 1]) & 0xff;
|
|
|
+
|
|
|
+ if (data[index_data] == 0) {
|
|
|
+ wb[0] = (data[index_data] >> 8) & 0xff;
|
|
|
+ wb[1] = (data[index_data]) & 0xff;
|
|
|
+ msg[0].len = 2;
|
|
|
+ if (i2c_transfer(i2c, msg, 2) != 2)
|
|
|
+ return -EIO;
|
|
|
+ wb[2] |= rb[0];
|
|
|
+ wb[3] |= rb[1] & ~(3 << 4);
|
|
|
+ }
|
|
|
+
|
|
|
+ wb[0] = (data[index_data ] >> 8)&0xff;
|
|
|
+ wb[1] = (data[index_data ] )&0xff;
|
|
|
+ msg[0].len = 4;
|
|
|
+ if (i2c_transfer(i2c, &msg[0], 1) != 1)
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct dib9000_config stk9090m_config = {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .output_mode = OUTMODE_MPEG2_FIFO,
|
|
|
+ .vcxo_timer = 279620,
|
|
|
+ .timing_frequency = 20452225,
|
|
|
+ .demod_clock_khz = 60000,
|
|
|
+ .xtal_clock_khz = 30000,
|
|
|
+ .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
|
|
|
+ .subband = {
|
|
|
+ 2,
|
|
|
+ {
|
|
|
+ { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
|
|
|
+ { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
|
|
|
+ { 0 },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ .gpio_function = {
|
|
|
+ { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
|
|
|
+ { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib9000_config nim9090md_config[2] = {
|
|
|
+ {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .output_mode = OUTMODE_MPEG2_FIFO,
|
|
|
+ .vcxo_timer = 279620,
|
|
|
+ .timing_frequency = 20452225,
|
|
|
+ .demod_clock_khz = 60000,
|
|
|
+ .xtal_clock_khz = 30000,
|
|
|
+ .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
|
|
|
+ }, {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .output_mode = OUTMODE_DIVERSITY,
|
|
|
+ .vcxo_timer = 279620,
|
|
|
+ .timing_frequency = 20452225,
|
|
|
+ .demod_clock_khz = 60000,
|
|
|
+ .xtal_clock_khz = 30000,
|
|
|
+ .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
|
|
|
+ .subband = {
|
|
|
+ 2,
|
|
|
+ {
|
|
|
+ { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
|
|
|
+ { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
|
|
|
+ { 0 },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ .gpio_function = {
|
|
|
+ { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
|
|
|
+ { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
|
|
|
+ },
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib0090_config dib9090_dib0090_config = {
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 1,
|
|
|
+ .io.pll_prediv = 1,
|
|
|
+ .io.pll_loopdiv = 8,
|
|
|
+ .io.adc_clock_ratio = 8,
|
|
|
+ .io.pll_int_loop_filt = 0,
|
|
|
+ .io.clock_khz = 30000,
|
|
|
+ .reset = dib90x0_tuner_reset,
|
|
|
+ .sleep = dib90x0_tuner_sleep,
|
|
|
+ .clkouttobamse = 0,
|
|
|
+ .analog_output = 0,
|
|
|
+ .use_pwm_agc = 0,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+ .freq_offset_khz_uhf = 0,
|
|
|
+ .freq_offset_khz_vhf = 0,
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib0090_config nim9090md_dib0090_config[2] = {
|
|
|
+ {
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 1,
|
|
|
+ .io.pll_prediv = 1,
|
|
|
+ .io.pll_loopdiv = 8,
|
|
|
+ .io.adc_clock_ratio = 8,
|
|
|
+ .io.pll_int_loop_filt = 0,
|
|
|
+ .io.clock_khz = 30000,
|
|
|
+ .reset = dib90x0_tuner_reset,
|
|
|
+ .sleep = dib90x0_tuner_sleep,
|
|
|
+ .clkouttobamse = 1,
|
|
|
+ .analog_output = 0,
|
|
|
+ .use_pwm_agc = 0,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+ .freq_offset_khz_uhf = 0,
|
|
|
+ .freq_offset_khz_vhf = 0,
|
|
|
+ },{
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 1,
|
|
|
+ .io.pll_prediv = 1,
|
|
|
+ .io.pll_loopdiv = 8,
|
|
|
+ .io.adc_clock_ratio = 8,
|
|
|
+ .io.pll_int_loop_filt = 0,
|
|
|
+ .io.clock_khz = 30000,
|
|
|
+ .reset = dib90x0_tuner_reset,
|
|
|
+ .sleep = dib90x0_tuner_sleep,
|
|
|
+ .clkouttobamse = 0,
|
|
|
+ .analog_output = 0,
|
|
|
+ .use_pwm_agc = 0,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+ .freq_offset_khz_uhf = 0,
|
|
|
+ .freq_offset_khz_vhf = 0,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ struct dib0700_state *st = adap->dev->priv;
|
|
|
+ u32 fw_version;
|
|
|
+
|
|
|
+ /* Make use of the new i2c functions from FW 1.20 */
|
|
|
+ dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
|
|
|
+ if (fw_version >= 0x10200)
|
|
|
+ st->fw_use_new_i2c_api = 1;
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 340);
|
|
|
+
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
+
|
|
|
+ dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
+
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
|
|
|
+
|
|
|
+ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
|
|
|
+ deb_info("%s: Upload failed. (file not found?)\n", __func__);
|
|
|
+ return -ENODEV;
|
|
|
+ } else {
|
|
|
+ deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
|
|
|
+ }
|
|
|
+ stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
|
|
|
+ stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
|
|
|
+
|
|
|
+ adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
|
|
|
+
|
|
|
+ return adap->fe == NULL ? -ENODEV : 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe);
|
|
|
+ u16 data_dib190[10] = {
|
|
|
+ 1, 0x1374,
|
|
|
+ 2, 0x01a2,
|
|
|
+ 7, 0x0020,
|
|
|
+ 0, 0x00ef,
|
|
|
+ 8, 0x0486,
|
|
|
+ };
|
|
|
+
|
|
|
+ if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
|
|
|
+ if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
|
|
|
+ return -ENODEV;
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 2000);
|
|
|
+ if (dib9000_firmware_post_pll_init(adap->fe) < 0)
|
|
|
+ return -ENODEV;
|
|
|
+ release_firmware(state->frontend_firmware);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ struct dib0700_state *st = adap->dev->priv;
|
|
|
+ struct i2c_adapter *i2c;
|
|
|
+ struct dvb_frontend *fe_slave;
|
|
|
+ u32 fw_version;
|
|
|
+
|
|
|
+ /* Make use of the new i2c functions from FW 1.20 */
|
|
|
+ dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
|
|
|
+ if (fw_version >= 0x10200)
|
|
|
+ st->fw_use_new_i2c_api = 1;
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 340);
|
|
|
+
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
+
|
|
|
+ dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
+
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
+
|
|
|
+ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
|
|
|
+ deb_info("%s: Upload failed. (file not found?)\n", __func__);
|
|
|
+ return -EIO;
|
|
|
+ } else {
|
|
|
+ deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
|
|
|
+ }
|
|
|
+ nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
|
|
|
+ nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
|
|
|
+ nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
|
|
|
+ nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
|
|
|
+
|
|
|
+ dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
|
|
|
+ adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
|
|
|
+
|
|
|
+ if (adap->fe == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
|
|
|
+ dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
|
|
|
+
|
|
|
+ fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
|
|
|
+ dib9000_set_slave_frontend(adap->fe, fe_slave);
|
|
|
+
|
|
|
+ return fe_slave == NULL ? -ENODEV : 0;
|
|
|
}
|
|
|
|
|
|
-static struct dib8000_config dib809x_dib8000_config = {
|
|
|
- .output_mpeg2_in_188_bytes = 1,
|
|
|
-
|
|
|
- .agc_config_count = 2,
|
|
|
- .agc = dib8090_agc_config,
|
|
|
- .agc_control = dib0090_dcc_freq,
|
|
|
- .pll = &dib8090_pll_config_12mhz,
|
|
|
- .tuner_is_baseband = 1,
|
|
|
-
|
|
|
- .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
|
|
|
- .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
|
|
|
- .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
|
|
|
-
|
|
|
- .hostbus_diversity = 1,
|
|
|
- .div_cfg = 0x31,
|
|
|
- .output_mode = OUTMODE_MPEG2_FIFO,
|
|
|
- .drives = 0x2d98,
|
|
|
- .diversity_delay = 144,
|
|
|
- .refclksel = 3,
|
|
|
+static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ struct i2c_adapter *i2c;
|
|
|
+ struct dvb_frontend *fe_slave;
|
|
|
+ u16 data_dib190[10] = {
|
|
|
+ 1, 0x5374,
|
|
|
+ 2, 0x01ae,
|
|
|
+ 7, 0x0020,
|
|
|
+ 0, 0x00ef,
|
|
|
+ 8, 0x0406,
|
|
|
+ };
|
|
|
+ i2c = dib9000_get_tuner_interface(adap->fe);
|
|
|
+ if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
|
|
|
+ if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
|
|
|
+ return -ENODEV;
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 2000);
|
|
|
+ if (dib9000_firmware_post_pll_init(adap->fe) < 0)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ fe_slave = dib9000_get_slave_frontend(adap->fe, 1);
|
|
|
+ if (fe_slave != NULL) {
|
|
|
+ i2c = dib9000_get_component_bus_interface(adap->fe);
|
|
|
+ dib9000_set_i2c_adapter(fe_slave, i2c);
|
|
|
+
|
|
|
+ i2c = dib9000_get_tuner_interface(fe_slave);
|
|
|
+ if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ fe_slave->dvb = adap->fe->dvb;
|
|
|
+ dib9000_fw_set_component_bus_speed(adap->fe, 2000);
|
|
|
+ if (dib9000_firmware_post_pll_init(fe_slave) < 0)
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ release_firmware(state->frontend_firmware);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* NIM7090 */
|
|
|
+struct dib7090p_best_adc {
|
|
|
+ u32 timf;
|
|
|
+ u32 pll_loopdiv;
|
|
|
+ u32 pll_prediv;
|
|
|
+};
|
|
|
+
|
|
|
+static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
|
|
|
+{
|
|
|
+ u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
|
|
|
+
|
|
|
+ u16 xtal = 12000;
|
|
|
+ u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
|
|
|
+ u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
|
|
|
+ u32 fdem_max = 76000;
|
|
|
+ u32 fdem_min = 69500;
|
|
|
+ u32 fcp = 0, fs = 0, fdem = 0;
|
|
|
+ u32 harmonic_id = 0;
|
|
|
+
|
|
|
+ adc->pll_loopdiv = loopdiv;
|
|
|
+ adc->pll_prediv = prediv;
|
|
|
+ adc->timf = 0;
|
|
|
+
|
|
|
+ deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
|
|
|
+
|
|
|
+ /* Find Min and Max prediv */
|
|
|
+ while((xtal/max_prediv) >= fcp_min)
|
|
|
+ max_prediv++;
|
|
|
+
|
|
|
+ max_prediv--;
|
|
|
+ min_prediv = max_prediv;
|
|
|
+ while((xtal/min_prediv) <= fcp_max) {
|
|
|
+ min_prediv--;
|
|
|
+ if(min_prediv == 1)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
|
|
|
+
|
|
|
+ min_prediv = 2;
|
|
|
+
|
|
|
+ for(prediv = min_prediv ; prediv < max_prediv; prediv ++) {
|
|
|
+ fcp = xtal / prediv;
|
|
|
+ if(fcp > fcp_min && fcp < fcp_max) {
|
|
|
+ for(loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
|
|
|
+ fdem = ((xtal/prediv) * loopdiv);
|
|
|
+ fs = fdem / 4;
|
|
|
+ /* test min/max system restrictions */
|
|
|
+
|
|
|
+ if((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
|
|
|
+ spur = 0;
|
|
|
+ /* test fs harmonics positions */
|
|
|
+ for(harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
|
|
|
+ if(((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
|
|
|
+ spur = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!spur) {
|
|
|
+ adc->pll_loopdiv = loopdiv;
|
|
|
+ adc->pll_prediv = prediv;
|
|
|
+ adc->timf = 2396745143UL/fdem*(1<<9);
|
|
|
+ adc->timf+= ((2396745143UL%fdem)<< 9)/fdem;
|
|
|
+ deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!spur)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(adc->pll_loopdiv == 0 && adc->pll_prediv == 0) {
|
|
|
+ return -EINVAL;
|
|
|
+ } else
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
|
|
|
+{
|
|
|
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
|
+ struct dib0700_adapter_state *state = adap->priv;
|
|
|
+ struct dibx000_bandwidth_config pll;
|
|
|
+ u16 target;
|
|
|
+ struct dib7090p_best_adc adc;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = state->set_param_save(fe, fep);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
|
|
|
+ dib0090_pwm_gain_reset(fe);
|
|
|
+ target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2;
|
|
|
+ dib7000p_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);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct dib0090_wbd_slope dib7090_wbd_table[] = {
|
|
|
+ { 380, 81, 850, 64, 540 ,4},
|
|
|
+ { 860, 51, 866, 21, 375 ,4},
|
|
|
+ {1700, 0, 250, 0, 100, 6}, //LBAND Predefinition , NOT tested Yet
|
|
|
+ {2600, 0, 250, 0, 100, 6}, //SBAND Predefinition , NOT tested Yet
|
|
|
+ { 0xFFFF, 0, 0, 0, 0 ,0},
|
|
|
};
|
|
|
|
|
|
-static struct dib0090_config dib809x_dib0090_config = {
|
|
|
- .io.pll_bypass = 1,
|
|
|
- .io.pll_range = 1,
|
|
|
- .io.pll_prediv = 1,
|
|
|
- .io.pll_loopdiv = 20,
|
|
|
- .io.adc_clock_ratio = 8,
|
|
|
- .io.pll_int_loop_filt = 0,
|
|
|
- .io.clock_khz = 12000,
|
|
|
- .reset = dib80xx_tuner_reset,
|
|
|
- .sleep = dib80xx_tuner_sleep,
|
|
|
- .clkouttobamse = 1,
|
|
|
- .analog_output = 1,
|
|
|
- .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
|
|
|
- .wbd_vhf_offset = 100,
|
|
|
- .wbd_cband_offset = 450,
|
|
|
- .use_pwm_agc = 1,
|
|
|
- .clkoutdrive = 1,
|
|
|
- .get_adc_power = dib8090_get_adc_power,
|
|
|
- .freq_offset_khz_uhf = 0,
|
|
|
- .freq_offset_khz_vhf = -143,
|
|
|
-};
|
|
|
+struct dibx000_agc_config dib7090_agc_config[2] = {
|
|
|
+ {
|
|
|
+ .band_caps = BAND_UHF,
|
|
|
+ /* 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 */
|
|
|
+ .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
|
|
|
+
|
|
|
+ .inv_gain = 687,// inv_gain = 1/ 95.4dB // no boost, lower gain due to ramp quantification
|
|
|
+ .time_stabiliz = 10, // time_stabiliz
|
|
|
+
|
|
|
+ .alpha_level = 0, // alpha_level
|
|
|
+ .thlock = 118, // thlock
|
|
|
+
|
|
|
+ .wbd_inv = 0, // wbd_inv
|
|
|
+ .wbd_ref = 1200, // wbd_ref
|
|
|
+ .wbd_sel = 3, // wbd_sel
|
|
|
+ .wbd_alpha = 5, // wbd_alpha
|
|
|
+
|
|
|
+ .agc1_max = 65535, // agc1_max
|
|
|
+ .agc1_min = 0, // agc1_min
|
|
|
+
|
|
|
+ .agc2_max = 65535, // agc2_max
|
|
|
+ .agc2_min = 0, // agc2_min
|
|
|
+
|
|
|
+ .agc1_pt1 = 0, // agc1_pt1
|
|
|
+ .agc1_pt2 = 32, // agc1_pt2
|
|
|
+ .agc1_pt3 = 114, // agc1_pt3 // 40.4dB
|
|
|
+ .agc1_slope1 = 143, // agc1_slope1
|
|
|
+ .agc1_slope2 = 144, // agc1_slope2
|
|
|
+ .agc2_pt1 = 114, // agc2_pt1
|
|
|
+ .agc2_pt2 = 227, // agc2_pt2
|
|
|
+ .agc2_slope1 = 116, // agc2_slope1
|
|
|
+ .agc2_slope2 = 117, // agc2_slope2
|
|
|
+
|
|
|
+ .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB
|
|
|
+ .alpha_exp = 0, // alpha_exp
|
|
|
+ .beta_mant = 20, // beta_mant
|
|
|
+ .beta_exp = 59, // beta_exp
|
|
|
+
|
|
|
+ .perform_agc_softsplit = 0, // perform_agc_softsplit
|
|
|
+ } , {
|
|
|
+ .band_caps = BAND_FM | BAND_VHF | 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 */
|
|
|
+ .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
|
|
|
+
|
|
|
+ .inv_gain = 732,// inv_gain = 1/ 89.5dB // no boost, lower gain due to ramp quantification
|
|
|
+ .time_stabiliz = 10, // time_stabiliz
|
|
|
+
|
|
|
+ .alpha_level = 0, // alpha_level
|
|
|
+ .thlock = 118, // thlock
|
|
|
+
|
|
|
+ .wbd_inv = 0, // wbd_inv
|
|
|
+ .wbd_ref = 1200, // wbd_ref
|
|
|
+ .wbd_sel = 3, // wbd_sel
|
|
|
+ .wbd_alpha = 5, // wbd_alpha
|
|
|
+
|
|
|
+ .agc1_max = 65535, // agc1_max : 1
|
|
|
+ .agc1_min = 0, // agc1_min
|
|
|
+
|
|
|
+ .agc2_max = 65535, // agc2_max
|
|
|
+ .agc2_min = 0, // agc2_min
|
|
|
+
|
|
|
+ .agc1_pt1 = 0, // agc1_pt1
|
|
|
+ .agc1_pt2 = 0, // agc1_pt2
|
|
|
+ .agc1_pt3 = 98, // agc1_pt3 // 34.5dB CBAND P1G + 55dB BB boost = 89.5dB
|
|
|
+ .agc1_slope1 = 0, // agc1_slope1
|
|
|
+ .agc1_slope2 = 167, // agc1_slope2 = Dy/Dx * 2**6 * 2**8 = 1/98 * 2**6 *2**8 : Dy = 1
|
|
|
+ .agc1_pt1 = 98, // agc2_pt1
|
|
|
+ .agc2_pt2 = 255, // agc2_pt2
|
|
|
+ .agc2_slope1 = 104, // agc2_slope1 = Dy/Dx * 2**6 * 2**8 = 1/(255-98) * 2**6 *2**8
|
|
|
+ .agc2_slope2 = 0, // agc2_slope2
|
|
|
+
|
|
|
+ .alpha_mant = 18, // alpha_mant // 5Hz with 95.4dB
|
|
|
+ .alpha_exp = 0, // alpha_exp
|
|
|
+ .beta_mant = 20, // beta_mant
|
|
|
+ .beta_exp = 59, // beta_exp
|
|
|
+
|
|
|
+ .perform_agc_softsplit = 0, // perform_agc_softsplit
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
|
|
|
+ 60000, 15000, // internal, sampling
|
|
|
+ 1, 5, 0, 0, 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) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
|
|
|
+ (0 << 25) | 0, // ifreq = 0.000000 MHz
|
|
|
+ 20452225, // timf
|
|
|
+ 15000000, // xtal_hz
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib7000p_config nim7090_dib7000p_config = {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .hostbus_diversity = 1,
|
|
|
+ .tuner_is_baseband = 1,
|
|
|
+ .update_lna = NULL,
|
|
|
+
|
|
|
+ .agc_config_count = 2,
|
|
|
+ .agc = dib7090_agc_config,
|
|
|
+
|
|
|
+ .bw = &dib7090_clock_config_12_mhz,
|
|
|
+
|
|
|
+ .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
|
+ .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
|
+ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
+
|
|
|
+ .pwm_freq_div = 0,
|
|
|
+
|
|
|
+ .agc_control = dib7090_agc_restart,
|
|
|
+
|
|
|
+ .spur_protect = 0,
|
|
|
+ .disable_sample_and_hold = 0,
|
|
|
+ .enable_current_mirror = 0,
|
|
|
+ .diversity_delay = 0,
|
|
|
+
|
|
|
+ .output_mode = OUTMODE_MPEG2_FIFO,
|
|
|
+ .enMpegOutput = 1,
|
|
|
+};
|
|
|
+
|
|
|
+static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
|
|
|
+ {
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .hostbus_diversity = 1,
|
|
|
+ .tuner_is_baseband = 1,
|
|
|
+ .update_lna = NULL,
|
|
|
+
|
|
|
+ .agc_config_count = 2,
|
|
|
+ .agc = dib7090_agc_config,
|
|
|
+
|
|
|
+ .bw = &dib7090_clock_config_12_mhz,
|
|
|
+
|
|
|
+ .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
|
+ .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
|
+ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
+
|
|
|
+ .pwm_freq_div = 0,
|
|
|
+
|
|
|
+ .agc_control = dib7090_agc_restart,
|
|
|
+
|
|
|
+ .spur_protect = 0,
|
|
|
+ .disable_sample_and_hold = 0,
|
|
|
+ .enable_current_mirror = 0,
|
|
|
+ .diversity_delay = 0,
|
|
|
+
|
|
|
+ .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
|
|
|
+ .default_i2c_addr = 0x90,
|
|
|
+ .enMpegOutput = 1,
|
|
|
+ },{
|
|
|
+ .output_mpeg2_in_188_bytes = 1,
|
|
|
+ .hostbus_diversity = 1,
|
|
|
+ .tuner_is_baseband = 1,
|
|
|
+ .update_lna = NULL,
|
|
|
+
|
|
|
+ .agc_config_count = 2,
|
|
|
+ .agc = dib7090_agc_config,
|
|
|
+
|
|
|
+ .bw = &dib7090_clock_config_12_mhz,
|
|
|
+
|
|
|
+ .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
|
+ .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
|
+ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
+
|
|
|
+ .pwm_freq_div = 0,
|
|
|
+
|
|
|
+ .agc_control = dib7090_agc_restart,
|
|
|
+
|
|
|
+ .spur_protect = 0,
|
|
|
+ .disable_sample_and_hold = 0,
|
|
|
+ .enable_current_mirror = 0,
|
|
|
+ .diversity_delay = 0,
|
|
|
+
|
|
|
+ .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
|
|
|
+ .default_i2c_addr = 0x92,
|
|
|
+ .enMpegOutput = 0,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static const struct dib0090_config nim7090_dib0090_config = {
|
|
|
+ .io.clock_khz = 12000,
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 0,
|
|
|
+ .io.pll_prediv = 3,
|
|
|
+ .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,
|
|
|
+
|
|
|
+ .wbd_vhf_offset = 0,
|
|
|
+ .wbd_cband_offset = 0,
|
|
|
+ .use_pwm_agc = 1,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+
|
|
|
+ .fref_clock_ratio = 0,
|
|
|
+
|
|
|
+ .wbd = dib7090_wbd_table,
|
|
|
+
|
|
|
+ .ls_cfg_pad_drv = 0,
|
|
|
+ .data_tx_drv = 0,
|
|
|
+ .low_if = NULL,
|
|
|
+ .in_soc = 1,
|
|
|
+};
|
|
|
+
|
|
|
+static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
|
|
|
+ {
|
|
|
+ .io.clock_khz = 12000,
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 0,
|
|
|
+ .io.pll_prediv = 3,
|
|
|
+ .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,
|
|
|
+
|
|
|
+ .wbd_vhf_offset = 0,
|
|
|
+ .wbd_cband_offset = 0,
|
|
|
+ .use_pwm_agc = 1,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+
|
|
|
+ .fref_clock_ratio = 0,
|
|
|
+
|
|
|
+ .wbd = dib7090_wbd_table,
|
|
|
+
|
|
|
+ .ls_cfg_pad_drv = 0,
|
|
|
+ .data_tx_drv = 0,
|
|
|
+ .low_if = NULL,
|
|
|
+ .in_soc = 1,
|
|
|
+ },{
|
|
|
+ .io.clock_khz = 12000,
|
|
|
+ .io.pll_bypass = 0,
|
|
|
+ .io.pll_range = 0,
|
|
|
+ .io.pll_prediv = 3,
|
|
|
+ .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,
|
|
|
+
|
|
|
+ .wbd_vhf_offset = 0,
|
|
|
+ .wbd_cband_offset = 0,
|
|
|
+ .use_pwm_agc = 1,
|
|
|
+ .clkoutdrive = 0,
|
|
|
+
|
|
|
+ .fref_clock_ratio = 0,
|
|
|
+
|
|
|
+ .wbd = dib7090_wbd_table,
|
|
|
+
|
|
|
+ .ls_cfg_pad_drv = 0,
|
|
|
+ .data_tx_drv = 0,
|
|
|
+ .low_if = NULL,
|
|
|
+ .in_soc = 1,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
+
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
+ msleep(10);
|
|
|
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
|
|
-static int dib8096_set_param_override(struct dvb_frontend *fe,
|
|
|
- struct dvb_frontend_parameters *fep)
|
|
|
-{
|
|
|
- struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
|
- struct dib0700_adapter_state *state = adap->priv;
|
|
|
- u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
|
|
|
- u16 offset;
|
|
|
- int ret = 0;
|
|
|
- enum frontend_tune_state tune_state = CT_SHUTDOWN;
|
|
|
- u16 ltgain, rf_gain_limit;
|
|
|
-
|
|
|
- ret = state->set_param_save(fe, fep);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
-
|
|
|
- switch (band) {
|
|
|
- case BAND_VHF:
|
|
|
- offset = 100;
|
|
|
- break;
|
|
|
- case BAND_UHF:
|
|
|
- offset = 550;
|
|
|
- break;
|
|
|
- default:
|
|
|
- offset = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
|
|
|
- dib8000_set_wbd_ref(fe, offset);
|
|
|
-
|
|
|
-
|
|
|
- if (band == BAND_CBAND) {
|
|
|
- deb_info("tuning in CBAND - soft-AGC startup\n");
|
|
|
- /* TODO specific wbd target for dib0090 - needed for startup ? */
|
|
|
- dib0090_set_tune_state(fe, CT_AGC_START);
|
|
|
- do {
|
|
|
- ret = dib0090_gain_control(fe);
|
|
|
- msleep(ret);
|
|
|
- tune_state = dib0090_get_tune_state(fe);
|
|
|
- if (tune_state == CT_AGC_STEP_0)
|
|
|
- dib8000_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 == 0)
|
|
|
- dib8000_set_gpio(fe, 6, 0, 0);
|
|
|
- }
|
|
|
- } while (tune_state < CT_AGC_STOP);
|
|
|
- dib0090_pwm_gain_reset(fe);
|
|
|
- dib8000_pwm_agc_reset(fe);
|
|
|
- dib8000_set_tune_state(fe, CT_DEMOD_START);
|
|
|
- } else {
|
|
|
- deb_info("not tuning in CBAND - standard AGC startup\n");
|
|
|
- dib0090_pwm_gain_reset(fe);
|
|
|
- }
|
|
|
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
|
|
|
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
|
|
|
|
|
|
- return 0;
|
|
|
+ return adap->fe == NULL ? -ENODEV : 0;
|
|
|
}
|
|
|
|
|
|
-static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
|
|
|
+static int nim7090_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, DIBX000_I2C_INTERFACE_TUNER, 1);
|
|
|
+ struct dib0700_adapter_state *st = adap->priv;
|
|
|
+ struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
|
|
|
+
|
|
|
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
|
|
|
- return -ENODEV;
|
|
|
+ dib7000p_set_gpio(adap->fe, 8, 0, 1);
|
|
|
|
|
|
- st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
- adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
|
|
|
- return 0;
|
|
|
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
+ adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
|
|
|
+static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
|
|
|
{
|
|
|
+ struct dib0700_state *st = adap->dev->priv;
|
|
|
+
|
|
|
+ /* The TFE7090 requires the dib0700 to not be in master mode */
|
|
|
+ st->disable_streaming_master_mode = 1;
|
|
|
+
|
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
|
msleep(10);
|
|
|
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
|
|
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
|
|
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
|
-
|
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
|
|
|
- dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
-
|
|
|
msleep(10);
|
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
msleep(10);
|
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
|
|
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
|
|
|
+ /* 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__);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
|
|
|
- adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 340);
|
|
|
+ adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
|
|
|
|
|
|
- return adap->fe == NULL ? -ENODEV : 0;
|
|
|
+ dib7090_slave_reset(adap->fe);
|
|
|
+
|
|
|
+ if (adap->fe == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
|
|
|
+{
|
|
|
+ struct i2c_adapter *i2c;
|
|
|
+
|
|
|
+ if (adap->dev->adapter[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, 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__);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+
|
|
|
+ adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
|
|
|
+ dib0700_set_i2c_speed(adap->dev, 200);
|
|
|
+
|
|
|
+ return adap->fe == NULL ? -ENODEV : 0;
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+
|
|
|
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ dib7000p_set_gpio(adap->fe, 8, 0, 1);
|
|
|
+
|
|
|
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
+ adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+
|
|
|
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ dib7000p_set_gpio(adap->fe, 8, 0, 1);
|
|
|
+
|
|
|
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
|
|
+ adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/* STK7070PD */
|
|
@@ -1856,6 +2797,11 @@ struct usb_device_id dib0700_usb_id_table[] = {
|
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
|
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
|
|
|
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
|
|
|
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
|
|
|
+/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
|
|
|
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
|
|
|
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
|
|
|
+ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
|
|
|
{ 0 } /* Terminating entry */
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
|
|
@@ -2609,6 +3555,205 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|
|
},
|
|
|
},
|
|
|
|
|
|
+ .rc.core = {
|
|
|
+ .rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
+ .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
|
+ .module_name = "dib0700",
|
|
|
+ .rc_query = dib0700_rc_query_old_firmware,
|
|
|
+ .allowed_protos = RC_TYPE_RC5 |
|
|
|
+ RC_TYPE_RC6 |
|
|
|
+ RC_TYPE_NEC,
|
|
|
+ .change_protocol = dib0700_change_protocol,
|
|
|
+ },
|
|
|
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
+ .num_adapters = 1,
|
|
|
+ .adapter = {
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = dib90x0_pid_filter,
|
|
|
+ .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
|
|
|
+ .frontend_attach = stk9090m_frontend_attach,
|
|
|
+ .tuner_attach = dib9090_tuner_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .num_device_descs = 1,
|
|
|
+ .devices = {
|
|
|
+ { "DiBcom STK9090M reference design",
|
|
|
+ { &dib0700_usb_id_table[69], NULL },
|
|
|
+ { NULL },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .rc.core = {
|
|
|
+ .rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
+ .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
|
+ .module_name = "dib0700",
|
|
|
+ .rc_query = dib0700_rc_query_old_firmware,
|
|
|
+ .allowed_protos = RC_TYPE_RC5 |
|
|
|
+ RC_TYPE_RC6 |
|
|
|
+ RC_TYPE_NEC,
|
|
|
+ .change_protocol = dib0700_change_protocol,
|
|
|
+ },
|
|
|
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
+ .num_adapters = 1,
|
|
|
+ .adapter = {
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = stk80xx_pid_filter,
|
|
|
+ .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
|
+ .frontend_attach = nim8096md_frontend_attach,
|
|
|
+ .tuner_attach = nim8096md_tuner_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .num_device_descs = 1,
|
|
|
+ .devices = {
|
|
|
+ { "DiBcom NIM8096MD reference design",
|
|
|
+ { &dib0700_usb_id_table[70], NULL },
|
|
|
+ { NULL },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .rc.core = {
|
|
|
+ .rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
+ .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
|
+ .module_name = "dib0700",
|
|
|
+ .rc_query = dib0700_rc_query_old_firmware,
|
|
|
+ .allowed_protos = RC_TYPE_RC5 |
|
|
|
+ RC_TYPE_RC6 |
|
|
|
+ RC_TYPE_NEC,
|
|
|
+ .change_protocol = dib0700_change_protocol,
|
|
|
+ },
|
|
|
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
+ .num_adapters = 1,
|
|
|
+ .adapter = {
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = dib90x0_pid_filter,
|
|
|
+ .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
|
|
|
+ .frontend_attach = nim9090md_frontend_attach,
|
|
|
+ .tuner_attach = nim9090md_tuner_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .num_device_descs = 1,
|
|
|
+ .devices = {
|
|
|
+ { "DiBcom NIM9090MD reference design",
|
|
|
+ { &dib0700_usb_id_table[71], NULL },
|
|
|
+ { NULL },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .rc.core = {
|
|
|
+ .rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
+ .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
|
+ .module_name = "dib0700",
|
|
|
+ .rc_query = dib0700_rc_query_old_firmware,
|
|
|
+ .allowed_protos = RC_TYPE_RC5 |
|
|
|
+ RC_TYPE_RC6 |
|
|
|
+ RC_TYPE_NEC,
|
|
|
+ .change_protocol = dib0700_change_protocol,
|
|
|
+ },
|
|
|
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
+ .num_adapters = 1,
|
|
|
+ .adapter = {
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = stk70x0p_pid_filter,
|
|
|
+ .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
|
+ .frontend_attach = nim7090_frontend_attach,
|
|
|
+ .tuner_attach = nim7090_tuner_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .num_device_descs = 1,
|
|
|
+ .devices = {
|
|
|
+ { "DiBcom NIM7090 reference design",
|
|
|
+ { &dib0700_usb_id_table[72], NULL },
|
|
|
+ { NULL },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .rc.core = {
|
|
|
+ .rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
+ .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
|
+ .module_name = "dib0700",
|
|
|
+ .rc_query = dib0700_rc_query_old_firmware,
|
|
|
+ .allowed_protos = RC_TYPE_RC5 |
|
|
|
+ RC_TYPE_RC6 |
|
|
|
+ RC_TYPE_NEC,
|
|
|
+ .change_protocol = dib0700_change_protocol,
|
|
|
+ },
|
|
|
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
+ .num_adapters = 2,
|
|
|
+ .adapter = {
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = stk70x0p_pid_filter,
|
|
|
+ .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
|
+ .frontend_attach = tfe7090pvr_frontend0_attach,
|
|
|
+ .tuner_attach = tfe7090pvr_tuner0_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
|
|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
|
|
+ .pid_filter_count = 32,
|
|
|
+ .pid_filter = stk70x0p_pid_filter,
|
|
|
+ .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
|
+ .frontend_attach = tfe7090pvr_frontend1_attach,
|
|
|
+ .tuner_attach = tfe7090pvr_tuner1_attach,
|
|
|
+
|
|
|
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
+
|
|
|
+ .size_of_priv =
|
|
|
+ sizeof(struct dib0700_adapter_state),
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ .num_device_descs = 1,
|
|
|
+ .devices = {
|
|
|
+ { "DiBcom TFE7090PVR reference design",
|
|
|
+ { &dib0700_usb_id_table[73], NULL },
|
|
|
+ { NULL },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
.rc.core = {
|
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
|
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|