TeVii S482: Difference between revisions
No edit summary |
|||
Line 58: | Line 58: | ||
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): |
|||
<pre> |
|||
diff -r 4c01a16b6237 linux/drivers/media/i2c/s5c73m3/s5c73m3-core.c |
|||
--- 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 |
|||
@@ -1585,7 +1585,11 @@ |
|||
oif_sd = &state->oif_sd; |
|||
v4l2_subdev_init(sd, &s5c73m3_subdev_ops); |
|||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) |
|||
sd->owner = client->driver->driver.owner; |
|||
+#else |
|||
+ sd->owner = client->dev.driver->owner; |
|||
+#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; |
|||
+ |
|||
+ struct tvp514x_reg *int_seq; |
|||
}; |
|||
/* TVP514x default register values */ |
|||
@@ -862,7 +864,6 @@ |
|||
static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable) |
|||
{ |
|||
int err = 0; |
|||
- struct i2c_client *client = v4l2_get_subdevdata(sd); |
|||
struct tvp514x_decoder *decoder = to_decoder(sd); |
|||
if (decoder->streaming == enable) |
|||
@@ -882,11 +883,8 @@ |
|||
} |
|||
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); |
|||
+ |
|||
+ return 0; |
|||
} |
|||
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)); |
|||
} |
|||
tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); |
|||
diff -r 4c01a16b6237 linux/drivers/media/pci/zoran/zoran_procfs.c |
|||
--- a/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Jun 16 17:27:56 2013 +0300 |
|||
+++ b/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Feb 08 19:01:07 2015 +0000 |
|||
@@ -58,6 +58,10 @@ |
|||
short bit; |
|||
}; |
|||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) |
|||
+ #define PDE_DATA(info) (struct zoran *)(PDE(inode)->data) |
|||
+#endif |
|||
+ |
|||
static const struct procfs_params_zr36067 zr67[] = { |
|||
{"HSPol", 0x000, 1, 30}, |
|||
{"HStart", 0x000, 0x3ff, 10}, |
|||
@@ -130,14 +134,14 @@ |
|||
static int zoran_open(struct inode *inode, struct file *file) |
|||
{ |
|||
- struct zoran *data = PDE(inode)->data; |
|||
+ struct zoran *data = PDE_DATA(inode); |
|||
return single_open(file, zoran_show, data); |
|||
} |
|||
static ssize_t zoran_write(struct file *file, const char __user *buffer, |
|||
size_t count, loff_t *ppos) |
|||
{ |
|||
- struct zoran *zr = PDE(file_inode(file))->data; |
|||
+ struct zoran *zr = PDE_DATA(file_inode(file)); |
|||
char *string, *sp; |
|||
char *line, *ldelim, *varname, *svar, *tdelim; |
|||
@@ -201,7 +205,7 @@ |
|||
dprintk(2, |
|||
KERN_INFO |
|||
"%s: procfs entry /proc/%s allocated. data=%p\n", |
|||
- ZR_DEVNAME(zr), name, zr->zoran_proc->data); |
|||
+ ZR_DEVNAME(zr), name, zr); |
|||
} else { |
|||
dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n", |
|||
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 |
|||
}; |
|||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) |
|||
+ATTRIBUTE_GROUPS(video_device); |
|||
+#endif |
|||
+ |
|||
/* |
|||
* Active devices |
|||
*/ |
|||
@@ -217,7 +221,11 @@ |
|||
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 |
|||
+ |
|||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) |
|||
+#define INIT_COMPLETION(x) reinit_completion(&x) |
|||
+#endif |
|||
+ |
|||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) |
|||
+#define put_compat_timespec compat_put_timespec |
|||
+#endif |
|||
+ |
|||
#ifdef NEED_HEX_TO_BIN |
|||
#include <linux/ctype.h> |
|||
static inline int hex_to_bin(char ch) |
|||
@@ -679,11 +693,17 @@ |
|||
struct module *module, int extra_size, |
|||
struct snd_card **card) |
|||
{ |
|||
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3,15,0) |
|||
+ return snd_card_new(NULL, idx, id, module, extra_size, card); |
|||
+#else |
|||
+ |
|||
*card = snd_card_new(idx, id, module, extra_size); |
|||
if (*card == NULL) |
|||
return -ENOMEM; |
|||
return 0; |
|||
+#endif |
|||
+ |
|||
} |
|||
#endif |
|||
</pre> |
|||
== Howto compile == |
== Howto compile == |
Revision as of 15:58, 9 February 2015
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
The s2-liplianin v4l branch includes support for the card.
It works in 3.2 kernel.
For kernel 3.16 you can apply the foloowing patch (tested on Debian Lenny):
diff -r 4c01a16b6237 linux/drivers/media/i2c/s5c73m3/s5c73m3-core.c --- 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 @@ -1585,7 +1585,11 @@ oif_sd = &state->oif_sd; v4l2_subdev_init(sd, &s5c73m3_subdev_ops); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) sd->owner = client->driver->driver.owner; +#else + sd->owner = client->dev.driver->owner; +#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; + + struct tvp514x_reg *int_seq; }; /* TVP514x default register values */ @@ -862,7 +864,6 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable) { int err = 0; - struct i2c_client *client = v4l2_get_subdevdata(sd); struct tvp514x_decoder *decoder = to_decoder(sd); if (decoder->streaming == enable) @@ -882,11 +883,8 @@ } 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); + + return 0; } 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)); } tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); diff -r 4c01a16b6237 linux/drivers/media/pci/zoran/zoran_procfs.c --- a/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Jun 16 17:27:56 2013 +0300 +++ b/linux/drivers/media/pci/zoran/zoran_procfs.c Sun Feb 08 19:01:07 2015 +0000 @@ -58,6 +58,10 @@ short bit; }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) + #define PDE_DATA(info) (struct zoran *)(PDE(inode)->data) +#endif + static const struct procfs_params_zr36067 zr67[] = { {"HSPol", 0x000, 1, 30}, {"HStart", 0x000, 0x3ff, 10}, @@ -130,14 +134,14 @@ static int zoran_open(struct inode *inode, struct file *file) { - struct zoran *data = PDE(inode)->data; + struct zoran *data = PDE_DATA(inode); return single_open(file, zoran_show, data); } static ssize_t zoran_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct zoran *zr = PDE(file_inode(file))->data; + struct zoran *zr = PDE_DATA(file_inode(file)); char *string, *sp; char *line, *ldelim, *varname, *svar, *tdelim; @@ -201,7 +205,7 @@ dprintk(2, KERN_INFO "%s: procfs entry /proc/%s allocated. data=%p\n", - ZR_DEVNAME(zr), name, zr->zoran_proc->data); + ZR_DEVNAME(zr), name, zr); } else { dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n", 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 }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) +ATTRIBUTE_GROUPS(video_device); +#endif + /* * Active devices */ @@ -217,7 +221,11 @@ 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 + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) +#define INIT_COMPLETION(x) reinit_completion(&x) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) +#define put_compat_timespec compat_put_timespec +#endif + #ifdef NEED_HEX_TO_BIN #include <linux/ctype.h> static inline int hex_to_bin(char ch) @@ -679,11 +693,17 @@ struct module *module, int extra_size, struct snd_card **card) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,15,0) + return snd_card_new(NULL, idx, id, module, extra_size, card); +#else + *card = snd_card_new(idx, id, module, extra_size); if (*card == NULL) return -ENOMEM; return 0; +#endif + } #endif
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