Difference between revisions of "TeVii S482"

From LinuxTVWiki
Jump to: navigation, search
(Linux support)
m (Linux support)
 
(3 intermediate revisions by one other user not shown)
Line 56: Line 56:
   
 
== Linux support ==
 
== Linux support ==
  +
  +
Native support is included in kernel 4.2. Media_build can be used to build support for older kernels.
  +
  +
Alternative methods described below:
  +
 
The [[s2-liplianin]] v4l branch includes support for the card.
 
The [[s2-liplianin]] v4l branch includes support for the card.
   
 
It works in 3.2 kernel.
 
It works in 3.2 kernel.
   
For kernel 3.16 you can apply the foloowing patch (tested on Debian Lenny):
+
For kernel > 3.10 (tested with 3.19 vanilla) you can apply the following patch to the kernel sources:
   
 
<pre>
 
<pre>
diff -r 4c01a16b6237 linux/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
  +
index 1a3df10..82d35c6 100644
--- a/linux/drivers/media/i2c/s5c73m3/s5c73m3-core.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/i2c/s5c73m3/s5c73m3-core.c Sun Feb 08 19:01:07 2015 +0000
+
--- a/drivers/media/usb/dvb-usb/dw2102.c
  +
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -1585,7 +1585,11 @@
 
  +
@@ -31,6 +31,9 @@
oif_sd = &state->oif_sd;
 
  +
#include "m88rs2000.h"
  +
#include "tda18271.h"
  +
#include "cxd2820r.h"
  +
+#include "m88ds3103.h"
  +
+#include "m88ts2022.h"
  +
+
  +
  +
/* Max transfer size done by I2C transfer functions */
  +
#define MAX_XFER_SIZE 64
  +
@@ -71,6 +74,14 @@
  +
#define USB_PID_TEVII_S480_2 0xd482
  +
#endif
 
 
  +
+#ifndef USB_PID_TEVII_S482_1
v4l2_subdev_init(sd, &s5c73m3_subdev_ops);
 
  +
+#define USB_PID_TEVII_S482_1 0xd483
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
 
sd->owner = client->driver->driver.owner;
 
+#else
 
+ sd->owner = client->dev.driver->owner;
 
 
+#endif
 
+#endif
v4l2_set_subdevdata(sd, state);
 
strlcpy(sd->name, "S5C73M3", sizeof(sd->name));
 
 
diff -r 4c01a16b6237 linux/drivers/media/i2c/tvp514x.c
 
--- a/linux/drivers/media/i2c/tvp514x.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/i2c/tvp514x.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -123,6 +123,8 @@
 
/* mc related members */
 
struct media_pad pad;
 
struct v4l2_mbus_framefmt format;
 
 
+
 
+
  +
+#ifndef USB_PID_TEVII_S482_2
+ struct tvp514x_reg *int_seq;
 
  +
+#define USB_PID_TEVII_S482_2 0xd484
  +
+#endif
  +
+
  +
#ifndef USB_PID_PROF_1100
  +
#define USB_PID_PROF_1100 0xb012
  +
#endif
  +
@@ -1117,6 +1128,19 @@ static struct tda18271_config tda18271_config = {
  +
.gate = TDA18271_GATE_DIGITAL,
 
};
 
};
 
 
  +
+static const struct m88ds3103_config s482_m88ds3103_config = {
/* TVP514x default register values */
 
  +
+ .i2c_addr = 0x68,
@@ -862,7 +864,6 @@
 
  +
+ .clock = 27000000,
static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
 
  +
+ .i2c_wr_max = 33,
{
 
int err = 0;
+
+ .clock_out = 0,
  +
+ .ts_mode = M88DS3103_TS_CI,
- struct i2c_client *client = v4l2_get_subdevdata(sd);
 
  +
+ .ts_clk = 16000,
struct tvp514x_decoder *decoder = to_decoder(sd);
 
  +
+ .ts_clk_pol = 0,
 
  +
+ .agc = 0x99,
if (decoder->streaming == enable)
 
  +
+ .lnb_hv_pol = 1,
@@ -882,11 +883,8 @@
 
  +
+ .lnb_en_pol = 1,
}
 
case 1:
+
+ };
{
 
- struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
 
- client->driver->id_table->driver_data;
 
-
 
/* Power Up Sequence */
 
- err = tvp514x_write_regs(sd, int_seq);
 
+ err = tvp514x_write_regs(sd, decoder->int_seq);
 
if (err) {
 
v4l2_err(sd, "Unable to turn on decoder\n");
 
return err;
 
@@ -1088,6 +1086,8 @@
 
/* Copy default register configuration */
 
memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
 
sizeof(tvp514x_reg_list_default));
 
+
 
+ decoder->int_seq = (struct tvp514x_reg *)id->driver_data;
 
 
/* Copy board specific information here */
 
decoder->pdata = client->dev.platform_data;
 
diff -r 4c01a16b6237 linux/drivers/media/pci/bt8xx/bttv-i2c.c
 
--- a/linux/drivers/media/pci/bt8xx/bttv-i2c.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/pci/bt8xx/bttv-i2c.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -397,8 +397,9 @@
 
 
int fini_bttv_i2c(struct bttv *btv)
 
{
 
- if (0 != btv->i2c_rc)
 
- return 0;
 
 
- return i2c_del_adapter(&btv->c.i2c_adap);
 
+ if (btv->i2c_rc == 0)
 
+ i2c_del_adapter(&btv->c.i2c_adap);
 
 
+
 
+
  +
static u8 m88rs2000_inittab[] = {
+ return 0;
 
  +
DEMOD_WRITE, 0x9a, 0x30,
  +
DEMOD_WRITE, 0x00, 0x01,
  +
@@ -1386,6 +1410,83 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
  +
return -EIO;
 
}
 
}
diff -r 4c01a16b6237 linux/drivers/media/pci/ttpci/av7110_ir.c
 
--- a/linux/drivers/media/pci/ttpci/av7110_ir.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/pci/ttpci/av7110_ir.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -375,7 +375,7 @@
 
if (av_cnt == 1) {
 
e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
 
if (e)
 
- e->size = 4 + 256 * sizeof(u16);
 
+ proc_set_size(e, 4 + 256 * sizeof(u16));
 
}
 
 
 
  +
+static int m88ds3103_frontend_attach(struct dvb_usb_adapter *d)
tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
 
  +
+{
diff -r 4c01a16b6237 linux/drivers/media/pci/zoran/zoran_procfs.c
 
  +
+ u8 obuf[3] = { 0xe, 0x80, 0 };
--- a/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Jun 16 17:27:56 2013 +0300
 
  +
+ u8 ibuf[] = { 0 };
+++ b/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Feb 08 19:01:07 2015 +0000
 
  +
+
@@ -58,6 +58,10 @@
 
  +
+ /* demod I2C adapter */
short bit;
 
  +
+ struct i2c_adapter *i2c_adapter;
};
 
  +
+ struct i2c_client *client;
 
  +
+ struct i2c_board_info info;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 
  +
+ struct m88ts2022_config m88ts2022_config = {
+ #define PDE_DATA(info) (struct zoran *)(PDE(inode)->data)
 
  +
+ .clock = 27000000,
+#endif
 
  +
+ };
  +
+ memset(&info, 0, sizeof(struct i2c_board_info));
  +
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
  +
+ err("command 0x0e transfer failed.");
 
+
 
+
  +
+ obuf[0] = 0xe;
static const struct procfs_params_zr36067 zr67[] = {
 
  +
+ obuf[1] = 0x02;
{"HSPol", 0x000, 1, 30},
 
  +
+ obuf[2] = 1;
{"HStart", 0x000, 0x3ff, 10},
 
  +
+
@@ -130,14 +134,14 @@
 
  +
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
 
  +
+ err("command 0x0e transfer failed.");
static int zoran_open(struct inode *inode, struct file *file)
 
  +
+ msleep(300);
  +
+
  +
+ obuf[0] = 0xe;
  +
+ obuf[1] = 0x83;
  +
+ obuf[2] = 0;
  +
+
  +
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
  +
+ err("command 0x0e transfer failed.");
  +
+
  +
+ obuf[0] = 0xe;
  +
+ obuf[1] = 0x83;
  +
+ obuf[2] = 1;
  +
+
  +
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
  +
+ err("command 0x0e transfer failed.");
  +
+
  +
+ obuf[0] = 0x51;
  +
+
  +
+ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
  +
+ err("command 0x51 transfer failed.");
  +
+ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach,
  +
+ &s482_m88ds3103_config,
  +
+ &d->dev->i2c_adap,
  +
+ &i2c_adapter);
  +
+ if (d->fe_adap[0].fe == NULL)
  +
+ return -EIO;
  +
+ /* attach tuner */
  +
+ m88ts2022_config.fe = d->fe_adap[0].fe;
  +
+ strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
  +
+ info.addr = 0x60;
  +
+ info.platform_data = &m88ts2022_config;
  +
+ request_module("m88ts2022");
  +
+ client = i2c_new_device(i2c_adapter, &info);
  +
+ if (client == NULL || client->dev.driver == NULL) {
  +
+ dvb_frontend_detach(d->fe_adap[0].fe);
  +
+ goto fail_attach;
  +
+ }
  +
+ if (!try_module_get(client->dev.driver->owner)) {
  +
+ i2c_unregister_device(client);
  +
+ dvb_frontend_detach(d->fe_adap[0].fe);
  +
+ goto fail_attach;
  +
+ }
  +
+ info("attached m88ds3103/m88ts2022!\n");
  +
+
  +
+ /* delegate signal strength measurement to tuner */
  +
+
  +
+ d->fe_adap[0].fe->ops.read_signal_strength =
  +
+ d->fe_adap[0].fe->ops.tuner_ops.get_rf_strength;
  +
+
  +
+ return 0;
  +
+fail_attach:
  +
+ info("Failed to attach m88ds3103/m88ts2022!\n");
  +
+ return -EIO;
  +
+}
  +
+
  +
static int t220_frontend_attach(struct dvb_usb_adapter *d)
 
{
 
{
  +
u8 obuf[3] = { 0xe, 0x87, 0 };
- struct zoran *data = PDE(inode)->data;
 
  +
@@ -1557,6 +1658,8 @@ enum dw2102_table_entry {
+ struct zoran *data = PDE_DATA(inode);
 
  +
TEVII_S480_2,
return single_open(file, zoran_show, data);
 
  +
X3M_SPC1400HD,
}
 
  +
TEVII_S421,
 
  +
+ TEVII_S482_1,
static ssize_t zoran_write(struct file *file, const char __user *buffer,
 
  +
+ TEVII_S482_2,
size_t count, loff_t *ppos)
 
  +
TEVII_S632,
{
 
  +
TERRATEC_CINERGY_S2_R2,
- struct zoran *zr = PDE(file_inode(file))->data;
 
  +
GOTVIEW_SAT_HD,
+ struct zoran *zr = PDE_DATA(file_inode(file));
 
  +
@@ -1580,7 +1683,9 @@ static struct usb_device_id dw2102_table[] = {
char *string, *sp;
 
  +
[TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
char *line, *ldelim, *varname, *svar, *tdelim;
 
  +
[X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
 
  +
[TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
@@ -201,7 +205,7 @@
 
  +
- [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
dprintk(2,
 
  +
+ [TEVII_S482_1] = { USB_DEVICE(0x9022, USB_PID_TEVII_S482_1) },
KERN_INFO
 
  +
+ [TEVII_S482_2] = { USB_DEVICE(0x9022, USB_PID_TEVII_S482_2) },
"%s: procfs entry /proc/%s allocated. data=%p\n",
 
  +
+ [TEVII_S632] = { USB_DEVICE(0x9022, USB_PID_TEVII_S632) },
- ZR_DEVNAME(zr), name, zr->zoran_proc->data);
 
  +
[TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
+ ZR_DEVNAME(zr), name, zr);
 
  +
[GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
} else {
 
  +
[GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
 
  +
@@ -2012,6 +2117,59 @@ static struct dvb_usb_device_properties su3000_properties = {
ZR_DEVNAME(zr), name);
 
diff -r 4c01a16b6237 linux/drivers/media/platform/m2m-deinterlace.c
 
--- a/linux/drivers/media/platform/m2m-deinterlace.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/platform/m2m-deinterlace.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -338,8 +338,7 @@
 
ctx->xt->dir = DMA_MEM_TO_MEM;
 
ctx->xt->src_sgl = false;
 
ctx->xt->dst_sgl = true;
 
- flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT |
 
- DMA_COMPL_SKIP_DEST_UNMAP | DMA_COMPL_SKIP_SRC_UNMAP;
 
+ flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 
 
tx = dmadev->device_prep_interleaved_dma(chan, ctx->xt, flags);
 
if (tx == NULL) {
 
diff -r 4c01a16b6237 linux/drivers/media/usb/uvc/uvc_driver.c.orig
 
--- a/linux/drivers/media/usb/uvc/uvc_driver.c.orig Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/usb/uvc/uvc_driver.c.orig Sun Feb 08 19:01:07 2015 +0000
 
@@ -1882,7 +1882,7 @@
 
sizeof(dev->mdev.serial));
 
strcpy(dev->mdev.bus_info, udev->devpath);
 
dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
 
- dev->mdev.driver_version = V4L2_VERSION;
 
+ dev->mdev.driver_version = LINUX_VERSION_CODE;
 
if (media_device_register(&dev->mdev) < 0)
 
goto error;
 
 
diff -r 4c01a16b6237 linux/drivers/media/usb/uvc/uvc_v4l2.c.orig
 
--- a/linux/drivers/media/usb/uvc/uvc_v4l2.c.orig Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/usb/uvc/uvc_v4l2.c.orig Sun Feb 08 19:01:07 2015 +0000
 
@@ -564,7 +564,7 @@
 
strlcpy(cap->card, vdev->name, sizeof cap->card);
 
usb_make_path(stream->dev->udev,
 
cap->bus_info, sizeof(cap->bus_info));
 
- cap->version = V4L2_VERSION;
 
+ cap->version = LINUX_VERSION_CODE;
 
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
 
| chain->caps;
 
if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
 
diff -r 4c01a16b6237 linux/drivers/media/v4l2-core/tuner-core.c
 
--- a/linux/drivers/media/v4l2-core/tuner-core.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/v4l2-core/tuner-core.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -43,8 +43,6 @@
 
 
#define UNSET (-1U)
 
 
-#define PREFIX (t->i2c->driver->driver.name)
 
-
 
/*
 
* Driver modprobe parameters
 
*/
 
@@ -83,28 +81,34 @@
 
/*
 
* Debug macros
 
*/
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
 
+ #define tuner_name(t) (t->i2c->driver->driver.name)
 
+#else
 
+ #define tuner_name(t) (t->i2c->dev.driver->name)
 
+#endif
 
+
 
 
#define tuner_warn(fmt, arg...) do { \
 
- printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
 
+ printk(KERN_WARNING "%s %d-%04x: " fmt, tuner_name(t), \
 
i2c_adapter_id(t->i2c->adapter), \
 
t->i2c->addr, ##arg); \
 
} while (0)
 
 
#define tuner_info(fmt, arg...) do { \
 
- printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
 
+ printk(KERN_INFO "%s %d-%04x: " fmt, tuner_name(t), \
 
i2c_adapter_id(t->i2c->adapter), \
 
t->i2c->addr, ##arg); \
 
} while (0)
 
 
#define tuner_err(fmt, arg...) do { \
 
- printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
 
+ printk(KERN_ERR "%s %d-%04x: " fmt, tuner_name(t), \
 
i2c_adapter_id(t->i2c->adapter), \
 
t->i2c->addr, ##arg); \
 
} while (0)
 
 
#define tuner_dbg(fmt, arg...) do { \
 
if (tuner_debug) \
 
- printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
 
+ printk(KERN_DEBUG "%s %d-%04x: " fmt, tuner_name(t), \
 
i2c_adapter_id(t->i2c->adapter), \
 
t->i2c->addr, ##arg); \
 
} while (0)
 
@@ -478,7 +482,7 @@
 
 
}
 
}
 
tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
 
- c->adapter->name, c->driver->driver.name, c->addr << 1, type,
 
+ c->adapter->name, tuner_name(t), c->addr << 1, type,
 
t->mode_mask);
 
return;
 
 
@@ -582,7 +586,7 @@
 
int mode_mask;
 
 
if (pos->i2c->adapter != adap ||
 
- strcmp(pos->i2c->driver->driver.name, "tuner"))
 
+ strcmp(tuner_name(pos), "tuner"))
 
continue;
 
 
mode_mask = pos->mode_mask;
 
diff -r 4c01a16b6237 linux/drivers/media/v4l2-core/v4l2-common.c
 
--- a/linux/drivers/media/v4l2-core/v4l2-common.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/v4l2-core/v4l2-common.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -248,10 +248,10 @@
 
 
switch (match->type) {
 
case V4L2_CHIP_MATCH_I2C_DRIVER:
 
- if (c->driver == NULL || c->driver->driver.name == NULL)
 
+ if (c->dev.driver == NULL || c->dev.driver->name == NULL)
 
return 0;
 
- len = strlen(c->driver->driver.name);
 
- return len && !strncmp(c->driver->driver.name, match->name, len);
 
+ len = strlen(c->dev.driver->name);
 
+ return len && !strncmp(c->dev.driver->name, match->name, len);
 
case V4L2_CHIP_MATCH_I2C_ADDR:
 
return c->addr == match->addr;
 
case V4L2_CHIP_MATCH_SUBDEV_IDX:
 
@@ -291,13 +291,13 @@
 
v4l2_subdev_init(sd, ops);
 
sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
 
/* the owner is the same as the i2c_client's driver owner */
 
- sd->owner = client->driver->driver.owner;
 
+ sd->owner = client->dev.driver->owner;
 
/* i2c_client and v4l2_subdev point to one another */
 
v4l2_set_subdevdata(sd, client);
 
i2c_set_clientdata(client, sd);
 
/* initialize name */
 
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
 
- client->driver->driver.name, i2c_adapter_id(client->adapter),
 
+ client->dev.driver->name, i2c_adapter_id(client->adapter),
 
client->addr);
 
}
 
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
@@ -330,11 +330,11 @@
 
loaded. This delay-load mechanism doesn't work if other drivers
 
want to use the i2c device, so explicitly loading the module
 
is the best alternative. */
 
- if (client == NULL || client->driver == NULL)
 
+ if (client == NULL || client->dev.driver == NULL)
 
goto error;
 
 
/* Lock the module so we can safely get the v4l2_subdev pointer */
 
- if (!try_module_get(client->driver->driver.owner))
 
+ if (!try_module_get(client->dev.driver->owner))
 
goto error;
 
sd = i2c_get_clientdata(client);
 
 
@@ -343,7 +343,7 @@
 
if (v4l2_device_register_subdev(v4l2_dev, sd))
 
sd = NULL;
 
/* Decrease the module use count to match the first try_module_get. */
 
- module_put(client->driver->driver.owner);
 
+ module_put(client->dev.driver->owner);
 
 
error:
 
/* If we have a client but no subdev, then something went wrong and
 
diff -r 4c01a16b6237 linux/drivers/media/v4l2-core/v4l2-dev.c
 
--- a/linux/drivers/media/v4l2-core/v4l2-dev.c Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/drivers/media/v4l2-core/v4l2-dev.c Sun Feb 08 19:01:07 2015 +0000
 
@@ -84,6 +84,10 @@
 
__ATTR_NULL
 
 
};
 
};
 
 
  +
+static struct dvb_usb_device_properties m88ds3103_properties = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
 
  +
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ATTRIBUTE_GROUPS(video_device);
 
  +
+ .usb_ctrl = DEVICE_SPECIFIC,
+#endif
 
  +
+ .size_of_priv = sizeof(struct su3000_state),
  +
+ .power_ctrl = su3000_power_ctrl,
  +
+ .num_adapters = 1,
  +
+ .identify_state = su3000_identify_state,
  +
+ .i2c_algo = &su3000_i2c_algo,
 
+
 
+
  +
+ .rc.core = {
/*
 
  +
+ .rc_interval = 150,
* Active devices
 
  +
+ .rc_codes = RC_MAP_TEVII_NEC,
*/
 
  +
+ .module_name = "dw2102",
@@ -217,7 +221,11 @@
 
  +
+ .allowed_protos = RC_BIT_NEC,
 
  +
+ .rc_query = dw2102_rc_query,
static struct class video_class = {
 
  +
+ },
.name = VIDEO_NAME,
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
 
+ .dev_groups = video_device_groups,
 
+#else
 
.dev_attrs = video_device_attrs,
 
+#endif
 
};
 
 
struct video_device *video_devdata(struct file *file)
 
diff -r 4c01a16b6237 linux/include/media/v4l2-common.h
 
--- a/linux/include/media/v4l2-common.h Sun Jun 16 17:27:56 2013 +0300
 
+++ b/linux/include/media/v4l2-common.h Sun Feb 08 19:01:07 2015 +0000
 
@@ -32,20 +32,16 @@
 
prefix consisting of the driver name, the adapter number and the i2c
 
address. */
 
#define v4l_printk(level, name, adapter, addr, fmt, arg...) \
 
- printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
 
-
 
-#define v4l_client_printk(level, client, fmt, arg...) \
 
- v4l_printk(level, (client)->driver->driver.name, (client)->adapter, \
 
- (client)->addr, fmt , ## arg)
 
-
 
+ printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
 
+#define v4l_client_printk(level, client, fmt, arg...) \
 
+ v4l_printk(level, (client)->dev.driver->name, (client)->adapter, \
 
+ (client)->addr, fmt , ## arg)
 
#define v4l_err(client, fmt, arg...) \
 
- v4l_client_printk(KERN_ERR, client, fmt , ## arg)
 
-
 
+ v4l_client_printk(KERN_ERR, client, fmt , ## arg)
 
#define v4l_warn(client, fmt, arg...) \
 
- v4l_client_printk(KERN_WARNING, client, fmt , ## arg)
 
-
 
+ v4l_client_printk(KERN_WARNING, client, fmt , ## arg)
 
#define v4l_info(client, fmt, arg...) \
 
- v4l_client_printk(KERN_INFO, client, fmt , ## arg)
 
+ v4l_client_printk(KERN_INFO, client, fmt , ## arg)
 
 
/* These three macros assume that the debug level is set with a module
 
parameter called 'debug'. */
 
diff -r 4c01a16b6237 v4l/compat.h
 
--- a/v4l/compat.h Sun Jun 16 17:27:56 2013 +0300
 
+++ b/v4l/compat.h Sun Feb 08 19:01:07 2015 +0000
 
@@ -7,6 +7,8 @@
 
 
#include <linux/version.h>
 
#include <linux/input.h>
 
+//needed to test for PCI_VDEVICE
 
+#include <linux/pci.h>
 
#include "config-compat.h"
 
#include "../linux/kernel_version.h"
 
 
@@ -89,6 +91,18 @@
 
#include <linux/i2c-dev.h>
 
#endif
 
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 
+#define proc_set_size(e, size) de->size = size;
 
+#endif
 
 
+
 
+
  +
+ .read_mac_address = su3000_read_mac_address,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
 
+#define INIT_COMPLETION(x) reinit_completion(&x)
 
+#endif
 
 
+
 
+
  +
+ .generic_bulk_ctrl_endpoint = 0x01,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
 
+#define put_compat_timespec compat_put_timespec
 
+#endif
 
 
+
 
+
  +
+ .adapter = {
#ifdef NEED_HEX_TO_BIN
 
  +
+ {
#include <linux/ctype.h>
 
  +
+ .num_frontends = 1,
static inline int hex_to_bin(char ch)
 
  +
+ .fe = { {
@@ -679,11 +693,17 @@
 
  +
+ .streaming_ctrl = su3000_streaming_ctrl,
struct module *module, int extra_size,
 
  +
+ .frontend_attach = m88ds3103_frontend_attach,
struct snd_card **card)
 
  +
+ .stream = {
{
 
  +
+ .type = USB_BULK,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3,15,0)
 
  +
+ .count = 8,
+ return snd_card_new(NULL, idx, id, module, extra_size, card);
 
  +
+ .endpoint = 0x82,
+#else
 
  +
+ .u = {
  +
+ .bulk = {
  +
+ .buffersize = 4096,
  +
+ }
  +
+ }
  +
+ }
  +
+ } },
  +
+ }
  +
+ },
  +
+ .num_device_descs = 2,
  +
+ .devices = {
  +
+ { "TeVii S482.1 USB",
  +
+ { &dw2102_table[TEVII_S482_1], NULL },
  +
+ { NULL },
  +
+ },
  +
+ { "TeVii S482.2 USB",
  +
+ { &dw2102_table[TEVII_S482_2], NULL },
  +
+ { NULL },
  +
+ },
  +
+ }
  +
+};
 
+
 
+
  +
static struct dvb_usb_device_properties t220_properties = {
*card = snd_card_new(idx, id, module, extra_size);
 
  +
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
  +
.usb_ctrl = DEVICE_SPECIFIC,
if (*card == NULL)
 
  +
@@ -2131,11 +2289,13 @@ static int dw2102_probe(struct usb_interface *intf,
return -ENOMEM;
 
  +
0 == dvb_usb_device_init(intf, p7500,
return 0;
 
  +
THIS_MODULE, NULL, adapter_nr) ||
+#endif
 
  +
0 == dvb_usb_device_init(intf, s421,
+
 
  +
- THIS_MODULE, NULL, adapter_nr) ||
}
 
  +
- 0 == dvb_usb_device_init(intf, &su3000_properties,
#endif
 
  +
- THIS_MODULE, NULL, adapter_nr) ||
  +
+ THIS_MODULE, NULL, adapter_nr) ||
  +
0 == dvb_usb_device_init(intf, &t220_properties,
  +
- THIS_MODULE, NULL, adapter_nr))
  +
+ THIS_MODULE, NULL, adapter_nr) ||
  +
+ 0 == dvb_usb_device_init(intf, &m88ds3103_properties,
  +
+ THIS_MODULE, NULL, adapter_nr) ||
  +
+ 0 == dvb_usb_device_init(intf, &su3000_properties,
  +
+ THIS_MODULE, NULL, adapter_nr))
  +
return 0;
 
 
  +
return -ENODEV;
  +
@@ -2153,7 +2313,7 @@ module_usb_driver(dw2102_driver);
  +
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, S660, S480, S421, S632"
  +
+ " TeVii S600, S630, S650, S660, S480, S482, S421, S632"
  +
" Prof 1100, 7500 USB2.0,"
  +
" Geniatech SU3000, T220 devices");
  +
MODULE_VERSION("0.1");
  +
</pre>
  +
  +
== dmesg ==
  +
<pre>
  +
[ 5.818669] usbcore: registered new interface driver usbfs
  +
[ 5.819305] usbcore: registered new interface driver hub
  +
[ 5.819405] usbcore: registered new device driver usb
  +
[ 5.835721] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
  +
[ 5.847556] ehci-pci: EHCI PCI platform driver
  +
[ 5.851960] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 29 for gsi 16
  +
[ 5.852344] ehci-pci 0000:00:00.1: Xen PCI mapped GSI16 to IRQ29
  +
[ 5.859554] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
  +
[ 5.861252] ehci-pci 0000:00:00.1: EHCI Host Controller
  +
[ 5.861308] ehci-pci 0000:00:00.1: new USB bus registered, assigned bus number 1
  +
[ 5.861337] ehci-pci 0000:00:00.1: applying MosChip frame-index workaround
  +
[ 5.865052] ehci-pci 0000:00:00.1: Enabling legacy PCI PM
  +
[ 5.867326] ehci-pci 0000:00:00.1: irq 29, io mem 0xfea06000
  +
[ 5.876104] ehci-pci 0000:00:00.1: USB 2.0 started, EHCI 1.00
  +
[ 5.876306] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
  +
[ 5.876319] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
  +
[ 5.876331] usb usb1: Product: EHCI Host Controller
  +
[ 5.876340] usb usb1: Manufacturer: Linux 3.19.0-rc6-build-tree+ ehci_hcd
  +
[ 5.876350] usb usb1: SerialNumber: 0000:00:00.1
  +
[ 5.877073] hub 1-0:1.0: USB hub found
  +
[ 5.877124] hub 1-0:1.0: 1 port detected
  +
[ 5.879360] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 30 for gsi 17
  +
[ 5.879397] ehci-pci 0000:00:00.3: Xen PCI mapped GSI17 to IRQ30
  +
[ 5.879999] ehci-pci 0000:00:00.3: EHCI Host Controller
  +
[ 5.883534] ehci-pci 0000:00:00.3: new USB bus registered, assigned bus number 2
  +
[ 5.883579] ehci-pci 0000:00:00.3: applying MosChip frame-index workaround
  +
[ 5.885849] ehci-pci 0000:00:00.3: Enabling legacy PCI PM
  +
[ 5.886277] ehci-pci 0000:00:00.3: irq 30, io mem 0xfea04000
  +
[ 5.896115] ehci-pci 0000:00:00.3: USB 2.0 started, EHCI 1.00
  +
[ 5.896326] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
  +
[ 5.896339] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
  +
[ 5.896351] usb usb2: Product: EHCI Host Controller
  +
[ 5.896360] usb usb2: Manufacturer: Linux 3.19.0-rc6-build-tree+ ehci_hcd
  +
[ 5.896369] usb usb2: SerialNumber: 0000:00:00.3
  +
[ 5.897076] hub 2-0:1.0: USB hub found
  +
[ 5.897117] hub 2-0:1.0: 1 port detected
  +
[ 5.915014] ohci-pci: OHCI PCI platform driver
  +
[ 5.915808] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 29 for gsi 16
  +
[ 5.915836] ohci-pci 0000:00:00.0: Xen PCI mapped GSI16 to IRQ29
  +
[ 5.917614] ohci-pci 0000:00:00.0: OHCI PCI host controller
  +
[ 5.917664] ohci-pci 0000:00:00.0: new USB bus registered, assigned bus number 3
  +
[ 5.917749] ohci-pci 0000:00:00.0: irq 29, io mem 0xfea07000
  +
[ 5.976289] usb usb3: New USB device found, idVendor=1d6b, idProduct=0001
  +
[ 5.976318] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
  +
[ 5.976331] usb usb3: Product: OHCI PCI host controller
  +
[ 5.976339] usb usb3: Manufacturer: Linux 3.19.0-rc6-build-tree+ ohci_hcd
  +
[ 5.976349] usb usb3: SerialNumber: 0000:00:00.0
  +
[ 5.977069] hub 3-0:1.0: USB hub found
  +
[ 5.977116] hub 3-0:1.0: 1 port detected
  +
[ 5.978048] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 30 for gsi 17
  +
[ 5.978077] ohci-pci 0000:00:00.2: Xen PCI mapped GSI17 to IRQ30
  +
[ 5.978457] ohci-pci 0000:00:00.2: OHCI PCI host controller
  +
[ 5.978502] ohci-pci 0000:00:00.2: new USB bus registered, assigned bus number 4
  +
[ 5.978618] ohci-pci 0000:00:00.2: irq 30, io mem 0xfea05000
  +
[ 6.036248] usb usb4: New USB device found, idVendor=1d6b, idProduct=0001
  +
[ 6.036278] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
  +
[ 6.036290] usb usb4: Product: OHCI PCI host controller
  +
[ 6.036299] usb usb4: Manufacturer: Linux 3.19.0-rc6-build-tree+ ohci_hcd
  +
[ 6.036309] usb usb4: SerialNumber: 0000:00:00.2
  +
[ 6.037031] hub 4-0:1.0: USB hub found
  +
[ 6.037077] hub 4-0:1.0: 1 port detected
  +
[ 6.189162] usb 1-1: new high-speed USB device number 2 using ehci-pci
  +
[ 6.234979] usb 2-1: new high-speed USB device number 2 using ehci-pci
  +
[ 6.327018] usb 1-1: New USB device found, idVendor=9022, idProduct=d483
  +
[ 6.327048] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
  +
[ 6.327060] usb 1-1: Product: Dual tuner S2 PCIe (LNB1)
  +
[ 6.327069] usb 1-1: Manufacturer: Tevii
  +
[ 6.327078] usb 1-1: SerialNumber: 0000000002001010011
  +
[ 6.370736] usb 2-1: New USB device found, idVendor=9022, idProduct=d484
  +
[ 6.370766] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
  +
[ 6.370778] usb 2-1: Product: Dual tuner S2 PCIe (LNB2)
  +
[ 6.370787] usb 2-1: Manufacturer: Tevii
  +
[ 6.370796] usb 2-1: SerialNumber: 000000000010020101
  +
[ 6.582141] dw2102: su3000_identify_state
  +
[ 6.582175] dvb-usb: found a 'TeVii S482.1 USB' in warm state.
  +
[ 6.582202] dw2102: su3000_power_ctrl: 1, initialized 0
  +
[ 6.584443] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
  +
[ 6.585223] DVB: registering new adapter (TeVii S482.1 USB)
  +
[ 6.590604] dvb-usb: MAC address: 00:18:bd:5b:bd:81
  +
[ 6.957230] i2c i2c-0: m88ds3103_attach: chip_id=70
  +
[ 6.963175] i2c i2c-0: Added multiplexed i2c bus 1
  +
[ 7.062312] m88ts2022 1-0060: Montage M88TS2022 successfully identified
  +
[ 7.062372] dw2102: attached m88ds3103/m88ts2022!
  +
[ 7.062394] usb 1-1: DVB: registering adapter 0 frontend 0 (Montage M88DS3103)...
  +
[ 7.063446] dw2102: su3000_power_ctrl: 0, initialized 1
  +
[ 7.063473] dvb-usb: TeVii S482.1 USB successfully initialized and connected.
  +
[ 7.063584] dw2102: su3000_identify_state
  +
[ 7.063599] dvb-usb: found a 'TeVii S482.2 USB' in warm state.
  +
[ 7.063624] dw2102: su3000_power_ctrl: 1, initialized 0
  +
[ 7.063974] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
  +
[ 7.066978] DVB: registering new adapter (TeVii S482.2 USB)
  +
[ 7.073128] dvb-usb: MAC address: 00:18:bd:5b:bd:80
  +
[ 7.386369] i2c i2c-2: m88ds3103_attach: chip_id=70
  +
[ 7.393475] i2c i2c-2: Added multiplexed i2c bus 3
  +
[ 7.490361] m88ts2022 3-0060: Montage M88TS2022 successfully identified
  +
[ 7.490423] dw2102: attached m88ds3103/m88ts2022!
  +
[ 7.490446] usb 2-1: DVB: registering adapter 1 frontend 0 (Montage M88DS3103)...
  +
[ 7.493886] dw2102: su3000_power_ctrl: 0, initialized 1
  +
[ 7.493916] dvb-usb: TeVii S482.2 USB successfully initialized and connected.
  +
[ 7.494020] usbcore: registered new interface driver dw2102
  +
[ 21.588265] dw2102: su3000_power_ctrl: 1, initialized 1
  +
[ 21.608463] i2c i2c-0: m88ds3103: found a 'Montage M88DS3103' in cold state
  +
[ 21.661719] i2c i2c-0: m88ds3103: downloading firmware from file 'dvb-demod-m88ds3103.fw'
  +
[ 22.763531] i2c i2c-0: m88ds3103: found a 'Montage M88DS3103' in warm state
  +
[ 22.763560] i2c i2c-0: m88ds3103: firmware version 3.B
   
 
</pre>
 
</pre>

Latest revision as of 06:15, 16 May 2015

TeVii S482 Card

A dual DVB-S2 PCIe card from TeVii.

Hardware/Features

  • PCIe x1 low profile
  • Dual Tuner
  • The card consists of a USB Host Controller and two TeVii S660 equivalent cards.
  • LNB power supply via floppy connector

The Retail packaging includes full-height and low profile brackets, an IR receiver cable, an IR handset (incl. 2 AAA batteries), a windows drivers CD and an install manual.

Components Used

  • RF Tuner (twice): Montage Don't know
  • Demodulator (twice): Montage M88DS3103
  • USB Peripheral Controller (twice): Cypress CY7C68013A-56
  • PCIe bridge/USB Host Controller: MosChip MCS9990CV-AA
  • Crystal clock: (twice) YXC 24.0SDK + YXC 12.0SDK


Identification

lspci -nnk:

01:00.0 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ohci_hcd
01:00.1 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ehci_hcd
01:00.2 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ohci_hcd
01:00.3 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ehci_hcd
01:00.4 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ohci_hcd
01:00.5 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ehci_hcd
01:00.6 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ohci_hcd
01:00.7 USB controller [0c03]: NetMos Technology MCS9990 PCIe to 4‐Port USB 2.0 Host Controller [9710:9990]
	Subsystem: Device [a000:4000]
	Kernel driver in use: ehci_hcd


lsusb:

 Bus 010 Device 002: ID 9022:d483 TeVii Technology Ltd. 
 Bus 011 Device 002: ID 9022:d484 TeVii Technology Ltd. 


Once the module/firmware is loaded it's listed as two TeVii S660 cards.

Linux support

Native support is included in kernel 4.2. Media_build can be used to build support for older kernels.

Alternative methods described below:

The s2-liplianin v4l branch includes support for the card.

It works in 3.2 kernel.

For kernel > 3.10 (tested with 3.19 vanilla) you can apply the following patch to the kernel sources:

diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 1a3df10..82d35c6 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -31,6 +31,9 @@
 #include "m88rs2000.h"
 #include "tda18271.h"
 #include "cxd2820r.h"
+#include "m88ds3103.h"
+#include "m88ts2022.h"
+
 
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
@@ -71,6 +74,14 @@
 #define USB_PID_TEVII_S480_2 0xd482
 #endif
 
+#ifndef USB_PID_TEVII_S482_1
+#define USB_PID_TEVII_S482_1 0xd483
+#endif
+
+#ifndef USB_PID_TEVII_S482_2
+#define USB_PID_TEVII_S482_2 0xd484
+#endif
+
 #ifndef USB_PID_PROF_1100
 #define USB_PID_PROF_1100 0xb012
 #endif
@@ -1117,6 +1128,19 @@ static struct tda18271_config tda18271_config = {
 	.gate = TDA18271_GATE_DIGITAL,
 };
 
+static const struct m88ds3103_config s482_m88ds3103_config = {
+	.i2c_addr = 0x68,
+	.clock = 27000000,
+	.i2c_wr_max = 33,
+	.clock_out = 0,
+	.ts_mode = M88DS3103_TS_CI,
+	.ts_clk = 16000,
+	.ts_clk_pol = 0,
+	.agc = 0x99,
+	.lnb_hv_pol = 1,
+	.lnb_en_pol = 1,
+	 };
+
 static u8 m88rs2000_inittab[] = {
 	DEMOD_WRITE, 0x9a, 0x30,
 	DEMOD_WRITE, 0x00, 0x01,
@@ -1386,6 +1410,83 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
 	return -EIO;
 }
 
+static int m88ds3103_frontend_attach(struct dvb_usb_adapter *d)
+{
+	u8 obuf[3] = { 0xe, 0x80, 0 };
+	u8 ibuf[] = { 0 };
+
+	/* demod I2C adapter */
+	struct i2c_adapter *i2c_adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct m88ts2022_config m88ts2022_config = {
+		.clock = 27000000,
+		 };
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0xe;
+	obuf[1] = 0x02;
+	obuf[2] = 1;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+	msleep(300);
+
+	obuf[0] = 0xe;
+	obuf[1] = 0x83;
+	obuf[2] = 0;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0xe;
+	obuf[1] = 0x83;
+	obuf[2] = 1;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+		err("command 0x0e transfer failed.");
+
+	obuf[0] = 0x51;
+
+	if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+		err("command 0x51 transfer failed.");
+	d->fe_adap[0].fe = dvb_attach(m88ds3103_attach,
+		&s482_m88ds3103_config,
+		&d->dev->i2c_adap,
+		&i2c_adapter);
+	if (d->fe_adap[0].fe == NULL)
+		return -EIO;
+	/* attach tuner */
+	m88ts2022_config.fe = d->fe_adap[0].fe;
+	strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &m88ts2022_config;
+	request_module("m88ts2022");
+	client = i2c_new_device(i2c_adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		dvb_frontend_detach(d->fe_adap[0].fe);
+		goto fail_attach;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		        i2c_unregister_device(client);
+				dvb_frontend_detach(d->fe_adap[0].fe);
+		        goto fail_attach;
+	}
+	info("attached m88ds3103/m88ts2022!\n");
+
+	/* delegate signal strength measurement to tuner */
+
+	d->fe_adap[0].fe->ops.read_signal_strength =
+		d->fe_adap[0].fe->ops.tuner_ops.get_rf_strength;
+
+	return 0;
+fail_attach:
+	info("Failed to attach m88ds3103/m88ts2022!\n");
+	return -EIO;
+}
+
 static int t220_frontend_attach(struct dvb_usb_adapter *d)
 {
 	u8 obuf[3] = { 0xe, 0x87, 0 };
@@ -1557,6 +1658,8 @@ enum dw2102_table_entry {
 	TEVII_S480_2,
 	X3M_SPC1400HD,
 	TEVII_S421,
+	TEVII_S482_1,
+	TEVII_S482_2,
 	TEVII_S632,
 	TERRATEC_CINERGY_S2_R2,
 	GOTVIEW_SAT_HD,
@@ -1580,7 +1683,9 @@ static struct usb_device_id dw2102_table[] = {
 	[TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
 	[X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
 	[TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
-	[TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
+	[TEVII_S482_1] = { USB_DEVICE(0x9022, USB_PID_TEVII_S482_1) },
+	[TEVII_S482_2] = { USB_DEVICE(0x9022, USB_PID_TEVII_S482_2) },
+	[TEVII_S632] = { USB_DEVICE(0x9022, USB_PID_TEVII_S632) },
 	[TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
 	[GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
 	[GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
@@ -2012,6 +2117,59 @@ static struct dvb_usb_device_properties su3000_properties = {
 	}
 };
 
+static struct dvb_usb_device_properties m88ds3103_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.size_of_priv = sizeof(struct su3000_state),
+	.power_ctrl = su3000_power_ctrl,
+	.num_adapters = 1,
+	.identify_state = su3000_identify_state,
+	.i2c_algo = &su3000_i2c_algo,
+
+	.rc.core = {
+		.rc_interval = 150,
+		.rc_codes = RC_MAP_TEVII_NEC,
+		.module_name = "dw2102",
+		.allowed_protos = RC_BIT_NEC,
+		.rc_query = dw2102_rc_query,
+	},
+
+	.read_mac_address = su3000_read_mac_address,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	.adapter = {
+		{
+			.num_frontends = 1,
+			.fe = { {
+					.streaming_ctrl = su3000_streaming_ctrl,
+					.frontend_attach = m88ds3103_frontend_attach,
+					.stream = {
+						.type = USB_BULK,
+						.count = 8,
+						.endpoint = 0x82,
+						.u = {
+							.bulk = {
+								.buffersize = 4096,
+							}
+						}
+					}
+				} },
+		}
+		},
+		.num_device_descs = 2,
+		.devices = {
+			{ "TeVii S482.1 USB",
+			{ &dw2102_table[TEVII_S482_1], NULL },
+			{ NULL },
+			},
+			{ "TeVii S482.2 USB",
+			{ &dw2102_table[TEVII_S482_2], NULL },
+			{ NULL },
+			},
+			}
+};
+
 static struct dvb_usb_device_properties t220_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 	.usb_ctrl = DEVICE_SPECIFIC,
@@ -2131,11 +2289,13 @@ static int dw2102_probe(struct usb_interface *intf,
 	    0 == dvb_usb_device_init(intf, p7500,
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, s421,
-			THIS_MODULE, NULL, adapter_nr) ||
-	    0 == dvb_usb_device_init(intf, &su3000_properties,
-			 THIS_MODULE, NULL, adapter_nr) ||
+			THIS_MODULE, NULL, adapter_nr)  ||
 	    0 == dvb_usb_device_init(intf, &t220_properties,
-			 THIS_MODULE, NULL, adapter_nr))
+			THIS_MODULE, NULL, adapter_nr) ||
+		0 == dvb_usb_device_init(intf, &m88ds3103_properties,
+			THIS_MODULE, NULL, adapter_nr) ||
+		0 == dvb_usb_device_init(intf, &su3000_properties,
+			THIS_MODULE, NULL, adapter_nr))
 		return 0;
 
 	return -ENODEV;
@@ -2153,7 +2313,7 @@ module_usb_driver(dw2102_driver);
 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, S660, S480, S421, S632"
+			" TeVii S600, S630, S650, S660, S480, S482, S421, S632"
 			" Prof 1100, 7500 USB2.0,"
 			" Geniatech SU3000, T220 devices");
 MODULE_VERSION("0.1");

dmesg

[    5.818669] usbcore: registered new interface driver usbfs
[    5.819305] usbcore: registered new interface driver hub
[    5.819405] usbcore: registered new device driver usb
[    5.835721] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    5.847556] ehci-pci: EHCI PCI platform driver
[    5.851960] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 29 for gsi 16
[    5.852344] ehci-pci 0000:00:00.1: Xen PCI mapped GSI16 to IRQ29
[    5.859554] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    5.861252] ehci-pci 0000:00:00.1: EHCI Host Controller
[    5.861308] ehci-pci 0000:00:00.1: new USB bus registered, assigned bus number 1
[    5.861337] ehci-pci 0000:00:00.1: applying MosChip frame-index workaround
[    5.865052] ehci-pci 0000:00:00.1: Enabling legacy PCI PM
[    5.867326] ehci-pci 0000:00:00.1: irq 29, io mem 0xfea06000
[    5.876104] ehci-pci 0000:00:00.1: USB 2.0 started, EHCI 1.00
[    5.876306] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    5.876319] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    5.876331] usb usb1: Product: EHCI Host Controller
[    5.876340] usb usb1: Manufacturer: Linux 3.19.0-rc6-build-tree+ ehci_hcd
[    5.876350] usb usb1: SerialNumber: 0000:00:00.1
[    5.877073] hub 1-0:1.0: USB hub found
[    5.877124] hub 1-0:1.0: 1 port detected
[    5.879360] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 30 for gsi 17
[    5.879397] ehci-pci 0000:00:00.3: Xen PCI mapped GSI17 to IRQ30
[    5.879999] ehci-pci 0000:00:00.3: EHCI Host Controller
[    5.883534] ehci-pci 0000:00:00.3: new USB bus registered, assigned bus number 2
[    5.883579] ehci-pci 0000:00:00.3: applying MosChip frame-index workaround
[    5.885849] ehci-pci 0000:00:00.3: Enabling legacy PCI PM
[    5.886277] ehci-pci 0000:00:00.3: irq 30, io mem 0xfea04000
[    5.896115] ehci-pci 0000:00:00.3: USB 2.0 started, EHCI 1.00
[    5.896326] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[    5.896339] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    5.896351] usb usb2: Product: EHCI Host Controller
[    5.896360] usb usb2: Manufacturer: Linux 3.19.0-rc6-build-tree+ ehci_hcd
[    5.896369] usb usb2: SerialNumber: 0000:00:00.3
[    5.897076] hub 2-0:1.0: USB hub found
[    5.897117] hub 2-0:1.0: 1 port detected
[    5.915014] ohci-pci: OHCI PCI platform driver
[    5.915808] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 29 for gsi 16
[    5.915836] ohci-pci 0000:00:00.0: Xen PCI mapped GSI16 to IRQ29
[    5.917614] ohci-pci 0000:00:00.0: OHCI PCI host controller
[    5.917664] ohci-pci 0000:00:00.0: new USB bus registered, assigned bus number 3
[    5.917749] ohci-pci 0000:00:00.0: irq 29, io mem 0xfea07000
[    5.976289] usb usb3: New USB device found, idVendor=1d6b, idProduct=0001
[    5.976318] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    5.976331] usb usb3: Product: OHCI PCI host controller
[    5.976339] usb usb3: Manufacturer: Linux 3.19.0-rc6-build-tree+ ohci_hcd
[    5.976349] usb usb3: SerialNumber: 0000:00:00.0
[    5.977069] hub 3-0:1.0: USB hub found
[    5.977116] hub 3-0:1.0: 1 port detected
[    5.978048] xen:events: xen_bind_pirq_gsi_to_irq: returning irq 30 for gsi 17
[    5.978077] ohci-pci 0000:00:00.2: Xen PCI mapped GSI17 to IRQ30
[    5.978457] ohci-pci 0000:00:00.2: OHCI PCI host controller
[    5.978502] ohci-pci 0000:00:00.2: new USB bus registered, assigned bus number 4
[    5.978618] ohci-pci 0000:00:00.2: irq 30, io mem 0xfea05000
[    6.036248] usb usb4: New USB device found, idVendor=1d6b, idProduct=0001
[    6.036278] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    6.036290] usb usb4: Product: OHCI PCI host controller
[    6.036299] usb usb4: Manufacturer: Linux 3.19.0-rc6-build-tree+ ohci_hcd
[    6.036309] usb usb4: SerialNumber: 0000:00:00.2
[    6.037031] hub 4-0:1.0: USB hub found
[    6.037077] hub 4-0:1.0: 1 port detected
[    6.189162] usb 1-1: new high-speed USB device number 2 using ehci-pci
[    6.234979] usb 2-1: new high-speed USB device number 2 using ehci-pci
[    6.327018] usb 1-1: New USB device found, idVendor=9022, idProduct=d483
[    6.327048] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    6.327060] usb 1-1: Product: Dual tuner S2 PCIe (LNB1)
[    6.327069] usb 1-1: Manufacturer: Tevii
[    6.327078] usb 1-1: SerialNumber: 0000000002001010011
[    6.370736] usb 2-1: New USB device found, idVendor=9022, idProduct=d484
[    6.370766] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    6.370778] usb 2-1: Product: Dual tuner S2 PCIe (LNB2)
[    6.370787] usb 2-1: Manufacturer: Tevii
[    6.370796] usb 2-1: SerialNumber: 000000000010020101
[    6.582141] dw2102: su3000_identify_state
[    6.582175] dvb-usb: found a 'TeVii S482.1 USB' in warm state.
[    6.582202] dw2102: su3000_power_ctrl: 1, initialized 0
[    6.584443] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
[    6.585223] DVB: registering new adapter (TeVii S482.1 USB)
[    6.590604] dvb-usb: MAC address: 00:18:bd:5b:bd:81
[    6.957230] i2c i2c-0: m88ds3103_attach: chip_id=70
[    6.963175] i2c i2c-0: Added multiplexed i2c bus 1
[    7.062312] m88ts2022 1-0060: Montage M88TS2022 successfully identified
[    7.062372] dw2102: attached m88ds3103/m88ts2022!
[    7.062394] usb 1-1: DVB: registering adapter 0 frontend 0 (Montage M88DS3103)...
[    7.063446] dw2102: su3000_power_ctrl: 0, initialized 1
[    7.063473] dvb-usb: TeVii S482.1 USB successfully initialized and connected.
[    7.063584] dw2102: su3000_identify_state
[    7.063599] dvb-usb: found a 'TeVii S482.2 USB' in warm state.
[    7.063624] dw2102: su3000_power_ctrl: 1, initialized 0
[    7.063974] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
[    7.066978] DVB: registering new adapter (TeVii S482.2 USB)
[    7.073128] dvb-usb: MAC address: 00:18:bd:5b:bd:80
[    7.386369] i2c i2c-2: m88ds3103_attach: chip_id=70
[    7.393475] i2c i2c-2: Added multiplexed i2c bus 3
[    7.490361] m88ts2022 3-0060: Montage M88TS2022 successfully identified
[    7.490423] dw2102: attached m88ds3103/m88ts2022!
[    7.490446] usb 2-1: DVB: registering adapter 1 frontend 0 (Montage M88DS3103)...
[    7.493886] dw2102: su3000_power_ctrl: 0, initialized 1
[    7.493916] dvb-usb: TeVii S482.2 USB successfully initialized and connected.
[    7.494020] usbcore: registered new interface driver dw2102
[   21.588265] dw2102: su3000_power_ctrl: 1, initialized 1
[   21.608463] i2c i2c-0: m88ds3103: found a 'Montage M88DS3103' in cold state
[   21.661719] i2c i2c-0: m88ds3103: downloading firmware from file 'dvb-demod-m88ds3103.fw'
[   22.763531] i2c i2c-0: m88ds3103: found a 'Montage M88DS3103' in warm state
[   22.763560] i2c i2c-0: m88ds3103: firmware version 3.B

Howto compile

 cd /usr/src/
 rm -rf s2-liplianin-v39
 hg clone https://bitbucket.org/liplianin/s2-liplianin-v39
 cd s2-liplianin-v39
 make release
 make

Install

mkdir -p /lib/modules/`uname -r`/updates/v4l
cp -f ./v4l/*.ko /lib/modules/`uname -r`/updates/v4l/
depmod -a
reboot

Uninstall

rm -rf /lib/modules/`uname -r`/updates/v4l
depmod -a
reboot

You must confirm to use the correct firmware from Tevii [1], wich normally is automatically installed by the driver:

cd /usr/local/src
wget http://www.tevii.com/s2_liplianin_1.tar
tar xvf s2_liplianin_1.tar
cd tevii_s2_liplianin-eb8a914cd499/linux/firmware/
md5sum dvb-usb-s660.fw
#2946e99fe3a4973ba905fcf59111cf40  dvb-usb-s660.fw
cp dvb-usb-s660.fw /lib/firmware/

Driver Status

05.10.2014 just work with liplianin drivers, not ported to Linux kernel

06.01.2015 It just compile in 3.2 kernel (Debian Wheezy) for me. The image and audio is bad in some channels.

          I try with Astra 19.2E:
                     CNN Int. works great
                     BBC World works bad

External Links

Official Website