aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h26
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c101
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c725
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c15
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c456
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c10
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c4
9 files changed, 951 insertions, 397 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 2dee1bf7357..1b249897c9f 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -265,9 +265,13 @@ config DVB_USB_DW2102
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_ZL10039 if !DVB_FE_CUSTOMISE
+ select DVB_DS3000 if !DVB_FE_CUSTOMISE
+ select DVB_STB6100 if !DVB_FE_CUSTOMISE
+ select DVB_STV6110 if !DVB_FE_CUSTOMISE
+ select DVB_STV0900 if !DVB_FE_CUSTOMISE
help
- Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
- and the TeVii S650, S630.
+ Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
+ receivers.
config DVB_USB_CINERGY_T2
tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 8b544fe79b0..495a90577c5 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug;
#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
-#define REQUEST_I2C_READ 0x2
-#define REQUEST_I2C_WRITE 0x3
-#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
-#define REQUEST_JUMPRAM 0x8
-#define REQUEST_SET_CLOCK 0xB
-#define REQUEST_SET_GPIO 0xC
-#define REQUEST_ENABLE_VIDEO 0xF
+#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
+ /* higher than 1.21 */
+#define REQUEST_I2C_READ 0x2
+#define REQUEST_I2C_WRITE 0x3
+#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
+#define REQUEST_JUMPRAM 0x8
+#define REQUEST_SET_CLOCK 0xB
+#define REQUEST_SET_GPIO 0xC
+#define REQUEST_ENABLE_VIDEO 0xF
// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
-#define REQUEST_SET_RC 0x11
-#define REQUEST_NEW_I2C_READ 0x12
-#define REQUEST_NEW_I2C_WRITE 0x13
-#define REQUEST_GET_VERSION 0x15
+#define REQUEST_SET_RC 0x11
+#define REQUEST_NEW_I2C_READ 0x12
+#define REQUEST_NEW_I2C_WRITE 0x13
+#define REQUEST_GET_VERSION 0x15
struct dib0700_state {
u8 channel_state;
@@ -44,6 +46,8 @@ struct dib0700_state {
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
+ u32 fw_version;
+ u32 nb_packet_buffer_size;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index db7f7f79a66..0d3c9a9a33b 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1;
module_param(dvb_usb_dib0700_ir_proto, int, 0644);
MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
+static int nb_packet_buffer_size = 21;
+module_param(nb_packet_buffer_size, int, 0644);
+MODULE_PARM_DESC(nb_packet_buffer_size,
+ "Set the dib0700 driver data buffer size. This parameter "
+ "corresponds to the number of TS packets. The actual size of "
+ "the data buffer corresponds to this parameter "
+ "multiplied by 188 (default: 21)");
+
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
- *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
- *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
- *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
- *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
+ if (hwversion != NULL)
+ *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+ if (romversion != NULL)
+ *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
+ if (ramversion != NULL)
+ *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
+ if (fwtype != NULL)
+ *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
return ret;
}
@@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
return dib0700_ctrl_wr(d,buf,3);
}
+static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
+{
+ struct dib0700_state *st = d->priv;
+ u8 b[3];
+ int ret;
+
+ if (st->fw_version >= 0x10201) {
+ b[0] = REQUEST_SET_USB_XFER_LEN;
+ b[1] = (nb_ts_packets >> 8)&0xff;
+ b[2] = nb_ts_packets & 0xff;
+
+ deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
+
+ ret = dib0700_ctrl_wr(d, b, 3);
+ } else {
+ deb_info("this firmware does not allow to change the USB xfer len\n");
+ ret = -EIO;
+ }
+ return ret;
+}
+
/*
* I2C master xfer function (supported in 1.20 firmware)
*/
@@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address)
int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
{
struct hexline hx;
- int pos = 0, ret, act_len;
+ int pos = 0, ret, act_len, i, adap_num;
+ u8 b[16];
+ u32 fw_version;
u8 buf[260];
@@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
} else
ret = -EIO;
+ /* the number of ts packet has to be at least 1 */
+ if (nb_packet_buffer_size < 1)
+ nb_packet_buffer_size = 1;
+
+ /* get the fimware version */
+ usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REQUEST_GET_VERSION,
+ USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+ b, sizeof(b), USB_CTRL_GET_TIMEOUT);
+ fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
+
+ /* set the buffer size - DVB-USB is allocating URB buffers
+ * only after the firwmare download was successful */
+ for (i = 0; i < dib0700_device_count; i++) {
+ for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
+ adap_num++) {
+ if (fw_version >= 0x10201)
+ dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
+ else {
+ /* for fw version older than 1.20.1,
+ * the buffersize has to be n times 512 */
+ dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
+ if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
+ dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
+ }
+ }
+ }
+
return ret;
}
@@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct dib0700_state *st = adap->dev->priv;
u8 b[4];
+ int ret;
+
+ if ((onoff != 0) && (st->fw_version >= 0x10201)) {
+ /* for firmware later than 1.20.1,
+ * the USB xfer length can be set */
+ ret = dib0700_set_usb_xfer_len(adap->dev,
+ st->nb_packet_buffer_size);
+ if (ret < 0) {
+ deb_info("can not set the USB xfer len\n");
+ return ret;
+ }
+ }
b[0] = REQUEST_ENABLE_VIDEO;
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
@@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf,
for (i = 0; i < dib0700_device_count; i++)
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
- &dev, adapter_nr) == 0)
- {
+ &dev, adapter_nr) == 0) {
+ struct dib0700_state *st = dev->priv;
+ u32 hwversion, romversion, fw_version, fwtype;
+
+ dib0700_get_version(dev, &hwversion, &romversion,
+ &fw_version, &fwtype);
+
+ deb_info("Firmware version: %x, %d, 0x%x, %d\n",
+ hwversion, romversion, fw_version, fwtype);
+
+ st->fw_version = fw_version;
+ st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
+
dib0700_rc_setup(dev);
+
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 684146f98eb..44972d01bbd 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -18,6 +18,7 @@
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h"
+#include "dib0090.h"
#include "lgdt3305.h"
#include "mxl5007t.h"
@@ -130,93 +131,95 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
/* MT226x */
static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
{
- BAND_UHF, // 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=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), // setup
-
- 1130, // inv_gain
- 21, // time_stabiliz
-
- 0, // alpha_level
- 118, // thlock
-
- 0, // wbd_inv
- 3530, // wbd_ref
- 1, // wbd_sel
- 0, // wbd_alpha
-
- 65535, // agc1_max
- 33770, // agc1_min
- 65535, // agc2_max
- 23592, // agc2_min
-
- 0, // agc1_pt1
- 62, // agc1_pt2
- 255, // agc1_pt3
- 64, // agc1_slope1
- 64, // agc1_slope2
- 132, // agc2_pt1
- 192, // agc2_pt2
- 80, // agc2_slope1
- 80, // agc2_slope2
-
- 17, // alpha_mant
- 27, // alpha_exp
- 23, // beta_mant
- 51, // beta_exp
-
- 1, // perform_agc_softsplit
+ (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, // band_caps
+ 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), // setup
-
- 2372, // inv_gain
- 21, // time_stabiliz
-
- 0, // alpha_level
- 118, // thlock
-
- 0, // wbd_inv
- 3530, // wbd_ref
- 1, // wbd_sel
- 0, // wbd_alpha
-
- 65535, // agc1_max
- 0, // agc1_min
- 65535, // agc2_max
- 23592, // agc2_min
-
- 0, // agc1_pt1
- 128, // agc1_pt2
- 128, // agc1_pt3
- 128, // agc1_slope1
- 0, // agc1_slope2
- 128, // agc2_pt1
- 253, // agc2_pt2
- 81, // agc2_slope1
- 0, // agc2_slope2
-
- 17, // alpha_mant
- 27, // alpha_exp
- 23, // beta_mant
- 51, // beta_exp
-
- 1, // perform_agc_softsplit
+ (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 = {
- 60000, 30000, // internal, sampling
- 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
- 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
- (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
- 0, // ifreq
- 20452225, // timf
+ 60000, 30000,
+ 1, 8, 3, 1, 0,
+ 0, 0, 1, 1, 2,
+ (3 << 14) | (1 << 12) | (524 << 0),
+ 0,
+ 20452225,
};
static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
@@ -605,17 +608,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
}
break;
default:
- if (actlen != sizeof(buf)) {
- /* We didn't get back the 6 byte message we expected */
- err("Unexpected RC response size [%d]", actlen);
- return -1;
- }
+ if (actlen != sizeof(buf)) {
+ /* We didn't get back the 6 byte message we expected */
+ err("Unexpected RC response size [%d]", actlen);
+ return -1;
+ }
- poll_reply.report_id = buf[0];
- poll_reply.data_state = buf[1];
+ poll_reply.report_id = buf[0];
+ poll_reply.data_state = buf[1];
poll_reply.system = (buf[2] << 8) | buf[3];
- poll_reply.data = buf[4];
- poll_reply.not_data = buf[5];
+ poll_reply.data = buf[4];
+ poll_reply.not_data = buf[5];
break;
}
@@ -632,7 +635,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
/* Find the key in the map */
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
- rc5_data(&keymap[i]) == poll_reply.data) {
+ rc5_data(&keymap[i]) == poll_reply.data) {
*event = keymap[i].event;
found = 1;
break;
@@ -641,8 +644,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
if (found == 0) {
err("Unknown remote controller key: %04x %02x %02x",
- poll_reply.system,
- poll_reply.data, poll_reply.not_data);
+ poll_reply.system,
+ poll_reply.data, poll_reply.not_data);
d->last_event = 0;
return 0;
}
@@ -933,47 +936,48 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
- BAND_UHF | BAND_VHF, // band_caps
+ BAND_UHF | BAND_VHF,
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
-
- 712, // inv_gain
- 41, // time_stabiliz
-
- 0, // alpha_level
- 118, // thlock
-
- 0, // wbd_inv
- 4095, // wbd_ref
- 0, // wbd_sel
- 0, // wbd_alpha
-
- 42598, // agc1_max
- 17694, // agc1_min
- 45875, // agc2_max
- 2621, // agc2_min
- 0, // agc1_pt1
- 76, // agc1_pt2
- 139, // agc1_pt3
- 52, // agc1_slope1
- 59, // agc1_slope2
- 107, // agc2_pt1
- 172, // agc2_pt2
- 57, // agc2_slope1
- 70, // agc2_slope2
-
- 21, // alpha_mant
- 25, // alpha_exp
- 28, // beta_mant
- 48, // beta_exp
-
- 1, // perform_agc_softsplit
- { 0, // split_min
- 107, // split_max
- 51800, // global_split_min
- 24700 // global_split_max
+ (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
},
};
@@ -982,54 +986,55 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
- 712, // inv_gain
- 41, // time_stabiliz
+ 712,
+ 41,
- 0, // alpha_level
- 118, // thlock
+ 0,
+ 118,
- 0, // wbd_inv
- 4095, // wbd_ref
- 0, // wbd_sel
- 0, // wbd_alpha
+ 0,
+ 4095,
+ 0,
+ 0,
- 42598, // agc1_max
- 16384, // agc1_min
- 42598, // agc2_max
- 0, // agc2_min
+ 42598,
+ 16384,
+ 42598,
+ 0,
- 0, // agc1_pt1
- 137, // agc1_pt2
- 255, // agc1_pt3
+ 0,
+ 137,
+ 255,
- 0, // agc1_slope1
- 255, // agc1_slope2
+ 0,
+ 255,
- 0, // agc2_pt1
- 0, // agc2_pt2
+ 0,
+ 0,
- 0, // agc2_slope1
- 41, // agc2_slope2
+ 0,
+ 41,
- 15, // alpha_mant
- 25, // alpha_exp
+ 15,
+ 25,
- 28, // beta_mant
- 48, // beta_exp
+ 28,
+ 48,
- 0, // perform_agc_softsplit
+ 0,
};
static struct dibx000_bandwidth_config stk7700p_pll_config = {
- 60000, 30000, // internal, sampling
- 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
- 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
- (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
- 60258167, // ifreq
- 20452225, // timf
- 30000000, // xtal
+ 60000, 30000,
+ 1, 8, 3, 1, 0,
+ 0, 0, 1, 1, 0,
+ (3 << 14) | (1 << 12) | (524 << 0),
+ 60258167,
+ 20452225,
+ 30000000,
};
static struct dib7000m_config stk7700p_dib7000m_config = {
@@ -1115,41 +1120,42 @@ static struct dibx000_agc_config dib7070_agc_config = {
BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // 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
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+ 600,
+ 10,
+
+ 0,
+ 118,
+
+ 0,
+ 3530,
+ 1,
+ 5,
+
+ 65535,
+ 0,
+
+ 65535,
+ 0,
+
+ 0,
+ 40,
+ 183,
+ 206,
+ 255,
+ 72,
+ 152,
+ 88,
+ 90,
+
+ 17,
+ 27,
+ 23,
+ 51,
+
+ 0,
};
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
@@ -1276,13 +1282,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
}
static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
- 60000, 15000, // internal, sampling
- 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
- 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
- (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
- (0 << 25) | 0, // ifreq = 0.000000 MHz
- 20452225, // timf
- 12000000, // xtal_hz
+ 60000, 15000,
+ 1, 20, 3, 1, 0,
+ 0, 0, 1, 1, 2,
+ (3 << 14) | (1 << 12) | (524 << 0),
+ (0 << 25) | 0,
+ 20452225,
+ 12000000,
};
static struct dib7000p_config dib7070p_dib7000p_config = {
@@ -1476,12 +1482,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = {
}
};
-static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
{
return dib8000_set_gpio(fe, 5, 0, !onoff);
}
-static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
return dib8000_set_gpio(fe, 0, 0, onoff);
}
@@ -1494,8 +1500,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
static struct dib0070_config dib807x_dib0070_config[2] = {
{
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
- .reset = dib807x_tuner_reset,
- .sleep = dib807x_tuner_sleep,
+ .reset = dib80xx_tuner_reset,
+ .sleep = dib80xx_tuner_sleep,
.clock_khz = 12000,
.clock_pad_drive = 4,
.vga_filter = 1,
@@ -1508,8 +1514,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = {
.freq_offset_khz_vhf = -100,
}, {
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
- .reset = dib807x_tuner_reset,
- .sleep = dib807x_tuner_sleep,
+ .reset = dib80xx_tuner_reset,
+ .sleep = dib80xx_tuner_sleep,
.clock_khz = 12000,
.clock_pad_drive = 2,
.vga_filter = 1,
@@ -1566,12 +1572,14 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
+ u16 pid, int onoff)
{
return dib8000_pid_filter(adapter->fe, index, pid, onoff);
}
-static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
+ int onoff)
{
return dib8000_pid_filter_ctrl(adapter->fe, onoff);
}
@@ -1624,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
/* initialize IC 0 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
&dib807x_dib8000_config[0]);
@@ -1635,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
{
/* initialize IC 1 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
&dib807x_dib8000_config[1]);
@@ -1643,6 +1651,245 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0;
}
+/* STK8096GP */
+struct dibx000_agc_config dib8090_agc_config[2] = {
+ {
+ BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+ /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+ * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+ * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+ 787,
+ 10,
+
+ 0,
+ 118,
+
+ 0,
+ 3530,
+ 1,
+ 5,
+
+ 65535,
+ 0,
+
+ 65535,
+ 0,
+
+ 0,
+ 32,
+ 114,
+ 143,
+ 144,
+ 114,
+ 227,
+ 116,
+ 117,
+
+ 28,
+ 26,
+ 31,
+ 51,
+
+ 0,
+ },
+ {
+ BAND_CBAND,
+ /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+ * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+ * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+ 787,
+ 10,
+
+ 0,
+ 118,
+
+ 0,
+ 3530,
+ 1,
+ 5,
+
+ 0,
+ 0,
+
+ 65535,
+ 0,
+
+ 0,
+ 32,
+ 114,
+ 143,
+ 144,
+ 114,
+ 227,
+ 116,
+ 117,
+
+ 28,
+ 26,
+ 31,
+ 51,
+
+ 0,
+ }
+};
+
+static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
+ 54000, 13500,
+ 1, 18, 3, 1, 0,
+ 0, 0, 1, 1, 2,
+ (3 << 14) | (1 << 12) | (599 << 0),
+ (0 << 25) | 0,
+ 20199727,
+ 12000000,
+};
+
+static int dib8090_get_adc_power(struct dvb_frontend *fe)
+{
+ return dib8000_get_adc_power(fe, 1);
+}
+
+static struct dib8000_config dib809x_dib8000_config = {
+ .output_mpeg2_in_188_bytes = 1,
+
+ .agc_config_count = 2,
+ .agc = dib8090_agc_config,
+ .agc_control = dib0090_dcc_freq,
+ .pll = &dib8090_pll_config_12mhz,
+ .tuner_is_baseband = 1,
+
+ .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+ .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+ .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+ .hostbus_diversity = 1,
+ .div_cfg = 0x31,
+ .output_mode = OUTMODE_MPEG2_FIFO,
+ .drives = 0x2d98,
+ .diversity_delay = 144,
+ .refclksel = 3,
+};
+
+static struct dib0090_config dib809x_dib0090_config = {
+ .io.pll_bypass = 1,
+ .io.pll_range = 1,
+ .io.pll_prediv = 1,
+ .io.pll_loopdiv = 20,
+ .io.adc_clock_ratio = 8,
+ .io.pll_int_loop_filt = 0,
+ .io.clock_khz = 12000,
+ .reset = dib80xx_tuner_reset,
+ .sleep = dib80xx_tuner_sleep,
+ .clkouttobamse = 1,
+ .analog_output = 1,
+ .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
+ .wbd_vhf_offset = 100,
+ .wbd_cband_offset = 450,
+ .use_pwm_agc = 1,
+ .clkoutdrive = 1,
+ .get_adc_power = dib8090_get_adc_power,
+ .freq_offset_khz_uhf = 0,
+ .freq_offset_khz_vhf = -143,
+};
+
+static int dib8096_set_param_override(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+ u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+ u16 offset;
+ int ret = 0;
+ enum frontend_tune_state tune_state = CT_SHUTDOWN;
+ u16 ltgain, rf_gain_limit;
+
+ ret = state->set_param_save(fe, fep);
+ if (ret < 0)
+ return ret;
+
+ switch (band) {
+ case BAND_VHF:
+ offset = 100;
+ break;
+ case BAND_UHF:
+ offset = 550;
+ break;
+ default:
+ offset = 0;
+ break;
+ }
+ offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
+ dib8000_set_wbd_ref(fe, offset);
+
+
+ if (band == BAND_CBAND) {
+ deb_info("tuning in CBAND - soft-AGC startup\n");
+ /* TODO specific wbd target for dib0090 - needed for startup ? */
+ dib0090_set_tune_state(fe, CT_AGC_START);
+ do {
+ ret = dib0090_gain_control(fe);
+ msleep(ret);
+ tune_state = dib0090_get_tune_state(fe);
+ if (tune_state == CT_AGC_STEP_0)
+ dib8000_set_gpio(fe, 6, 0, 1);
+ else if (tune_state == CT_AGC_STEP_1) {
+ dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
+ if (rf_gain_limit == 0)
+ dib8000_set_gpio(fe, 6, 0, 0);
+ }
+ } while (tune_state < CT_AGC_STOP);
+ dib0090_pwm_gain_reset(fe);
+ dib8000_pwm_agc_reset(fe);
+ dib8000_set_tune_state(fe, CT_DEMOD_START);
+ } else {
+ deb_info("not tuning in CBAND - standard AGC startup\n");
+ dib0090_pwm_gain_reset(fe);
+ }
+
+ return 0;
+}
+
+static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_adapter_state *st = adap->priv;
+ struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+ if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+ return -ENODEV;
+
+ st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+ adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
+ return 0;
+}
+
+static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+ dib0700_ctrl_clock(adap->dev, 72, 1);
+
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
+
+ adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
/* STK7070PD */
static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
@@ -1929,14 +2176,17 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ 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_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
- { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
+ { 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(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
{ 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) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2238,11 +2488,11 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ NULL },
},
{ "Pinnacle PCTV 73e SE",
- { &dib0700_usb_id_table[57], NULL },
+ { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
{ NULL },
},
{ "Pinnacle PCTV 282e",
- { &dib0700_usb_id_table[58], NULL },
+ { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
{ NULL },
},
},
@@ -2471,8 +2721,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk807x_pid_filter,
- .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+ .pid_filter = stk80xx_pid_filter,
+ .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
.frontend_attach = stk807x_frontend_attach,
.tuner_attach = dib807x_tuner_attach,
@@ -2510,8 +2760,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk807x_pid_filter,
- .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+ .pid_filter = stk80xx_pid_filter,
+ .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
.frontend_attach = stk807xpvr_frontend_attach0,
.tuner_attach = dib807x_tuner_attach,
@@ -2523,8 +2773,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk807x_pid_filter,
- .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+ .pid_filter = stk80xx_pid_filter,
+ .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
.frontend_attach = stk807xpvr_frontend_attach1,
.tuner_attach = dib807x_tuner_attach,
@@ -2547,6 +2797,37 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
.rc_query = dib0700_rc_query
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter_count = 32,
+ .pid_filter = stk80xx_pid_filter,
+ .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+ .frontend_attach = stk809x_frontend_attach,
+ .tuner_attach = dib809x_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv =
+ sizeof(struct dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "DiBcom STK8096GP reference design",
+ { &dib0700_usb_id_table[67], NULL },
+ { NULL },
+ },
+ },
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
},
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index da34979b533..9143b5631e8 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
} else if ((msg[i].flags & I2C_M_RD) == 0) {
if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
break;
- } else
- break;
+ } else if (msg[i].addr != 0x50) {
+ /* 0x50 is the address of the eeprom - we need to protect it
+ * from dibusb's bad i2c implementation: reads without
+ * writing the offset before are forbidden */
+ if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
+ break;
+ }
}
mutex_unlock(&d->i2c_mutex);
@@ -243,6 +248,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
{
+ if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
+ adap->dev->udev->descriptor.idProduct ==
+ USB_PID_LITEON_DVB_T_WARM) {
+ msleep(1000);
+ }
+
if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL ||
(adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
if (adap->priv != NULL) {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index f1602d4ace6..bc3581d58ce 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -47,6 +47,7 @@
#define USB_VID_MSI_2 0x1462
#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
+#define USB_VID_PCTV 0x2013
#define USB_VID_PIXELVIEW 0x1554
#define USB_VID_TECHNOTREND 0x0b48
#define USB_VID_TERRATEC 0x0ccd
@@ -101,6 +102,7 @@
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
#define USB_PID_DIBCOM_STK807XP 0x1f90
#define USB_PID_DIBCOM_STK807XPVR 0x1f98
+#define USB_PID_DIBCOM_STK8096GP 0x1fa0
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
#define USB_PID_DIBCOM_STK7770P 0x1e80
#define USB_PID_DPOSH_M9206_COLD 0x9206
@@ -211,6 +213,7 @@
#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
#define USB_PID_PINNACLE_PCTV73A 0x0243
#define USB_PID_PINNACLE_PCTV73ESE 0x0245
+#define USB_PID_PINNACLE_PCTV74E 0x0246
#define USB_PID_PINNACLE_PCTV282E 0x0248
#define USB_PID_PIXELVIEW_SBTVD 0x5010
#define USB_PID_PCTV_200E 0x020e
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 5bb9479d154..64132c0cf80 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -20,6 +20,11 @@
#include "tda1002x.h"
#include "mt312.h"
#include "zl10039.h"
+#include "ds3000.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
#ifndef USB_PID_DW2102
#define USB_PID_DW2102 0x2102
@@ -37,12 +42,20 @@
#define USB_PID_CINERGY_S 0x0064
#endif
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
+#endif
+
#ifndef USB_PID_TEVII_S650
#define USB_PID_TEVII_S650 0xd650
#endif
-#ifndef USB_PID_TEVII_S630
-#define USB_PID_TEVII_S630 0xd630
+#ifndef USB_PID_TEVII_S660
+#define USB_PID_TEVII_S660 0xd660
+#endif
+
+#ifndef USB_PID_PROF_1100
+#define USB_PID_PROF_1100 0xb012
#endif
#define DW210X_READ_MSG 0
@@ -55,6 +68,10 @@
#define DW2102_VOLTAGE_CTRL (0x1800)
#define DW2102_RC_QUERY (0x1a00)
+#define err_str "did not find the firmware file. (%s) " \
+ "Please see linux/Documentation/dvb/ for more details " \
+ "on firmware-problems."
+
struct dvb_usb_rc_keys_table {
struct dvb_usb_rc_key *rc_keys;
int rc_keys_size;
@@ -71,6 +88,12 @@ static int ir_keymap;
module_param_named(keymap, ir_keymap, int, 0644);
MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
+/* demod probe */
+static int demod_probe = 1;
+module_param_named(demod, demod_probe, int, 0644);
+MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
+ "4=stv0903+stb6100(or-able)).");
+
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
switch (num) {
case 2:
/* read si2109 register by number */
- buf6[0] = 0xd0;
+ buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len;
buf6[2] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
switch (msg[0].addr) {
case 0x68:
/* write to si2109 register */
- buf6[0] = 0xd0;
+ buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len;
memcpy(buf6 + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
/* read */
/* first write first register number */
u8 ibuf[msg[1].len + 2], obuf[3];
- obuf[0] = 0xd0;
+ obuf[0] = msg[0].addr << 1;
obuf[1] = msg[0].len;
obuf[2] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
case 0x68: {
/* write to register */
u8 obuf[msg[0].len + 2];
- obuf[0] = 0xd0;
+ obuf[0] = msg[0].addr << 1;
obuf[1] = msg[0].len;
memcpy(obuf + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
case 0x61: {
/* write to tuner */
u8 obuf[msg[0].len + 2];
- obuf[0] = 0xc2;
+ obuf[0] = msg[0].addr << 1;
obuf[1] = msg[0].len;
memcpy(obuf + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0;
- int len, i;
+ int len, i, j;
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- switch (num) {
- case 2: {
- /* read */
- /* first write first register number */
- u8 ibuf[msg[1].len + 2], obuf[3];
- obuf[0] = 0xaa;
- obuf[1] = msg[0].len;
- obuf[2] = msg[0].buf[0];
- ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
- obuf, msg[0].len + 2, DW210X_WRITE_MSG);
- /* second read registers */
- ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
- ibuf, msg[1].len + 2, DW210X_READ_MSG);
- memcpy(msg[1].buf, ibuf + 2, msg[1].len);
-
- break;
- }
- case 1:
- switch (msg[0].addr) {
- case 0x55: {
- if (msg[0].buf[0] == 0xf7) {
- /* firmware */
- /* Write in small blocks */
- u8 obuf[19];
- obuf[0] = 0xaa;
- obuf[1] = 0x11;
- obuf[2] = 0xf7;
- len = msg[0].len - 1;
- i = 1;
- do {
- memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
- ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
- obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
- i += 16;
- len -= 16;
- } while (len > 0);
- } else {
- /* write to register */
- u8 obuf[msg[0].len + 2];
- obuf[0] = 0xaa;
- obuf[1] = msg[0].len;
- memcpy(obuf + 2, msg[0].buf, msg[0].len);
- ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
- obuf, msg[0].len + 2, DW210X_WRITE_MSG);
- }
- break;
- }
+ for (j = 0; j < num; j++) {
+ switch (msg[j].addr) {
case(DW2102_RC_QUERY): {
u8 ibuf[2];
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
ibuf, 2, DW210X_READ_MSG);
- memcpy(msg[0].buf, ibuf , 2);
+ memcpy(msg[j].buf, ibuf , 2);
break;
}
case(DW2102_VOLTAGE_CTRL): {
u8 obuf[2];
obuf[0] = 0x30;
- obuf[1] = msg[0].buf[0];
+ obuf[1] = msg[j].buf[0];
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
obuf, 2, DW210X_WRITE_MSG);
break;
}
+ /*case 0x55: cx24116
+ case 0x6a: stv0903
+ case 0x68: ds3000, stv0903
+ case 0x60: ts2020, stv6110, stb6100 */
+ default: {
+ if (msg[j].flags == I2C_M_RD) {
+ /* read registers */
+ u8 ibuf[msg[j].len + 2];
+ ret = dw210x_op_rw(d->udev, 0xc3,
+ (msg[j].addr << 1) + 1, 0,
+ ibuf, msg[j].len + 2,
+ DW210X_READ_MSG);
+ memcpy(msg[j].buf, ibuf + 2, msg[j].len);
+ mdelay(10);
+ } else if (((msg[j].buf[0] == 0xb0) &&
+ (msg[j].addr == 0x68)) ||
+ ((msg[j].buf[0] == 0xf7) &&
+ (msg[j].addr == 0x55))) {
+ /* write firmware */
+ u8 obuf[19];
+ obuf[0] = msg[j].addr << 1;
+ obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
+ obuf[2] = msg[j].buf[0];
+ len = msg[j].len - 1;
+ i = 1;
+ do {
+ memcpy(obuf + 3, msg[j].buf + i,
+ (len > 16 ? 16 : len));
+ ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+ obuf, (len > 16 ? 16 : len) + 3,
+ DW210X_WRITE_MSG);
+ i += 16;
+ len -= 16;
+ } while (len > 0);
+ } else {
+ /* write registers */
+ u8 obuf[msg[j].len + 2];
+ obuf[0] = msg[j].addr << 1;
+ obuf[1] = msg[j].len;
+ memcpy(obuf + 2, msg[j].buf, msg[j].len);
+ ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+ obuf, msg[j].len + 2,
+ DW210X_WRITE_MSG);
+ }
+ break;
+ }
}
- break;
}
mutex_unlock(&d->i2c_mutex);
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
return num;
}
-static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0;
+ int len, i, j;
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- switch (num) {
- case 2: { /* read */
- u8 ibuf[msg[1].len], obuf[3];
- obuf[0] = msg[1].len;
- obuf[1] = (msg[0].addr << 1);
- obuf[2] = msg[0].buf[0];
-
- ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
- obuf, 3, DW210X_WRITE_MSG);
- msleep(5);
- ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
- ibuf, msg[1].len, DW210X_READ_MSG);
- memcpy(msg[1].buf, ibuf, msg[1].len);
- break;
- }
- case 1:
- switch (msg[0].addr) {
- case 0x60:
- case 0x0e: {
- /* write to zl10313, zl10039 register, */
- u8 obuf[msg[0].len + 2];
- obuf[0] = msg[0].len + 1;
- obuf[1] = (msg[0].addr << 1);
- memcpy(obuf + 2, msg[0].buf, msg[0].len);
- ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
- obuf, msg[0].len + 2, DW210X_WRITE_MSG);
- break;
- }
+ for (j = 0; j < num; j++) {
+ switch (msg[j].addr) {
case (DW2102_RC_QUERY): {
u8 ibuf[4];
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
ibuf, 4, DW210X_READ_MSG);
- msg[0].buf[0] = ibuf[3];
+ memcpy(msg[j].buf, ibuf + 1, 2);
break;
}
case (DW2102_VOLTAGE_CTRL): {
u8 obuf[2];
- obuf[0] = 0x03;
- obuf[1] = msg[0].buf[0];
+ obuf[0] = 3;
+ obuf[1] = msg[j].buf[0];
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
obuf, 2, DW210X_WRITE_MSG);
break;
}
+ /*case 0x55: cx24116
+ case 0x6a: stv0903
+ case 0x68: ds3000, stv0903
+ case 0x60: ts2020, stv6110, stb6100
+ case 0xa0: eeprom */
+ default: {
+ if (msg[j].flags == I2C_M_RD) {
+ /* read registers */
+ u8 ibuf[msg[j].len];
+ ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+ ibuf, msg[j].len,
+ DW210X_READ_MSG);
+ memcpy(msg[j].buf, ibuf, msg[j].len);
+ break;
+ } else if ((msg[j].buf[0] == 0xb0) &&
+ (msg[j].addr == 0x68)) {
+ /* write firmware */
+ u8 obuf[19];
+ obuf[0] = (msg[j].len > 16 ?
+ 18 : msg[j].len + 1);
+ obuf[1] = msg[j].addr << 1;
+ obuf[2] = msg[j].buf[0];
+ len = msg[j].len - 1;
+ i = 1;
+ do {
+ memcpy(obuf + 3, msg[j].buf + i,
+ (len > 16 ? 16 : len));
+ ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
+ obuf, (len > 16 ? 16 : len) + 3,
+ DW210X_WRITE_MSG);
+ i += 16;
+ len -= 16;
+ } while (len > 0);
+ } else {
+ /* write registers */
+ u8 obuf[msg[j].len + 2];
+ obuf[0] = msg[j].len + 1;
+ obuf[1] = (msg[j].addr << 1);
+ memcpy(obuf + 2, msg[j].buf, msg[j].len);
+ ret = dw210x_op_rw(d->udev,
+ (num > 1 ? 0x90 : 0x80), 0, 0,
+ obuf, msg[j].len + 2,
+ DW210X_WRITE_MSG);
+ break;
+ }
+ break;
+ }
}
- break;
+ msleep(3);
}
mutex_unlock(&d->i2c_mutex);
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = {
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm s630_i2c_algo = {
- .master_xfer = s630_i2c_transfer,
+static struct i2c_algorithm s6x0_i2c_algo = {
+ .master_xfer = s6x0_i2c_transfer,
.functionality = dw210x_i2c_func,
};
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
return 0;
};
-static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
{
int i, ret;
- u8 buf[3], eeprom[256], eepromline[16];
+ u8 ibuf[] = { 0 }, obuf[] = { 0 };
+ u8 eeprom[256], eepromline[16];
+ struct i2c_msg msg[] = {
+ {
+ .addr = 0xa0 >> 1,
+ .flags = 0,
+ .buf = obuf,
+ .len = 1,
+ }, {
+ .addr = 0xa0 >> 1,
+ .flags = I2C_M_RD,
+ .buf = ibuf,
+ .len = 1,
+ }
+ };
for (i = 0; i < 256; i++) {
- buf[0] = 1;
- buf[1] = 0xa0;
- buf[2] = i;
- ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
- buf, 3, DW210X_WRITE_MSG);
- ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
- buf, 1, DW210X_READ_MSG);
- if (ret < 0) {
+ obuf[0] = i;
+ ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
+ if (ret != 2) {
err("read eeprom failed.");
return -1;
} else {
- eepromline[i % 16] = buf[0];
- eeprom[i] = buf[0];
+ eepromline[i % 16] = ibuf[0];
+ eeprom[i] = ibuf[0];
}
if ((i % 16) == 15) {
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config = {
.demod_address = 0x0e,
};
+static struct ds3000_config dw2104_ds3000_config = {
+ .demod_address = 0x68,
+};
+
+static struct stv0900_config dw2104a_stv0900_config = {
+ .demod_address = 0x6a,
+ .demod_mode = 0,
+ .xtal = 27000000,
+ .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+ .diseqc_mode = 2,/* 2/3 PWM */
+ .tun1_maddress = 0,/* 0x60 */
+ .tun1_adc = 0,/* 2 Vpp */
+ .path1_mode = 3,
+};
+
+static struct stb6100_config dw2104a_stb6100_config = {
+ .tuner_address = 0x60,
+ .refclock = 27000000,
+};
+
+static struct stv0900_config dw2104_stv0900_config = {
+ .demod_address = 0x68,
+ .demod_mode = 0,
+ .xtal = 8000000,
+ .clkmode = 3,
+ .diseqc_mode = 2,
+ .tun1_maddress = 0,
+ .tun1_adc = 1,/* 1 Vpp */
+ .path1_mode = 3,
+};
+
+static struct stv6110_config dw2104_stv6110_config = {
+ .i2c_address = 0x60,
+ .mclk = 16000000,
+ .clk_div = 1,
+};
+
static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
{
- if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
- &d->dev->i2c_adap)) != NULL) {
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (demod_probe & 4) {
+ d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
+ &d->dev->i2c_adap, 0);
+ if (d->fe != NULL) {
+ if (dvb_attach(stb6100_attach, d->fe,
+ &dw2104a_stb6100_config,
+ &d->dev->i2c_adap)) {
+ tuner_ops = &d->fe->ops.tuner_ops;
+ tuner_ops->set_frequency = stb6100_set_freq;
+ tuner_ops->get_frequency = stb6100_get_freq;
+ tuner_ops->set_bandwidth = stb6100_set_bandw;
+ tuner_ops->get_bandwidth = stb6100_get_bandw;
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached STV0900+STB6100!\n");
+ return 0;
+ }
+ }
+ }
+
+ if (demod_probe & 2) {
+ d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
+ &d->dev->i2c_adap, 0);
+ if (d->fe != NULL) {
+ if (dvb_attach(stv6110_attach, d->fe,
+ &dw2104_stv6110_config,
+ &d->dev->i2c_adap)) {
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached STV0900+STV6110A!\n");
+ return 0;
+ }
+ }
+ }
+
+ if (demod_probe & 1) {
+ d->fe = dvb_attach(cx24116_attach, &dw2104_config,
+ &d->dev->i2c_adap);
+ if (d->fe != NULL) {
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached cx24116!\n");
+ return 0;
+ }
+ }
+
+ d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+ &d->dev->i2c_adap);
+ if (d->fe != NULL) {
d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached cx24116!\n");
+ info("Attached DS3000!\n");
return 0;
}
+
return -EIO;
}
static struct dvb_usb_device_properties dw2102_properties;
static struct dvb_usb_device_properties dw2104_properties;
+static struct dvb_usb_device_properties s6x0_properties;
static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
{
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
return 0;
}
}
+
if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
- /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
d->fe = dvb_attach(stv0288_attach, &earda_config,
&d->dev->i2c_adap);
if (d->fe != NULL) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached stv0288!\n");
- return 0;
+ if (dvb_attach(stb6000_attach, d->fe, 0x61,
+ &d->dev->i2c_adap)) {
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached stv0288!\n");
+ return 0;
+ }
}
}
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
return -EIO;
}
-static int s630_frontend_attach(struct dvb_usb_adapter *d)
+static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
{
d->fe = dvb_attach(mt312_attach, &zl313_config,
- &d->dev->i2c_adap);
+ &d->dev->i2c_adap);
+ if (d->fe != NULL) {
+ if (dvb_attach(zl10039_attach, d->fe, 0x60,
+ &d->dev->i2c_adap)) {
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached zl100313+zl10039!\n");
+ return 0;
+ }
+ }
+
+ d->fe = dvb_attach(stv0288_attach, &earda_config,
+ &d->dev->i2c_adap);
+ if (d->fe != NULL) {
+ if (dvb_attach(stb6000_attach, d->fe, 0x61,
+ &d->dev->i2c_adap)) {
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached stv0288+stb6000!\n");
+ return 0;
+ }
+ }
+
+ d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+ &d->dev->i2c_adap);
if (d->fe != NULL) {
d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached zl10313!\n");
+ info("Attached ds3000+ds2020!\n");
return 0;
}
+
return -EIO;
}
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
-{
- dvb_attach(stb6000_attach, adap->fe, 0x61,
- &adap->dev->i2c_adap);
-
- return 0;
-}
-
static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
{
dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
-{
- dvb_attach(zl10039_attach, adap->fe, 0x60,
- &adap->dev->i2c_adap);
-
- return 0;
-}
-
static struct dvb_usb_rc_key dw210x_rc_keys[] = {
{ 0xf80a, KEY_Q }, /*power*/
{ 0xf80c, KEY_M }, /*mute*/
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = {
{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
+ {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
+ {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
{ }
};
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev,
u8 reset;
u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
const struct firmware *fw;
- const char *filename = "dvb-usb-dw2101.fw";
+ const char *fw_2101 = "dvb-usb-dw2101.fw";
switch (dev->descriptor.idProduct) {
case 0x2101:
- ret = request_firmware(&fw, filename, &dev->dev);
+ ret = request_firmware(&fw, fw_2101, &dev->dev);
if (ret != 0) {
- err("did not find the firmware file. (%s) "
- "Please see linux/Documentation/dvb/ for more details "
- "on firmware-problems.", filename);
+ err(err_str, fw_2101);
return ret;
}
break;
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev,
}
/* init registers */
switch (dev->descriptor.idProduct) {
+ case USB_PID_PROF_1100:
+ s6x0_properties.rc_key_map = tbs_rc_keys;
+ s6x0_properties.rc_key_map_size =
+ ARRAY_SIZE(tbs_rc_keys);
+ break;
case USB_PID_TEVII_S650:
dw2104_properties.rc_key_map = tevii_rc_keys;
dw2104_properties.rc_key_map_size =
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
DW210X_READ_MSG);
if (reset16[2] == 0x11) {
dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
- dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
break;
}
}
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = {
}
};
-static struct dvb_usb_device_properties s630_properties = {
+static struct dvb_usb_device_properties s6x0_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.firmware = "dvb-usb-s630.fw",
.no_reconnect = 1,
- .i2c_algo = &s630_i2c_algo,
+ .i2c_algo = &s6x0_i2c_algo,
.rc_key_map = tevii_rc_keys,
.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
.rc_interval = 150,
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = {
.generic_bulk_ctrl_endpoint = 0x81,
.num_adapters = 1,
.download_firmware = dw2102_load_firmware,
- .read_mac_address = s630_read_mac_address,
+ .read_mac_address = s6x0_read_mac_address,
.adapter = {
{
- .frontend_attach = s630_frontend_attach,
+ .frontend_attach = s6x0_frontend_attach,
.streaming_ctrl = NULL,
- .tuner_attach = s630_zl10039_tuner_attach,
+ .tuner_attach = NULL,
.stream = {
.type = USB_BULK,
.count = 8,
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = {
},
}
},
- .num_device_descs = 1,
+ .num_device_descs = 3,
.devices = {
{"TeVii S630 USB",
{&dw2102_table[6], NULL},
{NULL},
},
+ {"Prof 1100 USB ",
+ {&dw2102_table[7], NULL},
+ {NULL},
+ },
+ {"TeVii S660 USB",
+ {&dw2102_table[8], NULL},
+ {NULL},
+ },
}
};
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, &dw3101_properties,
THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &s630_properties,
- THIS_MODULE, NULL, adapter_nr)) {
+ 0 == dvb_usb_device_init(intf, &s6x0_properties,
+ THIS_MODULE, NULL, adapter_nr))
return 0;
- }
+
return -ENODEV;
}
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit);
MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
" DVB-C 3101 USB2.0,"
- " TeVii S600, S630, S650 USB2.0 devices");
+ " TeVii S600, S630, S650, S660 USB2.0,"
+ " Prof 1100 USB2.0 devices");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index 9cbbe42ca44..ebb7b9fd115 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
state->frontend.ops.info.frequency_stepsize);
/* freq -> oscilator frequency conversion. */
- /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
- /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */
- /* 1/7MHz for center freq shift */
+ /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
f = freq / state->frontend.ops.info.frequency_stepsize;
- f += 400;
+ /* add 399[1/7 MHZ] = 57MHz for the IF */
+ f += 399;
+ /* add center frequency shift if necessary */
+ if (f % 7 == 0)
+ f++;
pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
index 20eadf9318e..7a7f1b2b681 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
switch (c->delivery_system) {
case SYS_DVBS:
- /* Only QPSK is supported for DVB-S */
- if (c->modulation != QPSK) {
+ /* Allow QPSK and 8PSK (even for DVB-S) */
+ if (c->modulation != QPSK && c->modulation != PSK_8) {
deb_fe("%s: unsupported modulation selected (%d)\n",
__func__, c->modulation);
return -EOPNOTSUPP;