forked from Minki/linux
765bb8610d
When CONFIG_DVB_DIB9000 is disabled, we can still compile code that
now fails to link against dibx000_i2c_set_speed:
drivers/media/usb/dvb-usb/dib0700_devices.o: In function `dib01x0_pmu_update.constprop.7':
dib0700_devices.c:(.text.unlikely+0x1c9c): undefined reference to `dibx000_i2c_set_speed'
The call sites are both through dib01x0_pmu_update(), which gets passed
an 'i2c' pointer from dib9000_get_i2c_master(), which has returned
NULL. Checking this pointer seems to be a good idea anyway, and it avoids
the link failure in most cases.
Sean Young found another case that is not fixed by that, where certain
gcc versions leave an unused function in place that causes the link error,
but adding an explict IS_ENABLED() check also solves this.
Fixes: b7f54910ce
("V4L/DVB (4647): Added module for DiB0700 based devices")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
5161 lines
141 KiB
C
5161 lines
141 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
|
|
*
|
|
* Copyright (C) 2005-9 DiBcom, SA et al
|
|
*/
|
|
#include "dib0700.h"
|
|
|
|
#include "dib3000mc.h"
|
|
#include "dib7000m.h"
|
|
#include "dib7000p.h"
|
|
#include "dib8000.h"
|
|
#include "dib9000.h"
|
|
#include "mt2060.h"
|
|
#include "mt2266.h"
|
|
#include "tuner-xc2028.h"
|
|
#include "xc5000.h"
|
|
#include "xc4000.h"
|
|
#include "s5h1411.h"
|
|
#include "dib0070.h"
|
|
#include "dib0090.h"
|
|
#include "lgdt3305.h"
|
|
#include "mxl5007t.h"
|
|
#include "mn88472.h"
|
|
#include "tda18250.h"
|
|
|
|
|
|
static int force_lna_activation;
|
|
module_param(force_lna_activation, int, 0644);
|
|
MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifier(s) (LNA), if applicable for the device (default: 0=automatic/off).");
|
|
|
|
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)
|
|
* has a LNA on GPIO0 which is enabled by setting 1 */
|
|
static struct mt2060_config bristol_mt2060_config[2] = {
|
|
{
|
|
.i2c_address = 0x60,
|
|
.clock_out = 3,
|
|
}, {
|
|
.i2c_address = 0x61,
|
|
}
|
|
};
|
|
|
|
|
|
static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
|
|
.band_caps = BAND_VHF | BAND_UHF,
|
|
.setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
|
|
|
|
.agc1_max = 42598,
|
|
.agc1_min = 17694,
|
|
.agc2_max = 45875,
|
|
.agc2_min = 0,
|
|
|
|
.agc1_pt1 = 0,
|
|
.agc1_pt2 = 59,
|
|
|
|
.agc1_slope1 = 0,
|
|
.agc1_slope2 = 69,
|
|
|
|
.agc2_pt1 = 0,
|
|
.agc2_pt2 = 59,
|
|
|
|
.agc2_slope1 = 111,
|
|
.agc2_slope2 = 28,
|
|
};
|
|
|
|
static struct dib3000mc_config bristol_dib3000mc_config[2] = {
|
|
{ .agc = &bristol_dib3000p_mt2060_agc_config,
|
|
.max_time = 0x196,
|
|
.ln_adc_level = 0x1cc7,
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
},
|
|
{ .agc = &bristol_dib3000p_mt2060_agc_config,
|
|
.max_time = 0x196,
|
|
.ln_adc_level = 0x1cc7,
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
}
|
|
};
|
|
|
|
static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_state *st = adap->dev->priv;
|
|
if (adap->id == 0) {
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
|
|
|
|
if (force_lna_activation)
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
else
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
|
|
|
|
if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
st->mt2060_if1[adap->id] = 1220;
|
|
return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
|
|
(10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
|
|
{
|
|
struct i2c_msg msg[2] = {
|
|
{ .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
|
|
{ .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
|
|
};
|
|
if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
|
|
return 0;
|
|
}
|
|
|
|
static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
|
|
struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
|
|
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_500_2)) {
|
|
if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
|
|
}
|
|
return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c,
|
|
&bristol_mt2060_config[adap->id], if1) == NULL ?
|
|
-ENODEV : 0;
|
|
}
|
|
|
|
/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
|
|
|
|
/* MT226x */
|
|
static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
|
|
{
|
|
BAND_UHF,
|
|
|
|
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
|
|
* 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) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
|
|
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
|
|
|
1130,
|
|
21,
|
|
|
|
0,
|
|
118,
|
|
|
|
0,
|
|
3530,
|
|
1,
|
|
0,
|
|
|
|
65535,
|
|
33770,
|
|
65535,
|
|
23592,
|
|
|
|
0,
|
|
62,
|
|
255,
|
|
64,
|
|
64,
|
|
132,
|
|
192,
|
|
80,
|
|
80,
|
|
|
|
17,
|
|
27,
|
|
23,
|
|
51,
|
|
|
|
1,
|
|
}, {
|
|
BAND_VHF | BAND_LBAND,
|
|
|
|
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
|
|
* 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) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
|
|
| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
|
|
|
|
2372,
|
|
21,
|
|
|
|
0,
|
|
118,
|
|
|
|
0,
|
|
3530,
|
|
1,
|
|
0,
|
|
|
|
65535,
|
|
0,
|
|
65535,
|
|
23592,
|
|
|
|
0,
|
|
128,
|
|
128,
|
|
128,
|
|
0,
|
|
128,
|
|
253,
|
|
81,
|
|
0,
|
|
|
|
17,
|
|
27,
|
|
23,
|
|
51,
|
|
|
|
1,
|
|
}
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
|
|
.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[] = {
|
|
{ .output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.tuner_is_baseband = 1,
|
|
|
|
.agc_config_count = 2,
|
|
.agc = stk7700d_7000p_mt2266_agc_config,
|
|
.bw = &stk7700d_mt2266_pll_config,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
},
|
|
{ .output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.tuner_is_baseband = 1,
|
|
|
|
.agc_config_count = 2,
|
|
.agc = stk7700d_7000p_mt2266_agc_config,
|
|
.bw = &stk7700d_mt2266_pll_config,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
}
|
|
};
|
|
|
|
static struct mt2266_config stk7700d_mt2266_config[2] = {
|
|
{ .i2c_address = 0x60
|
|
},
|
|
{ .i2c_address = 0x60
|
|
}
|
|
};
|
|
|
|
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);
|
|
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);
|
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
|
|
stk7700d_dib7000p_mt2266_config)
|
|
!= 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
|
|
0x80 + (adap->id << 1),
|
|
&stk7700d_dib7000p_mt2266_config[adap->id]);
|
|
|
|
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
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);
|
|
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);
|
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
|
|
stk7700d_dib7000p_mt2266_config)
|
|
!= 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
|
|
0x80 + (adap->id << 1),
|
|
&stk7700d_dib7000p_mt2266_config[adap->id]);
|
|
|
|
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct i2c_adapter *tun_i2c;
|
|
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_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 */
|
|
.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 = {
|
|
.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 = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.tuner_is_baseband = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &xc3028_agc_config,
|
|
.bw = &xc3028_bw_config,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
};
|
|
|
|
static int stk7700ph_xc3028_callback(void *ptr, int component,
|
|
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 */
|
|
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:
|
|
case XC2028_I2C_FLUSH:
|
|
break;
|
|
default:
|
|
err("%s: unknown command %d, arg %d\n", __func__,
|
|
command, arg);
|
|
return -EINVAL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
|
|
.fname = XC2028_DEFAULT_FIRMWARE,
|
|
.max_len = 64,
|
|
.demod = XC3028_FE_DIBCOM52,
|
|
};
|
|
|
|
static struct xc2028_config stk7700ph_xc3028_config = {
|
|
.i2c_addr = 0x61,
|
|
.ctrl = &stk7700ph_xc3028_ctrl,
|
|
};
|
|
|
|
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);
|
|
else
|
|
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);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
msleep(10);
|
|
|
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
|
|
&stk7700ph_dib7700_xc3028_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct i2c_adapter *tun_i2c;
|
|
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);
|
|
|
|
stk7700ph_xc3028_config.i2c_adap = tun_i2c;
|
|
|
|
/* FIXME: generalize & move to common area */
|
|
adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;
|
|
|
|
return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
|
|
== NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
#define DEFAULT_RC_INTERVAL 50
|
|
|
|
/*
|
|
* This function is used only when firmware is < 1.20 version. Newer
|
|
* firmwares use bulk mode, with functions implemented at dib0700_core,
|
|
* at dib0700_rc_urb_completion()
|
|
*/
|
|
static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
|
|
{
|
|
enum rc_proto protocol;
|
|
u32 scancode;
|
|
u8 toggle;
|
|
int i;
|
|
struct dib0700_state *st = d->priv;
|
|
|
|
if (st->fw_version >= 0x10200) {
|
|
/* For 1.20 firmware , We need to keep the RC polling
|
|
callback so we can reuse the input device setup in
|
|
dvb-usb-remote.c. However, the actual work is being done
|
|
in the bulk URB completion handler. */
|
|
return 0;
|
|
}
|
|
|
|
st->buf[0] = REQUEST_POLL_RC;
|
|
st->buf[1] = 0;
|
|
|
|
i = dib0700_ctrl_rd(d, st->buf, 2, st->buf, 4);
|
|
if (i <= 0) {
|
|
err("RC Query Failed");
|
|
return -EIO;
|
|
}
|
|
|
|
/* losing half of KEY_0 events from Philipps rc5 remotes.. */
|
|
if (st->buf[0] == 0 && st->buf[1] == 0
|
|
&& st->buf[2] == 0 && st->buf[3] == 0)
|
|
return 0;
|
|
|
|
/* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)st->buf[3 - 2],(int)st->buf[3 - 3],(int)st->buf[3 - 1],(int)st->buf[3]); */
|
|
|
|
dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */
|
|
|
|
switch (d->props.rc.core.protocol) {
|
|
case RC_PROTO_BIT_NEC:
|
|
/* NEC protocol sends repeat code as 0 0 0 FF */
|
|
if ((st->buf[3 - 2] == 0x00) && (st->buf[3 - 3] == 0x00) &&
|
|
(st->buf[3] == 0xff)) {
|
|
rc_repeat(d->rc_dev);
|
|
return 0;
|
|
}
|
|
|
|
protocol = RC_PROTO_NEC;
|
|
scancode = RC_SCANCODE_NEC(st->buf[3 - 2], st->buf[3 - 3]);
|
|
toggle = 0;
|
|
break;
|
|
|
|
default:
|
|
/* RC-5 protocol changes toggle bit on new keypress */
|
|
protocol = RC_PROTO_RC5;
|
|
scancode = RC_SCANCODE_RC5(st->buf[3 - 2], st->buf[3 - 3]);
|
|
toggle = st->buf[3 - 1];
|
|
break;
|
|
}
|
|
|
|
rc_keydown(d->rc_dev, protocol, scancode, toggle);
|
|
return 0;
|
|
}
|
|
|
|
/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
|
|
static struct dibx000_agc_config stk7700p_7000m_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),
|
|
|
|
712,
|
|
41,
|
|
|
|
0,
|
|
118,
|
|
|
|
0,
|
|
4095,
|
|
0,
|
|
0,
|
|
|
|
42598,
|
|
17694,
|
|
45875,
|
|
2621,
|
|
0,
|
|
76,
|
|
139,
|
|
52,
|
|
59,
|
|
107,
|
|
172,
|
|
57,
|
|
70,
|
|
|
|
21,
|
|
25,
|
|
28,
|
|
48,
|
|
|
|
1,
|
|
{ 0,
|
|
107,
|
|
51800,
|
|
24700
|
|
},
|
|
};
|
|
|
|
static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
|
|
.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 */
|
|
.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 = {
|
|
.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 = {
|
|
.dvbt_mode = 1,
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.quartz_direct = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.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_config_count = 1,
|
|
.agc = &stk7700p_7000p_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 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);
|
|
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_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;
|
|
|
|
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 {
|
|
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;
|
|
}
|
|
|
|
static struct mt2060_config stk7700p_mt2060_config = {
|
|
0x60
|
|
};
|
|
|
|
static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
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 = 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);
|
|
|
|
return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
|
|
if1) == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
/* DIB7070 generic */
|
|
static struct dibx000_agc_config dib7070_agc_config = {
|
|
.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 */
|
|
.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 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 state->dib7000p_ops.set_gpio(fe, 9, 0, onoff);
|
|
}
|
|
|
|
static struct dib0070_config dib7070p_dib0070_config[2] = {
|
|
{
|
|
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
|
.reset = dib7070_tuner_reset,
|
|
.sleep = dib7070_tuner_sleep,
|
|
.clock_khz = 12000,
|
|
.clock_pad_drive = 4,
|
|
.charge_pump = 2,
|
|
}, {
|
|
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
|
.reset = dib7070_tuner_reset,
|
|
.sleep = dib7070_tuner_sleep,
|
|
.clock_khz = 12000,
|
|
.charge_pump = 2,
|
|
}
|
|
};
|
|
|
|
static struct dib0070_config dib7770p_dib0070_config = {
|
|
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
|
.reset = dib7070_tuner_reset,
|
|
.sleep = dib7070_tuner_sleep,
|
|
.clock_khz = 12000,
|
|
.clock_pad_drive = 0,
|
|
.flip_chip = 1,
|
|
.charge_pump = 2,
|
|
};
|
|
|
|
static int dib7070_set_param_override(struct dvb_frontend *fe)
|
|
{
|
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
|
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: offset = 950; break;
|
|
case BAND_UHF:
|
|
default: offset = 550; 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 dib7770_set_param_override(struct dvb_frontend *fe)
|
|
{
|
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
|
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:
|
|
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 = 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;
|
|
}
|
|
|
|
static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
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 (adap->id == 0) {
|
|
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
|
|
return -ENODEV;
|
|
} else {
|
|
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == 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 = dib7070_set_param_override;
|
|
return 0;
|
|
}
|
|
|
|
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 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 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)
|
|
{
|
|
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)
|
|
{
|
|
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 = {
|
|
.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 = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &dib7070_agc_config,
|
|
.bw = &dib7070_bw_config_12_mhz,
|
|
.tuner_is_baseband = 1,
|
|
.spur_protect = 1,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
|
.hostbus_diversity = 1,
|
|
};
|
|
|
|
/* STK7070P */
|
|
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);
|
|
else
|
|
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 (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
|
|
&dib7070p_dib7000p_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/* STK7770P */
|
|
static struct dib7000p_config dib7770p_dib7000p_config = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &dib7070_agc_config,
|
|
.bw = &dib7070_bw_config_12_mhz,
|
|
.tuner_is_baseband = 1,
|
|
.spur_protect = 1,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
|
.hostbus_diversity = 1,
|
|
.enable_current_mirror = 1,
|
|
.disable_sample_and_hold = 0,
|
|
};
|
|
|
|
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);
|
|
else
|
|
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 (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
|
|
&dib7770p_dib7000p_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/* DIB807x generic */
|
|
static struct dibx000_agc_config dib807x_agc_config[2] = {
|
|
{
|
|
BAND_VHF,
|
|
/* 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) | (7 << 11) | (0 << 10) | (0 << 9) |
|
|
(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
|
|
(0 << 0), /* setup*/
|
|
|
|
600, /* inv_gain*/
|
|
10, /* time_stabiliz*/
|
|
|
|
0, /* alpha_level*/
|
|
118, /* thlock*/
|
|
|
|
0, /* wbd_inv*/
|
|
3530, /* wbd_ref*/
|
|
1, /* wbd_sel*/
|
|
5, /* wbd_alpha*/
|
|
|
|
65535, /* agc1_max*/
|
|
0, /* agc1_min*/
|
|
|
|
65535, /* agc2_max*/
|
|
0, /* agc2_min*/
|
|
|
|
0, /* agc1_pt1*/
|
|
40, /* agc1_pt2*/
|
|
183, /* agc1_pt3*/
|
|
206, /* agc1_slope1*/
|
|
255, /* agc1_slope2*/
|
|
72, /* agc2_pt1*/
|
|
152, /* agc2_pt2*/
|
|
88, /* agc2_slope1*/
|
|
90, /* agc2_slope2*/
|
|
|
|
17, /* alpha_mant*/
|
|
27, /* alpha_exp*/
|
|
23, /* beta_mant*/
|
|
51, /* beta_exp*/
|
|
|
|
0, /* perform_agc_softsplit*/
|
|
}, {
|
|
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 */
|
|
(0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
|
|
(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
|
|
(0 << 0), /* setup */
|
|
|
|
600, /* inv_gain*/
|
|
10, /* time_stabiliz*/
|
|
|
|
0, /* alpha_level*/
|
|
118, /* thlock*/
|
|
|
|
0, /* wbd_inv*/
|
|
3530, /* wbd_ref*/
|
|
1, /* wbd_sel*/
|
|
5, /* wbd_alpha*/
|
|
|
|
65535, /* agc1_max*/
|
|
0, /* agc1_min*/
|
|
|
|
65535, /* agc2_max*/
|
|
0, /* agc2_min*/
|
|
|
|
0, /* agc1_pt1*/
|
|
40, /* agc1_pt2*/
|
|
183, /* agc1_pt3*/
|
|
206, /* agc1_slope1*/
|
|
255, /* agc1_slope2*/
|
|
72, /* agc2_pt1*/
|
|
152, /* agc2_pt2*/
|
|
88, /* agc2_slope1*/
|
|
90, /* agc2_slope2*/
|
|
|
|
17, /* alpha_mant*/
|
|
27, /* alpha_exp*/
|
|
23, /* beta_mant*/
|
|
51, /* beta_exp*/
|
|
|
|
0, /* perform_agc_softsplit*/
|
|
}
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
|
|
.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] = {
|
|
{
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 2,
|
|
.agc = dib807x_agc_config,
|
|
.pll = &dib807x_bw_config_12_mhz,
|
|
.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 = 1,
|
|
.agc_control = &dib0070_ctrl_agc_filter,
|
|
.output_mode = OUTMODE_MPEG2_FIFO,
|
|
.drives = 0x2d98,
|
|
}, {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 2,
|
|
.agc = dib807x_agc_config,
|
|
.pll = &dib807x_bw_config_12_mhz,
|
|
.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,
|
|
.agc_control = &dib0070_ctrl_agc_filter,
|
|
.output_mode = OUTMODE_MPEG2_FIFO,
|
|
.drives = 0x2d98,
|
|
}
|
|
};
|
|
|
|
static int dib80xx_tuner_reset(struct dvb_frontend *fe, int 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)
|
|
{
|
|
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[] = {
|
|
{ 240, 7},
|
|
{ 0xffff, 6},
|
|
};
|
|
|
|
static struct dib0070_config dib807x_dib0070_config[2] = {
|
|
{
|
|
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
|
.reset = dib80xx_tuner_reset,
|
|
.sleep = dib80xx_tuner_sleep,
|
|
.clock_khz = 12000,
|
|
.clock_pad_drive = 4,
|
|
.vga_filter = 1,
|
|
.force_crystal_mode = 1,
|
|
.enable_third_order_filter = 1,
|
|
.charge_pump = 0,
|
|
.wbd_gain = dib8070_wbd_gain_cfg,
|
|
.osc_buffer_state = 0,
|
|
.freq_offset_khz_uhf = -100,
|
|
.freq_offset_khz_vhf = -100,
|
|
}, {
|
|
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
|
.reset = dib80xx_tuner_reset,
|
|
.sleep = dib80xx_tuner_sleep,
|
|
.clock_khz = 12000,
|
|
.clock_pad_drive = 2,
|
|
.vga_filter = 1,
|
|
.force_crystal_mode = 1,
|
|
.enable_third_order_filter = 1,
|
|
.charge_pump = 0,
|
|
.wbd_gain = dib8070_wbd_gain_cfg,
|
|
.osc_buffer_state = 0,
|
|
.freq_offset_khz_uhf = -25,
|
|
.freq_offset_khz_vhf = -25,
|
|
}
|
|
};
|
|
|
|
static int dib807x_set_param_override(struct dvb_frontend *fe)
|
|
{
|
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
|
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
struct dib0700_adapter_state *state = adap->priv;
|
|
|
|
u16 offset = dib0070_wbd_offset(fe);
|
|
u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
|
|
switch (band) {
|
|
case BAND_VHF:
|
|
offset += 750;
|
|
break;
|
|
case BAND_UHF: /* fall-thru wanted */
|
|
default:
|
|
offset += 250; break;
|
|
}
|
|
deb_info("WBD for DiB8000: %d\n", offset);
|
|
state->dib8000_ops.set_wbd_ref(fe, offset);
|
|
|
|
return state->set_param_save(fe);
|
|
}
|
|
|
|
static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
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) {
|
|
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
|
|
&dib807x_dib0070_config[0]) == NULL)
|
|
return -ENODEV;
|
|
} else {
|
|
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
|
|
&dib807x_dib0070_config[1]) == 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 = dib807x_set_param_override;
|
|
return 0;
|
|
}
|
|
|
|
static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
|
|
u16 pid, int 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)
|
|
{
|
|
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);
|
|
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);
|
|
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
|
|
0x80, 0);
|
|
|
|
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;
|
|
}
|
|
|
|
/* 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);
|
|
msleep(500);
|
|
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);
|
|
|
|
/* initialize IC 0 */
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
|
|
|
|
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;
|
|
}
|
|
|
|
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 */
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
|
|
|
|
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;
|
|
}
|
|
|
|
/* STK8096GP */
|
|
static struct dibx000_agc_config dib8090_agc_config[2] = {
|
|
{
|
|
.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 */
|
|
.setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
|
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
|
|
|
.inv_gain = 787,
|
|
.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 = 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,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
},
|
|
{
|
|
.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 */
|
|
.setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
|
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
|
|
|
.inv_gain = 787,
|
|
.time_stabiliz = 10,
|
|
|
|
.alpha_level = 0,
|
|
.thlock = 118,
|
|
|
|
.wbd_inv = 0,
|
|
.wbd_ref = 3530,
|
|
.wbd_sel = 1,
|
|
.wbd_alpha = 5,
|
|
|
|
.agc1_max = 0,
|
|
.agc1_min = 0,
|
|
|
|
.agc2_max = 65535,
|
|
.agc2_min = 0,
|
|
|
|
.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,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
}
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
|
|
.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)
|
|
{
|
|
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)
|
|
{
|
|
deb_info("AGC control callback: %i\n", restart);
|
|
dib0090_dcc_freq(fe, restart);
|
|
|
|
if (restart == 0) /* before AGC startup */
|
|
dib0090_set_dc_servo(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 = dib8090_agc_control,
|
|
.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 = dib8090_agc_control,
|
|
.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 u8 dib8090_compute_pll_parameters(struct dvb_frontend *fe)
|
|
{
|
|
u8 optimal_pll_ratio = 20;
|
|
u32 freq_adc, ratio, rest, max = 0;
|
|
u8 pll_ratio;
|
|
|
|
for (pll_ratio = 17; pll_ratio <= 20; pll_ratio++) {
|
|
freq_adc = 12 * pll_ratio * (1 << 8) / 16;
|
|
ratio = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) / freq_adc;
|
|
rest = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) - ratio * freq_adc;
|
|
|
|
if (rest > freq_adc / 2)
|
|
rest = freq_adc - rest;
|
|
deb_info("PLL ratio=%i rest=%i\n", pll_ratio, rest);
|
|
if ((rest > max) && (rest > 717)) {
|
|
optimal_pll_ratio = pll_ratio;
|
|
max = rest;
|
|
}
|
|
}
|
|
deb_info("optimal PLL ratio=%i\n", optimal_pll_ratio);
|
|
|
|
return optimal_pll_ratio;
|
|
}
|
|
|
|
static int dib8096_set_param_override(struct dvb_frontend *fe)
|
|
{
|
|
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
struct dib0700_adapter_state *state = adap->priv;
|
|
u8 pll_ratio, band = BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
|
|
u16 target, ltgain, rf_gain_limit;
|
|
u32 timf;
|
|
int ret = 0;
|
|
enum frontend_tune_state tune_state = CT_SHUTDOWN;
|
|
|
|
switch (band) {
|
|
default:
|
|
deb_info("Warning : Rf frequency (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency);
|
|
/* fall through */
|
|
case BAND_VHF:
|
|
state->dib8000_ops.set_gpio(fe, 3, 0, 1);
|
|
break;
|
|
case BAND_UHF:
|
|
state->dib8000_ops.set_gpio(fe, 3, 0, 0);
|
|
break;
|
|
}
|
|
|
|
ret = state->set_param_save(fe);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (fe->dtv_property_cache.bandwidth_hz != 6000000) {
|
|
deb_info("only 6MHz bandwidth is supported\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Update PLL if needed ratio */
|
|
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);
|
|
if (pll_ratio == 17)
|
|
timf = 21387946;
|
|
else if (pll_ratio == 18)
|
|
timf = 20199727;
|
|
else if (pll_ratio == 19)
|
|
timf = 19136583;
|
|
else
|
|
timf = 18179756;
|
|
|
|
/* Update ratio */
|
|
state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);
|
|
|
|
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;
|
|
state->dib8000_ops.set_wbd_ref(fe, target);
|
|
}
|
|
|
|
if (band == BAND_CBAND) {
|
|
deb_info("tuning in CBAND - soft-AGC startup\n");
|
|
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)
|
|
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 */
|
|
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);
|
|
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");
|
|
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 = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
|
|
|
|
if (adap->id == 0) {
|
|
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
|
|
return -ENODEV;
|
|
} else {
|
|
/* FIXME: check if it is fe_adap[1] */
|
|
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_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 = dib8096_set_param_override;
|
|
return 0;
|
|
}
|
|
|
|
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);
|
|
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);
|
|
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 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;
|
|
}
|
|
|
|
static int stk809x_frontend1_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *state = adap->priv;
|
|
|
|
if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
|
|
return -ENODEV;
|
|
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x82, 0);
|
|
|
|
adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
|
|
|
|
return adap->fe_adap[0].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 = st->dib8000_ops.get_slave_frontend(adap->fe_adap[0].fe, 1);
|
|
|
|
if (fe_slave) {
|
|
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 = 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;
|
|
|
|
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
|
|
adap->fe_adap[0].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;
|
|
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);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 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;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* TFE8096P */
|
|
static struct dibx000_agc_config dib8096p_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),
|
|
|
|
.inv_gain = 684,
|
|
.time_stabiliz = 10,
|
|
|
|
.alpha_level = 0,
|
|
.thlock = 118,
|
|
|
|
.wbd_inv = 0,
|
|
.wbd_ref = 1200,
|
|
.wbd_sel = 3,
|
|
.wbd_alpha = 5,
|
|
|
|
.agc1_max = 65535,
|
|
.agc1_min = 0,
|
|
|
|
.agc2_max = 32767,
|
|
.agc2_min = 0,
|
|
|
|
.agc1_pt1 = 0,
|
|
.agc1_pt2 = 0,
|
|
.agc1_pt3 = 105,
|
|
.agc1_slope1 = 0,
|
|
.agc1_slope2 = 156,
|
|
.agc2_pt1 = 105,
|
|
.agc2_pt2 = 255,
|
|
.agc2_slope1 = 54,
|
|
.agc2_slope2 = 0,
|
|
|
|
.alpha_mant = 28,
|
|
.alpha_exp = 26,
|
|
.beta_mant = 31,
|
|
.beta_exp = 51,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
} , {
|
|
.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),
|
|
|
|
.inv_gain = 732,
|
|
.time_stabiliz = 10,
|
|
|
|
.alpha_level = 0,
|
|
.thlock = 118,
|
|
|
|
.wbd_inv = 0,
|
|
.wbd_ref = 1200,
|
|
.wbd_sel = 3,
|
|
.wbd_alpha = 5,
|
|
|
|
.agc1_max = 65535,
|
|
.agc1_min = 0,
|
|
|
|
.agc2_max = 32767,
|
|
.agc2_min = 0,
|
|
|
|
.agc1_pt1 = 0,
|
|
.agc1_pt2 = 0,
|
|
.agc1_pt3 = 98,
|
|
.agc1_slope1 = 0,
|
|
.agc1_slope2 = 167,
|
|
.agc2_pt1 = 98,
|
|
.agc2_pt2 = 255,
|
|
.agc2_slope1 = 52,
|
|
.agc2_slope2 = 0,
|
|
|
|
.alpha_mant = 28,
|
|
.alpha_exp = 26,
|
|
.beta_mant = 31,
|
|
.beta_exp = 51,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
}
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
|
|
.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 = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.update_lna = NULL,
|
|
|
|
.agc_config_count = 2,
|
|
.agc = dib8096p_agc_config,
|
|
.pll = &dib8096p_clock_config_12_mhz,
|
|
|
|
.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
|
|
|
|
.agc_control = NULL,
|
|
.diversity_delay = 48,
|
|
.output_mode = OUTMODE_MPEG2_FIFO,
|
|
.enMpegOutput = 1,
|
|
};
|
|
|
|
static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
|
|
{ 380, 81, 850, 64, 540, 4},
|
|
{ 860, 51, 866, 21, 375, 4},
|
|
{1700, 0, 250, 0, 100, 6},
|
|
{2600, 0, 250, 0, 100, 6},
|
|
{ 0xFFFF, 0, 0, 0, 0, 0},
|
|
};
|
|
|
|
static struct dib0090_config tfe8096p_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,
|
|
|
|
.freq_offset_khz_uhf = -143,
|
|
.freq_offset_khz_vhf = -143,
|
|
|
|
.get_adc_power = dib8090_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 = 1,
|
|
|
|
.ls_cfg_pad_drv = 0,
|
|
.data_tx_drv = 0,
|
|
.low_if = NULL,
|
|
.in_soc = 1,
|
|
.force_cband_input = 0,
|
|
};
|
|
|
|
struct dibx090p_adc {
|
|
u32 freq; /* RF freq MHz */
|
|
u32 timf; /* New Timf */
|
|
u32 pll_loopdiv; /* New prediv */
|
|
u32 pll_prediv; /* New loopdiv */
|
|
};
|
|
|
|
struct dibx090p_best_adc {
|
|
u32 timf;
|
|
u32 pll_loopdiv;
|
|
u32 pll_prediv;
|
|
};
|
|
|
|
static int dib8096p_get_best_sampling(struct dvb_frontend *fe, struct dibx090p_best_adc *adc)
|
|
{
|
|
u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
|
|
u16 xtal = 12000;
|
|
u16 fcp_min = 1900; /* PLL, Minimum Frequency of phase comparator (KHz) */
|
|
u16 fcp_max = 20000; /* PLL, Maximum Frequency of phase comparator (KHz) */
|
|
u32 fmem_max = 140000; /* 140MHz max SDRAM freq */
|
|
u32 fdem_min = 66000;
|
|
u32 fcp = 0, fs = 0, fdem = 0, fmem = 0;
|
|
u32 harmonic_id = 0;
|
|
|
|
adc->timf = 0;
|
|
adc->pll_loopdiv = loopdiv;
|
|
adc->pll_prediv = prediv;
|
|
|
|
deb_info("bandwidth = %d", fe->dtv_property_cache.bandwidth_hz);
|
|
|
|
/* 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 = 1;
|
|
|
|
for (prediv = min_prediv; prediv < max_prediv; prediv++) {
|
|
fcp = xtal / prediv;
|
|
if (fcp > fcp_min && fcp < fcp_max) {
|
|
for (loopdiv = 1; loopdiv < 64; loopdiv++) {
|
|
fmem = ((xtal/prediv) * loopdiv);
|
|
fdem = fmem / 2;
|
|
fs = fdem / 4;
|
|
|
|
/* test min/max system restrictions */
|
|
if ((fdem >= fdem_min) && (fmem <= fmem_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 = (4260880253U / fdem) * (1 << 8);
|
|
adc->timf += ((4260880253U % fdem) << 8) / fdem;
|
|
|
|
deb_info("RF %6d; BW %6d; Xtal %6d; Fmem %6d; Fdem %6d; Fs %6d; Prediv %2d; Loopdiv %2d; Timf %8d;", fe->dtv_property_cache.frequency, fe->dtv_property_cache.bandwidth_hz, xtal, fmem, fdem, fs, prediv, loopdiv, adc->timf);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!spur)
|
|
break;
|
|
}
|
|
|
|
if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
static int dib8096p_agc_startup(struct dvb_frontend *fe)
|
|
{
|
|
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
struct dib0700_adapter_state *state = adap->priv;
|
|
struct dibx000_bandwidth_config pll;
|
|
struct dibx090p_best_adc adc;
|
|
u16 target;
|
|
int ret;
|
|
|
|
ret = state->set_param_save(fe);
|
|
if (ret < 0)
|
|
return ret;
|
|
memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
|
|
|
|
dib0090_pwm_gain_reset(fe);
|
|
/* dib0090_get_wbd_target is returning any possible
|
|
temperature compensated wbd-target */
|
|
target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
|
|
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);
|
|
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;
|
|
}
|
|
|
|
static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
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)
|
|
st->fw_use_new_i2c_api = 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);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
|
|
|
|
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;
|
|
}
|
|
|
|
static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
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;
|
|
|
|
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;
|
|
return 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_adap[0].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_adap[0].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(20);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
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_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
|
|
|
|
return adap->fe_adap[0].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_adap[0].fe);
|
|
u16 data_dib190[10] = {
|
|
1, 0x1374,
|
|
2, 0x01a2,
|
|
7, 0x0020,
|
|
0, 0x00ef,
|
|
8, 0x0486,
|
|
};
|
|
|
|
if (!IS_ENABLED(CONFIG_DVB_DIB9000))
|
|
return -ENODEV;
|
|
if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
|
|
return -ENODEV;
|
|
i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
|
|
if (!i2c)
|
|
return -ENODEV;
|
|
if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
|
|
return -ENODEV;
|
|
dib0700_set_i2c_speed(adap->dev, 1500);
|
|
if (dib9000_firmware_post_pll_init(adap->fe_adap[0].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(20);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
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_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
|
|
|
|
if (adap->fe_adap[0].fe == NULL)
|
|
return -ENODEV;
|
|
|
|
i2c = dib9000_get_i2c_master(adap->fe_adap[0].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_adap[0].fe, fe_slave);
|
|
|
|
return fe_slave == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
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,
|
|
};
|
|
if (!IS_ENABLED(CONFIG_DVB_DIB9000))
|
|
return -ENODEV;
|
|
i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
|
|
if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
|
|
return -ENODEV;
|
|
i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
|
|
if (!i2c)
|
|
return -ENODEV;
|
|
if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
|
|
return -ENODEV;
|
|
|
|
dib0700_set_i2c_speed(adap->dev, 1500);
|
|
if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
|
|
return -ENODEV;
|
|
|
|
fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1);
|
|
if (fe_slave != NULL) {
|
|
i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].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_adap[0].fe->dvb;
|
|
dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
|
|
if (dib9000_firmware_post_pll_init(fe_slave) < 0)
|
|
return -ENODEV;
|
|
}
|
|
release_firmware(state->frontend_firmware);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* NIM7090 */
|
|
static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dibx090p_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_usb_adapter *adap = fe->dvb->priv;
|
|
struct dib0700_adapter_state *state = adap->priv;
|
|
struct dibx000_bandwidth_config pll;
|
|
u16 target;
|
|
struct dibx090p_best_adc adc;
|
|
int ret;
|
|
|
|
ret = state->set_param_save(fe);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
|
|
dib0090_pwm_gain_reset(fe);
|
|
target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
|
|
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;
|
|
|
|
state->dib7000p_ops.update_pll(fe, &pll);
|
|
state->dib7000p_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
|
|
{
|
|
deb_info("AGC restart callback: %d", restart);
|
|
if (restart == 0) /* before AGC startup */
|
|
dib0090_set_dc_servo(fe, 1);
|
|
return 0;
|
|
}
|
|
|
|
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) {
|
|
state->dib7000p_ops.set_gpio(fe, 8, 0, 0);
|
|
state->dib7000p_ops.set_agc1_min(fe, 0);
|
|
} else {
|
|
state->dib7000p_ops.set_gpio(fe, 8, 0, 1);
|
|
state->dib7000p_ops.set_agc1_min(fe, 32768);
|
|
}
|
|
|
|
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},
|
|
{2600, 0, 250, 0, 100, 6},
|
|
{ 0xFFFF, 0, 0, 0, 0, 0},
|
|
};
|
|
|
|
static 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),
|
|
|
|
.inv_gain = 687,
|
|
.time_stabiliz = 10,
|
|
|
|
.alpha_level = 0,
|
|
.thlock = 118,
|
|
|
|
.wbd_inv = 0,
|
|
.wbd_ref = 1200,
|
|
.wbd_sel = 3,
|
|
.wbd_alpha = 5,
|
|
|
|
.agc1_max = 65535,
|
|
.agc1_min = 32768,
|
|
|
|
.agc2_max = 65535,
|
|
.agc2_min = 0,
|
|
|
|
.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 = 18,
|
|
.alpha_exp = 0,
|
|
.beta_mant = 20,
|
|
.beta_exp = 59,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
} , {
|
|
.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),
|
|
|
|
.inv_gain = 732,
|
|
.time_stabiliz = 10,
|
|
|
|
.alpha_level = 0,
|
|
.thlock = 118,
|
|
|
|
.wbd_inv = 0,
|
|
.wbd_ref = 1200,
|
|
.wbd_sel = 3,
|
|
.wbd_alpha = 5,
|
|
|
|
.agc1_max = 65535,
|
|
.agc1_min = 0,
|
|
|
|
.agc2_max = 65535,
|
|
.agc2_min = 0,
|
|
|
|
.agc1_pt1 = 0,
|
|
.agc1_pt2 = 0,
|
|
.agc1_pt3 = 98,
|
|
.agc1_slope1 = 0,
|
|
.agc1_slope2 = 167,
|
|
.agc2_pt1 = 98,
|
|
.agc2_pt2 = 255,
|
|
.agc2_slope1 = 104,
|
|
.agc2_slope2 = 0,
|
|
|
|
.alpha_mant = 18,
|
|
.alpha_exp = 0,
|
|
.beta_mant = 20,
|
|
.beta_exp = 59,
|
|
|
|
.perform_agc_softsplit = 0,
|
|
}
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
|
|
.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 = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.tuner_is_baseband = 1,
|
|
.update_lna = tfe7790p_update_lna, /* GPIO used is the same as TFE7790 */
|
|
|
|
.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 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) {
|
|
state->dib7000p_ops.set_gpio(fe, 5, 0, 0);
|
|
state->dib7000p_ops.set_agc1_min(fe, 0);
|
|
} else {
|
|
state->dib7000p_ops.set_gpio(fe, 5, 0, 1);
|
|
state->dib7000p_ops.set_agc1_min(fe, 32768);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
|
|
{
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.tuner_is_baseband = 1,
|
|
.update_lna = tfe7090p_pvr_update_lna,
|
|
|
|
.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 = tfe7090p_pvr_update_lna,
|
|
|
|
.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 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,
|
|
|
|
.freq_offset_khz_uhf = 0,
|
|
.freq_offset_khz_vhf = 0,
|
|
|
|
.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 struct dib7000p_config tfe7790p_dib7000p_config = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
.hostbus_diversity = 1,
|
|
.tuner_is_baseband = 1,
|
|
.update_lna = tfe7790p_update_lna,
|
|
|
|
.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,
|
|
.enMpegOutput = 1,
|
|
};
|
|
|
|
static struct dib0090_config tfe7790p_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,
|
|
|
|
.freq_offset_khz_uhf = 0,
|
|
.freq_offset_khz_vhf = 0,
|
|
|
|
.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,
|
|
.force_cband_input = 0,
|
|
.is_dib7090e = 0,
|
|
.force_crystal_mode = 1,
|
|
};
|
|
|
|
static 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,
|
|
|
|
.freq_offset_khz_uhf = 50,
|
|
.freq_offset_khz_vhf = 70,
|
|
|
|
.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,
|
|
|
|
.freq_offset_khz_uhf = -50,
|
|
.freq_offset_khz_vhf = -70,
|
|
|
|
.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)
|
|
{
|
|
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);
|
|
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(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
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.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
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;
|
|
}
|
|
|
|
static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
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;
|
|
|
|
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;
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
|
|
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);
|
|
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
/* initialize IC 0 */
|
|
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.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
dib0700_set_i2c_speed(adap->dev, 340);
|
|
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;
|
|
|
|
state->dib7000p_ops.slave_reset(adap->fe_adap[0].fe);
|
|
|
|
return 0;
|
|
}
|
|
|
|
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 */
|
|
}
|
|
|
|
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.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
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;
|
|
|
|
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;
|
|
return 0;
|
|
}
|
|
|
|
static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
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;
|
|
|
|
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;
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
|
|
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);
|
|
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
msleep(20);
|
|
dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(20);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
|
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap,
|
|
1, 0x10, &tfe7790p_dib7000p_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
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;
|
|
}
|
|
|
|
static int tfe7790p_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_adapter_state *st = adap->priv;
|
|
struct i2c_adapter *tun_i2c =
|
|
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;
|
|
|
|
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;
|
|
return 0;
|
|
}
|
|
|
|
/* STK7070PD */
|
|
static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
|
|
{
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &dib7070_agc_config,
|
|
.bw = &dib7070_bw_config_12_mhz,
|
|
.tuner_is_baseband = 1,
|
|
.spur_protect = 1,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
|
.hostbus_diversity = 1,
|
|
}, {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &dib7070_agc_config,
|
|
.bw = &dib7070_bw_config_12_mhz,
|
|
.tuner_is_baseband = 1,
|
|
.spur_protect = 1,
|
|
|
|
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
|
|
|
|
.hostbus_diversity = 1,
|
|
}
|
|
};
|
|
|
|
static void stk7070pd_init(struct dvb_usb_device *dev)
|
|
{
|
|
dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
|
|
msleep(10);
|
|
dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
|
|
dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
|
|
dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
|
|
dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
|
|
|
|
dib0700_ctrl_clock(dev, 72, 1);
|
|
|
|
msleep(10);
|
|
dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
|
|
}
|
|
|
|
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 (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
|
|
stk7070pd_dib7000p_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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,
|
|
enum fe_status *stat)
|
|
{
|
|
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
struct dvb_usb_device *dev = adap->dev;
|
|
struct dib0700_state *state = dev->priv;
|
|
int ret;
|
|
|
|
ret = state->read_status(fe, stat);
|
|
|
|
if (!ret)
|
|
dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
|
|
!!(*stat & FE_HAS_LOCK));
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int novatd_sleep_override(struct dvb_frontend* fe)
|
|
{
|
|
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
|
struct dvb_usb_device *dev = adap->dev;
|
|
struct dib0700_state *state = dev->priv;
|
|
|
|
/* turn off LED */
|
|
dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
|
|
|
|
return state->sleep(fe);
|
|
}
|
|
|
|
/*
|
|
* novatd_frontend_attach - Nova-TD specific attach
|
|
*
|
|
* Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
|
|
* information purposes.
|
|
*/
|
|
static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
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);
|
|
|
|
/* turn the power LED on, the other two off (just in case) */
|
|
dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
|
|
dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
|
|
dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
|
|
|
|
if (state->dib7000p_ops.i2c_enumeration(&dev->i2c_adap, 2, 18,
|
|
stk7070pd_dib7000p_config) != 0) {
|
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
|
__func__);
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&dev->i2c_adap,
|
|
adap->id == 0 ? 0x80 : 0x82,
|
|
&stk7070pd_dib7000p_config[adap->id]);
|
|
|
|
if (adap->fe_adap[0].fe == NULL)
|
|
return -ENODEV;
|
|
|
|
st->read_status = adap->fe_adap[0].fe->ops.read_status;
|
|
adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
|
|
st->sleep = adap->fe_adap[0].fe->ops.sleep;
|
|
adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* S5H1411 */
|
|
static struct s5h1411_config pinnacle_801e_config = {
|
|
.output_mode = S5H1411_PARALLEL_OUTPUT,
|
|
.gpio = S5H1411_GPIO_OFF,
|
|
.mpeg_timing = S5H1411_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK,
|
|
.qam_if = S5H1411_IF_44000,
|
|
.vsb_if = S5H1411_IF_44000,
|
|
.inversion = S5H1411_INVERSION_OFF,
|
|
.status_mode = S5H1411_DEMODLOCKING
|
|
};
|
|
|
|
/* Pinnacle PCTV HD Pro 801e GPIOs map:
|
|
GPIO0 - currently unknown
|
|
GPIO1 - xc5000 tuner reset
|
|
GPIO2 - CX25843 sleep
|
|
GPIO3 - currently unknown
|
|
GPIO4 - currently unknown
|
|
GPIO6 - currently unknown
|
|
GPIO7 - currently unknown
|
|
GPIO9 - currently unknown
|
|
GPIO10 - CX25843 reset
|
|
*/
|
|
static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_state *st = adap->dev->priv;
|
|
|
|
/* Make use of the new i2c functions from FW 1.20 */
|
|
st->fw_use_new_i2c_api = 1;
|
|
|
|
/* The s5h1411 requires the dib0700 to not be in master mode */
|
|
st->disable_streaming_master_mode = 1;
|
|
|
|
/* All msleep values taken from Windows USB trace */
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
|
|
dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
msleep(400);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
msleep(60);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
|
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, GPIO2, GPIO_OUT, 0);
|
|
msleep(30);
|
|
|
|
/* Put the CX25843 to sleep for now since we're in digital mode */
|
|
dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
|
|
|
|
/* GPIOs are initialized, do the attach */
|
|
adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
|
|
&adap->dev->i2c_adap);
|
|
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int dib0700_xc5000_tuner_callback(void *priv, int component,
|
|
int command, int arg)
|
|
{
|
|
struct dvb_usb_adapter *adap = priv;
|
|
|
|
if (command == XC5000_TUNER_RESET) {
|
|
/* Reset the tuner */
|
|
dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
|
|
msleep(10);
|
|
dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
|
|
msleep(10);
|
|
} else {
|
|
err("xc5000: unknown tuner callback command: %d\n", command);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct xc5000_config s5h1411_xc5000_tunerconfig = {
|
|
.i2c_address = 0x64,
|
|
.if_khz = 5380,
|
|
};
|
|
|
|
static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
/* FIXME: generalize & move to common area */
|
|
adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback;
|
|
|
|
return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
|
|
&s5h1411_xc5000_tunerconfig)
|
|
== NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int dib0700_xc4000_tuner_callback(void *priv, int component,
|
|
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 */
|
|
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);
|
|
} else {
|
|
err("xc4000: unknown tuner callback command: %d\n", command);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
|
|
.band_caps = BAND_UHF | BAND_VHF,
|
|
.setup = 0x64,
|
|
.inv_gain = 0x02c8,
|
|
.time_stabiliz = 0x15,
|
|
.alpha_level = 0x00,
|
|
.thlock = 0x76,
|
|
.wbd_inv = 0x01,
|
|
.wbd_ref = 0x0b33,
|
|
.wbd_sel = 0x00,
|
|
.wbd_alpha = 0x02,
|
|
.agc1_max = 0x00,
|
|
.agc1_min = 0x00,
|
|
.agc2_max = 0x9b26,
|
|
.agc2_min = 0x26ca,
|
|
.agc1_pt1 = 0x00,
|
|
.agc1_pt2 = 0x00,
|
|
.agc1_pt3 = 0x00,
|
|
.agc1_slope1 = 0x00,
|
|
.agc1_slope2 = 0x00,
|
|
.agc2_pt1 = 0x00,
|
|
.agc2_pt2 = 0x80,
|
|
.agc2_slope1 = 0x1d,
|
|
.agc2_slope2 = 0x1d,
|
|
.alpha_mant = 0x11,
|
|
.alpha_exp = 0x1b,
|
|
.beta_mant = 0x17,
|
|
.beta_exp = 0x33,
|
|
.perform_agc_softsplit = 0x00,
|
|
};
|
|
|
|
static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
|
|
.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 */
|
|
static struct dib7000p_config pctv_340e_config = {
|
|
.output_mpeg2_in_188_bytes = 1,
|
|
|
|
.agc_config_count = 1,
|
|
.agc = &stk7700p_7000p_xc4000_agc_config,
|
|
.bw = &stk7700p_xc4000_pll_config,
|
|
|
|
.gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
|
|
.gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
|
|
.gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
|
|
};
|
|
|
|
/* PCTV 340e GPIOs map:
|
|
dib0700:
|
|
GPIO2 - CX25843 sleep
|
|
GPIO3 - CS5340 reset
|
|
GPIO5 - IRD
|
|
GPIO6 - Power Supply
|
|
GPIO8 - LNA (1=off 0=on)
|
|
GPIO10 - CX25843 reset
|
|
dib7000:
|
|
GPIO8 - xc4000 reset
|
|
*/
|
|
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);
|
|
msleep(50);
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
msleep(100); /* Allow power supply to settle before probing */
|
|
|
|
/* cx25843 reset */
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
msleep(1); /* cx25843 datasheet say 350us required */
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
|
|
/* LNA off for now */
|
|
dib0700_set_gpio(adap->dev, GPIO8, GPIO_OUT, 1);
|
|
|
|
/* Put the CX25843 to sleep for now since we're in digital mode */
|
|
dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
|
|
|
|
/* FIXME: not verified yet */
|
|
dib0700_ctrl_clock(adap->dev, 72, 1);
|
|
|
|
msleep(500);
|
|
|
|
if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
|
|
/* Demodulator not found for some reason? */
|
|
dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
|
return -ENODEV;
|
|
}
|
|
|
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x12,
|
|
&pctv_340e_config);
|
|
st->is_dib7000pc = 1;
|
|
|
|
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static struct xc4000_config dib7000p_xc4000_tunerconfig = {
|
|
.i2c_address = 0x61,
|
|
.default_pm = 1,
|
|
.dvb_amplitude = 0,
|
|
.set_smoothedcvbs = 0,
|
|
.if_khz = 5400
|
|
};
|
|
|
|
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 = 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");
|
|
return 0;
|
|
}
|
|
|
|
/* Setup the reset callback */
|
|
adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback;
|
|
|
|
return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c,
|
|
&dib7000p_xc4000_tunerconfig)
|
|
== NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static struct lgdt3305_config hcw_lgdt3305_config = {
|
|
.i2c_addr = 0x0e,
|
|
.mpeg_mode = LGDT3305_MPEG_PARALLEL,
|
|
.tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
|
|
.tpvalid_polarity = LGDT3305_TP_VALID_LOW,
|
|
.deny_i2c_rptr = 0,
|
|
.spectral_inversion = 1,
|
|
.qam_if_khz = 6000,
|
|
.vsb_if_khz = 6000,
|
|
.usref_8vsb = 0x0500,
|
|
};
|
|
|
|
static struct mxl5007t_config hcw_mxl5007t_config = {
|
|
.xtal_freq_hz = MxL_XTAL_25_MHZ,
|
|
.if_freq_hz = MxL_IF_6_MHZ,
|
|
.invert_if = 1,
|
|
};
|
|
|
|
/* TIGER-ATSC map:
|
|
GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
|
|
GPIO1 - ANT_SEL (H: VPA, L: MCX)
|
|
GPIO4 - SCL2
|
|
GPIO6 - EN_TUNER
|
|
GPIO7 - SDA2
|
|
GPIO10 - DEM_RST
|
|
|
|
MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
|
|
*/
|
|
static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_state *st = adap->dev->priv;
|
|
|
|
/* Make use of the new i2c functions from FW 1.20 */
|
|
st->fw_use_new_i2c_api = 1;
|
|
|
|
st->disable_streaming_master_mode = 1;
|
|
|
|
/* fe power enable */
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
msleep(30);
|
|
|
|
/* demod reset */
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(30);
|
|
|
|
adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach,
|
|
&hcw_lgdt3305_config,
|
|
&adap->dev->i2c_adap);
|
|
|
|
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
|
|
&adap->dev->i2c_adap, 0x60,
|
|
&hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
|
|
}
|
|
|
|
static int xbox_one_attach(struct dvb_usb_adapter *adap)
|
|
{
|
|
struct dib0700_state *st = adap->dev->priv;
|
|
struct i2c_client *client_demod, *client_tuner;
|
|
struct dvb_usb_device *d = adap->dev;
|
|
struct mn88472_config mn88472_config = { };
|
|
struct tda18250_config tda18250_config;
|
|
struct i2c_board_info info;
|
|
|
|
st->fw_use_new_i2c_api = 1;
|
|
st->disable_streaming_master_mode = 1;
|
|
|
|
/* fe power enable */
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
|
msleep(30);
|
|
|
|
/* demod reset */
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
|
msleep(30);
|
|
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
|
msleep(30);
|
|
|
|
/* attach demod */
|
|
mn88472_config.fe = &adap->fe_adap[0].fe;
|
|
mn88472_config.i2c_wr_max = 22;
|
|
mn88472_config.xtal = 20500000;
|
|
mn88472_config.ts_mode = PARALLEL_TS_MODE;
|
|
mn88472_config.ts_clock = FIXED_TS_CLOCK;
|
|
memset(&info, 0, sizeof(struct i2c_board_info));
|
|
strscpy(info.type, "mn88472", I2C_NAME_SIZE);
|
|
info.addr = 0x18;
|
|
info.platform_data = &mn88472_config;
|
|
request_module(info.type);
|
|
client_demod = i2c_new_device(&d->i2c_adap, &info);
|
|
if (client_demod == NULL || client_demod->dev.driver == NULL)
|
|
goto fail_demod_device;
|
|
if (!try_module_get(client_demod->dev.driver->owner))
|
|
goto fail_demod_module;
|
|
|
|
st->i2c_client_demod = client_demod;
|
|
|
|
adap->fe_adap[0].fe = mn88472_config.get_dvb_frontend(client_demod);
|
|
|
|
/* attach tuner */
|
|
memset(&tda18250_config, 0, sizeof(tda18250_config));
|
|
tda18250_config.if_dvbt_6 = 3950;
|
|
tda18250_config.if_dvbt_7 = 4450;
|
|
tda18250_config.if_dvbt_8 = 4950;
|
|
tda18250_config.if_dvbc_6 = 4950;
|
|
tda18250_config.if_dvbc_8 = 4950;
|
|
tda18250_config.if_atsc = 4079;
|
|
tda18250_config.loopthrough = true;
|
|
tda18250_config.xtal_freq = TDA18250_XTAL_FREQ_27MHZ;
|
|
tda18250_config.fe = adap->fe_adap[0].fe;
|
|
|
|
memset(&info, 0, sizeof(struct i2c_board_info));
|
|
strscpy(info.type, "tda18250", I2C_NAME_SIZE);
|
|
info.addr = 0x60;
|
|
info.platform_data = &tda18250_config;
|
|
|
|
request_module(info.type);
|
|
client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info);
|
|
if (client_tuner == NULL || client_tuner->dev.driver == NULL)
|
|
goto fail_tuner_device;
|
|
if (!try_module_get(client_tuner->dev.driver->owner))
|
|
goto fail_tuner_module;
|
|
|
|
st->i2c_client_tuner = client_tuner;
|
|
return 0;
|
|
|
|
fail_tuner_module:
|
|
i2c_unregister_device(client_tuner);
|
|
fail_tuner_device:
|
|
module_put(client_demod->dev.driver->owner);
|
|
fail_demod_module:
|
|
i2c_unregister_device(client_demod);
|
|
fail_demod_device:
|
|
return -ENODEV;
|
|
}
|
|
|
|
|
|
/* DVB-USB and USB stuff follows */
|
|
struct usb_device_id dib0700_usb_id_table[] = {
|
|
/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
|
|
/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
|
|
{ USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
|
|
{ USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
|
|
{ USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
|
|
/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC,
|
|
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
|
|
/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE,
|
|
USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
|
|
{ USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
|
|
/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
|
|
{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
|
|
{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
|
|
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
|
|
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
|
|
/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
|
|
/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
|
|
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
|
|
{ USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
|
|
/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
|
|
{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
|
|
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
|
|
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
|
|
/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC,
|
|
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
|
|
{ USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
|
|
/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
|
|
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
|
|
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
|
|
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
|
|
/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
|
|
{ USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
|
|
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
|
|
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
|
|
/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
|
|
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
|
|
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
|
|
/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
|
|
{ USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
|
|
{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
|
|
/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
|
|
{ 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) },
|
|
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
|
|
/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) },
|
|
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) },
|
|
{ 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) },
|
|
{ USB_DEVICE(USB_VID_PCTV, USB_PID_DIBCOM_STK8096PVR) },
|
|
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096PVR) },
|
|
/* 85 */{ USB_DEVICE(USB_VID_HAMA, USB_PID_HAMA_DVBT_HYBRID) },
|
|
{ USB_DEVICE(USB_VID_MICROSOFT, USB_PID_XBOX_ONE_TUNER) },
|
|
{ 0 } /* Terminating entry */
|
|
};
|
|
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
|
|
|
|
#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
|
|
.caps = DVB_USB_IS_AN_I2C_ADAPTER, \
|
|
.usb_ctrl = DEVICE_SPECIFIC, \
|
|
.firmware = "dvb-usb-dib0700-1.20.fw", \
|
|
.download_firmware = dib0700_download_firmware, \
|
|
.no_reconnect = 1, \
|
|
.size_of_priv = sizeof(struct dib0700_state), \
|
|
.i2c_algo = &dib0700_i2c_algo, \
|
|
.identify_state = dib0700_identify_state
|
|
|
|
#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
|
|
.streaming_ctrl = dib0700_streaming_ctrl, \
|
|
.stream = { \
|
|
.type = USB_BULK, \
|
|
.count = 4, \
|
|
.endpoint = ep, \
|
|
.u = { \
|
|
.bulk = { \
|
|
.buffersize = 39480, \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#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,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk7700p_pid_filter,
|
|
.pid_filter_ctrl = stk7700p_pid_filter_ctrl,
|
|
.frontend_attach = stk7700p_frontend_attach,
|
|
.tuner_attach = stk7700p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 8,
|
|
.devices = {
|
|
{ "DiBcom STK7700P reference design",
|
|
{ &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge Nova-T Stick",
|
|
{ &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "AVerMedia AVerTV DVB-T Volar",
|
|
{ &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
|
|
{ NULL },
|
|
},
|
|
{ "Compro Videomate U500",
|
|
{ &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
|
|
{ NULL },
|
|
},
|
|
{ "Uniwill STK7700P based (Hama and others)",
|
|
{ &dib0700_usb_id_table[7], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Leadtek Winfast DTV Dongle (STK7700P based)",
|
|
{ &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
|
|
{ NULL },
|
|
},
|
|
{ "AVerMedia AVerTV DVB-T Express",
|
|
{ &dib0700_usb_id_table[20] },
|
|
{ NULL },
|
|
},
|
|
{ "Gigabyte U7000",
|
|
{ &dib0700_usb_id_table[21], NULL },
|
|
{ NULL },
|
|
}
|
|
},
|
|
|
|
.rc.core = {
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = bristol_frontend_attach,
|
|
.tuner_attach = bristol_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
}, {
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = bristol_frontend_attach,
|
|
.tuner_attach = bristol_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
}
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "Hauppauge Nova-T 500 Dual DVB-T",
|
|
{ &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
|
|
{ NULL },
|
|
},
|
|
},
|
|
|
|
.rc.core = {
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7700d_frontend_attach,
|
|
.tuner_attach = stk7700d_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
}, {
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7700d_frontend_attach,
|
|
.tuner_attach = stk7700d_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
}
|
|
},
|
|
|
|
.num_device_descs = 5,
|
|
.devices = {
|
|
{ "Pinnacle PCTV 2000e",
|
|
{ &dib0700_usb_id_table[11], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Terratec Cinergy DT XS Diversity",
|
|
{ &dib0700_usb_id_table[12], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
|
|
{ &dib0700_usb_id_table[13], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "DiBcom STK7700D reference design",
|
|
{ &dib0700_usb_id_table[14], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "YUAN High-Tech DiBcom STK7700D",
|
|
{ &dib0700_usb_id_table[55], NULL },
|
|
{ NULL },
|
|
},
|
|
|
|
},
|
|
|
|
.rc.core = {
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7700P2_frontend_attach,
|
|
.tuner_attach = stk7700d_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 3,
|
|
.devices = {
|
|
{ "ASUS My Cinema U3000 Mini DVBT Tuner",
|
|
{ &dib0700_usb_id_table[23], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Yuan EC372S",
|
|
{ &dib0700_usb_id_table[31], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Terratec Cinergy T Express",
|
|
{ &dib0700_usb_id_table[42], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070p_frontend_attach,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 12,
|
|
.devices = {
|
|
{ "DiBcom STK7070P reference design",
|
|
{ &dib0700_usb_id_table[15], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV DVB-T Flash Stick",
|
|
{ &dib0700_usb_id_table[16], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Artec T14BR DVB-T",
|
|
{ &dib0700_usb_id_table[22], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "ASUS My Cinema U3100 Mini DVBT Tuner",
|
|
{ &dib0700_usb_id_table[24], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge Nova-T Stick",
|
|
{ &dib0700_usb_id_table[25], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge Nova-T MyTV.t",
|
|
{ &dib0700_usb_id_table[26], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV 72e",
|
|
{ &dib0700_usb_id_table[29], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV 73e",
|
|
{ &dib0700_usb_id_table[30], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Elgato EyeTV DTT",
|
|
{ &dib0700_usb_id_table[49], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Yuan PD378S",
|
|
{ &dib0700_usb_id_table[45], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Elgato EyeTV Dtt Dlx PD378S",
|
|
{ &dib0700_usb_id_table[50], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Elgato EyeTV DTT rev. 2",
|
|
{ &dib0700_usb_id_table[80], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070p_frontend_attach,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 3,
|
|
.devices = {
|
|
{ "Pinnacle PCTV 73A",
|
|
{ &dib0700_usb_id_table[56], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV 73e SE",
|
|
{ &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV 282e",
|
|
{ &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = novatd_frontend_attach,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
}, {
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = novatd_frontend_attach,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
}
|
|
},
|
|
|
|
.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 = {
|
|
.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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070pd_frontend_attach0,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
}, {
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070pd_frontend_attach1,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
}
|
|
},
|
|
|
|
.num_device_descs = 5,
|
|
.devices = {
|
|
{ "DiBcom STK7070PD reference design",
|
|
{ &dib0700_usb_id_table[17], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV Dual DVB-T Diversity Stick",
|
|
{ &dib0700_usb_id_table[18], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge Nova-TD-500 (84xxx)",
|
|
{ &dib0700_usb_id_table[36], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Terratec Cinergy DT USB XS Diversity/ T5",
|
|
{ &dib0700_usb_id_table[43],
|
|
&dib0700_usb_id_table[53], NULL},
|
|
{ NULL },
|
|
},
|
|
{ "Sony PlayTV",
|
|
{ &dib0700_usb_id_table[44], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070pd_frontend_attach0,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
}, {
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7070pd_frontend_attach1,
|
|
.tuner_attach = dib7070p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
}
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "Elgato EyeTV Diversity",
|
|
{ &dib0700_usb_id_table[68], NULL },
|
|
{ NULL },
|
|
},
|
|
},
|
|
|
|
.rc.core = {
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
|
|
.module_name = "dib0700",
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7700ph_frontend_attach,
|
|
.tuner_attach = stk7700ph_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 10,
|
|
.devices = {
|
|
{ "Terratec Cinergy HT USB XE",
|
|
{ &dib0700_usb_id_table[27], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle Expresscard 320cx",
|
|
{ &dib0700_usb_id_table[28], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Terratec Cinergy HT Express",
|
|
{ &dib0700_usb_id_table[32], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Gigabyte U8000-RH",
|
|
{ &dib0700_usb_id_table[37], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "YUAN High-Tech STK7700PH",
|
|
{ &dib0700_usb_id_table[38], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Asus My Cinema-U3000Hybrid",
|
|
{ &dib0700_usb_id_table[39], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "YUAN High-Tech MC770",
|
|
{ &dib0700_usb_id_table[48], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Leadtek WinFast DTV Dongle H",
|
|
{ &dib0700_usb_id_table[51], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "YUAN High-Tech STK7700D",
|
|
{ &dib0700_usb_id_table[54], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hama DVB=T Hybrid USB Stick",
|
|
{ &dib0700_usb_id_table[85], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = s5h1411_frontend_attach,
|
|
.tuner_attach = xc5000_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 2,
|
|
.devices = {
|
|
{ "Pinnacle PCTV HD Pro USB Stick",
|
|
{ &dib0700_usb_id_table[40], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV HD USB Stick",
|
|
{ &dib0700_usb_id_table[41], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = lgdt3305_frontend_attach,
|
|
.tuner_attach = mxl5007t_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 2,
|
|
.devices = {
|
|
{ "Hauppauge ATSC MiniCard (B200)",
|
|
{ &dib0700_usb_id_table[46], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Hauppauge ATSC MiniCard (B210)",
|
|
{ &dib0700_usb_id_table[47], NULL },
|
|
{ NULL },
|
|
},
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = stk7770p_frontend_attach,
|
|
.tuner_attach = dib7770p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 4,
|
|
.devices = {
|
|
{ "DiBcom STK7770P reference design",
|
|
{ &dib0700_usb_id_table[59], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Terratec Cinergy T USB XXS (HD)/ T3",
|
|
{ &dib0700_usb_id_table[33],
|
|
&dib0700_usb_id_table[52],
|
|
&dib0700_usb_id_table[60], NULL},
|
|
{ NULL },
|
|
},
|
|
{ "TechniSat AirStar TeleStick 2",
|
|
{ &dib0700_usb_id_table[74], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Medion CTX1921 DVB-T USB",
|
|
{ &dib0700_usb_id_table[75], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk80xx_pid_filter,
|
|
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
.frontend_attach = stk807x_frontend_attach,
|
|
.tuner_attach = dib807x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 3,
|
|
.devices = {
|
|
{ "DiBcom STK807xP reference design",
|
|
{ &dib0700_usb_id_table[62], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Prolink Pixelview SBTVD",
|
|
{ &dib0700_usb_id_table[63], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "EvolutePC TVWay+",
|
|
{ &dib0700_usb_id_table[64], NULL },
|
|
{ NULL },
|
|
},
|
|
},
|
|
|
|
.rc.core = {
|
|
.rc_interval = DEFAULT_RC_INTERVAL,
|
|
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
|
|
.module_name = "dib0700",
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk80xx_pid_filter,
|
|
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
.frontend_attach = stk807xpvr_frontend_attach0,
|
|
.tuner_attach = dib807x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
{
|
|
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,
|
|
.pid_filter = stk80xx_pid_filter,
|
|
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
.frontend_attach = stk807xpvr_frontend_attach1,
|
|
.tuner_attach = dib807x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "DiBcom STK807xPVR reference design",
|
|
{ &dib0700_usb_id_table[61], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk80xx_pid_filter,
|
|
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
.frontend_attach = stk809x_frontend_attach,
|
|
.tuner_attach = dib809x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "DiBcom STK8096GP reference design",
|
|
{ &dib0700_usb_id_table[67], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
{
|
|
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,
|
|
.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),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.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,
|
|
.module_name = "dib0700",
|
|
.rc_query = dib0700_rc_query_old_firmware,
|
|
.allowed_protos = RC_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = pctv340e_frontend_attach,
|
|
.tuner_attach = xc4000_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
}},
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 2,
|
|
.devices = {
|
|
{ "Pinnacle PCTV 340e HD Pro USB Stick",
|
|
{ &dib0700_usb_id_table[76], NULL },
|
|
{ NULL },
|
|
},
|
|
{ "Pinnacle PCTV Hybrid Stick Solo",
|
|
{ &dib0700_usb_id_table[77], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk70x0p_pid_filter,
|
|
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
|
|
.frontend_attach = tfe7790p_frontend_attach,
|
|
.tuner_attach = tfe7790p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
} },
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "DiBcom TFE7790P reference design",
|
|
{ &dib0700_usb_id_table[78], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
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,
|
|
.pid_filter = stk80xx_pid_filter,
|
|
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
|
.frontend_attach = tfe8096p_frontend_attach,
|
|
.tuner_attach = tfe8096p_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
|
|
} },
|
|
},
|
|
},
|
|
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "DiBcom TFE8096P reference design",
|
|
{ &dib0700_usb_id_table[79], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 2,
|
|
.adapter = {
|
|
{
|
|
.num_frontends = 1,
|
|
.fe = {{
|
|
.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 = stk809x_frontend_attach,
|
|
.tuner_attach = dib809x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
|
} },
|
|
.size_of_priv =
|
|
sizeof(struct dib0700_adapter_state),
|
|
}, {
|
|
.num_frontends = 1,
|
|
.fe = { {
|
|
.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 = stk809x_frontend1_attach,
|
|
.tuner_attach = dib809x_tuner_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
|
|
} },
|
|
.size_of_priv =
|
|
sizeof(struct dib0700_adapter_state),
|
|
},
|
|
},
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "DiBcom STK8096-PVR reference design",
|
|
{ &dib0700_usb_id_table[83],
|
|
&dib0700_usb_id_table[84], 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_PROTO_BIT_RC5 |
|
|
RC_PROTO_BIT_RC6_MCE |
|
|
RC_PROTO_BIT_NEC,
|
|
.change_protocol = dib0700_change_protocol,
|
|
},
|
|
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
|
.num_adapters = 1,
|
|
.adapter = {
|
|
{
|
|
DIB0700_NUM_FRONTENDS(1),
|
|
.fe = {{
|
|
.frontend_attach = xbox_one_attach,
|
|
|
|
DIB0700_DEFAULT_STREAMING_CONFIG(0x82),
|
|
} },
|
|
},
|
|
},
|
|
.num_device_descs = 1,
|
|
.devices = {
|
|
{ "Microsoft Xbox One Digital TV Tuner",
|
|
{ &dib0700_usb_id_table[86], NULL },
|
|
{ NULL },
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
|