diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700.h | 5 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_core.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_devices.c | 96 |
4 files changed, 129 insertions, 13 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index a0aeaf4bbb37..dfd53d5e7926 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -69,6 +69,7 @@ config DVB_USB_DIBUSB_MC config DVB_USB_DIB0700 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" depends on DVB_USB + select DVB_DIB7000P select DVB_DIB7000M select DVB_DIB3000MC select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index ac84347f9d4c..cda3adea24fb 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h @@ -24,18 +24,23 @@ extern int dvb_usb_dib0700_debug; #define REQUEST_I2C_WRITE 0x3 #define REQUEST_POLL_RC 0x4 #define REQUEST_JUMPRAM 0x8 +#define REQUEST_SET_CLOCK 0xB #define REQUEST_SET_GPIO 0xC #define REQUEST_ENABLE_VIDEO 0xF // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) +#define REQUEST_GET_VERSION 0x15 struct dib0700_state { u8 channel_state; u16 mt2060_if1[2]; + + u8 is_dib7000pc; }; extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); +extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index dca6c6985661..6a4d150784a6 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -135,14 +135,46 @@ struct i2c_algorithm dib0700_i2c_algo = { int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold) { - u8 buf[3] = { REQUEST_SET_GPIO, 4, (GPIO_IN << 7) | (0 << 6) }; // GPIO4 is save - used for I2C - *cold = usb_control_msg(udev, usb_sndctrlpipe(udev,0), - buf[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, buf, 3, USB_CTRL_GET_TIMEOUT) != 3; + u8 b[16]; + s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); + + deb_info("FW GET_VERSION length: %d\n",ret); + + *cold = ret <= 0; deb_info("cold: %d\n", *cold); return 0; } +static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, + u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, + u16 pll_loopdiv, u16 free_div, u16 dsuScaler) +{ + u8 b[10]; + b[0] = REQUEST_SET_CLOCK; + b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4); + b[2] = (pll_prediv >> 8) & 0xff; // MSB + b[3] = pll_prediv & 0xff; // LSB + b[4] = (pll_loopdiv >> 8) & 0xff; // MSB + b[5] = pll_loopdiv & 0xff; // LSB + b[6] = (free_div >> 8) & 0xff; // MSB + b[7] = free_div & 0xff; // LSB + b[8] = (dsuScaler >> 8) & 0xff; // MSB + b[9] = dsuScaler & 0xff; // LSB + + return dib0700_ctrl_wr(d, b, 10); +} + +int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) +{ + switch (clk_MHz) { + case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break; + default: return -EINVAL; + } + return 0; +} + static int dib0700_jumpram(struct usb_device *udev, u32 address) { int ret, actlen; @@ -197,7 +229,7 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw /* start the firmware */ if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) { info("firmware started successfully."); - msleep(100); + msleep(500); } } else ret = -EIO; diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 305dd35a1021..c231a1e5204e 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -10,6 +10,7 @@ #include "dib3000mc.h" #include "dib7000m.h" +#include "dib7000p.h" #include "mt2060.h" static int force_lna_activation; @@ -96,7 +97,7 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) } /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ -static struct dibx000_agc_config stk7700p_dib7000m_agc_config = { +static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { BAND_UHF | BAND_VHF, // band_caps /* 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, @@ -141,7 +142,52 @@ static struct dibx000_agc_config stk7700p_dib7000m_agc_config = { }, }; -static struct dibx000_bandwidth_config stk7700p_dib7000m_mt2060_config = { +static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { + 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), // setup + + 712, // inv_gain + 41, // time_stabiliz + + 0, // alpha_level + 118, // thlock + + 0, // wbd_inv + 4095, // wbd_ref + 0, // wbd_sel + 0, // wbd_alpha + + 42598, // agc1_max + 16384, // agc1_min + 42598, // agc2_max + 0, // agc2_min + + 0, // agc1_pt1 + 137, // agc1_pt2 + 255, // agc1_pt3 + + 0, // agc1_slope1 + 255, // agc1_slope2 + + 0, // agc2_pt1 + 0, // agc2_pt2 + + 0, // agc2_slope1 + 41, // agc2_slope2 + + 15, // alpha_mant + 25, // alpha_exp + + 28, // beta_mant + 48, // beta_exp + + 0, // perform_agc_softsplit +}; + +static struct dibx000_bandwidth_config stk7700p_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 @@ -156,8 +202,19 @@ static struct dib7000m_config stk7700p_dib7000m_config = { .quartz_direct = 1, .agc_config_count = 1, - .agc = &stk7700p_dib7000m_agc_config, - .bw = &stk7700p_dib7000m_mt2060_config, + .agc = &stk7700p_7000m_mt2060_agc_config, + .bw = &stk7700p_pll_config, + + .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, +}; + +static struct dib7000p_config stk7700p_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + + .agc = &stk7700p_7000p_mt2060_agc_config, + .bw = &stk7700p_pll_config, .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, @@ -168,13 +225,28 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; /* unless there is no real power management in DVB - we leave the device on GPIO6 */ - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50); + 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, GPIO10, GPIO_OUT, 0); msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); + dib0700_ctrl_clock(adap->dev, 72, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100); + + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); st->mt2060_if1[0] = 1220; - return (adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config)) == NULL ? -ENODEV : 0; + + if (dib7000pc_detection(&adap->dev->i2c_adap)) { + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); + st->is_dib7000pc = 1; + } else + adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); + + return adap->fe == NULL ? -ENODEV : 0; } static struct mt2060_config stk7700p_mt2060_config = { @@ -184,8 +256,14 @@ static struct mt2060_config stk7700p_mt2060_config = { static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_state *st = adap->dev->priv; - struct i2c_adapter *tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); - return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &stk7700p_mt2060_config, + struct i2c_adapter *tun_i2c; + + if (st->is_dib7000pc) + tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + else + tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + + return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config, st->mt2060_if1[0]) == NULL ? -ENODEV : 0; } |